ViewDid Load of today Widget gets called every time

1k Views Asked by At

I have implemented today widget for displaying recently recorded videos thumb.i am using collection view in Widget Storyboard file. Its all working fine. I am able to get required thumbs from shared container and bind it to collection view as well. Now the issue is Whenever i look for the widget in Notification centre it calls ViewDidLoad of TodayWidgetViewController every time. Because of this collection view seems to be reloaded every time.

Is there a way to prevent this being reloaded every time?

Thanks in advance.

Below is the Source Code Implemented:

{

@IBOutlet weak var widgetCollection: UICollectionView!
@IBOutlet weak var recordButton: UIButton!

var mutArryListOfVideosImg: NSMutableArray = NSMutableArray()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view from its nib.

    self.recordButton.layer.borderWidth = 2.0
    self.recordButton.layer.borderColor = UIColor.white.cgColor
    self.recordButton.layer.masksToBounds = true
    self.recordButton.layer.cornerRadius = self.recordButton.frame.size.width / 2

    self.extensionContext?.widgetLargestAvailableDisplayMode = .expanded

    //print("array count:\()")

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    self.getVideoThumbImages()

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func btnRecordAction(sender:UIButton)
{
    let pjUrl = URL(string: "")
    self.extensionContext?.open(pjUrl!, completionHandler: { (Bool) in

    })
}


func getDataPath() -> URL
{
    let appGroupId = “”

    let appGroupDirectoryPath:URL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupId)!

    let newDirectory = appGroupDirectoryPath.appendingPathComponent("VideoThumbs")

    return newDirectory

}

func getVideoThumbImages()
{

    let videoDirectoryPath  = self.getDataPath()

      if  let Images = try? FileManager.default.contentsOfDirectory(atPath: videoDirectoryPath.path) as [String]
      {
        if((Images.count) > 0)
        {
            let sortedImages = (Images.sorted(by: backward)) as [String]

            //print("Sorted Array:\(sortedImages)")

            if((sortedImages.count) > 0)
            {
                for (index,element) in (sortedImages.enumerated()) {
                    print("\(index) = \(element)")

                    mutArryListOfVideosImg.add(element)

                }

                if(mutArryListOfVideosImg.count > 0)
                {
                    widgetCollection.reloadData()
                }
            }
        }
    }

}

func backward(_ s1: String, _ s2: String) -> Bool {
    return s1 > s2
}

func getDataFromUrl(url: URL, completion: @escaping (_ data: Data?, _  response: URLResponse?, _ error: Error?) -> Void) {
    URLSession.shared.dataTask(with: url) {
        (data, response, error) in
        completion(data, response, error)
        }.resume()
}

//MARK: CollectionView  Delegate and Datasource

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
    if mutArryListOfVideosImg.count > 3
    {
        return 3
    }
    else
    {
        return mutArryListOfVideosImg.count
    }
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WidgetCollectionCell", for: indexPath as IndexPath) as! WidgetCollectionCell
    cell.imgVideoThumbImage.layer.cornerRadius = 8.0
    cell.imgVideoThumbImage.layer.masksToBounds = true

    let directoryPath = self.getDataPath()

    let url = directoryPath.appendingPathComponent(mutArryListOfVideosImg.object(at: indexPath.item) as! String)

    getDataFromUrl(url: url) { (data, response, error)  in
        guard let data = data, error == nil else { return }
        //print(response?.suggestedFilename ?? url.lastPathComponent)
        //print("Download Finished")

        DispatchQueue.main.async() { () -> Void in
            cell.imgVideoThumbImage.image = UIImage(data: data)
        }
    }

    return cell
}

public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
    print("Widget thumb tapped....")

    let pjUrl = URL(string: “CallBack://edit-\(mutArryListOfVideosImg.object(at: indexPath.item))")
    self.extensionContext?.open(pjUrl!, completionHandler: { (Bool) in

    })

}

public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
    return CGSize(width: (self.widgetCollection.frame.size.width/3) - 10, height: 70)
}

func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
    // Perform any setup necessary in order to update the view.

    // If an error is encountered, use NCUpdateResult.Failed
    // If there's no update required, use NCUpdateResult.NoData
    // If there's an update, use NCUpdateResult.NewData

    completionHandler(NCUpdateResult.newData)
}

func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
    if (activeDisplayMode == NCWidgetDisplayMode.compact) {
        self.preferredContentSize = maxSize
    }
    else {
        self.preferredContentSize = CGSize(width: maxSize.width, height: 120)
    }
}

}

1

There are 1 best solutions below

9
Alessandro Ornano On

viewWillAppear and viewDidAppear will be called every time your widget is displayed.

About viewDidLoad seems strange, are you sure about it? Anyway this should not happen, it's not normal, try to check this method:

func widgetPerformUpdate(completionHandler: ((NCUpdateResult) -> Void)) {
        // you could call here a custom function to update your widget 
        completionHandler(NCUpdateResult.NewData)
}

Your extension probably has an error and everytime view appears it is being called again.

Hope it helps.


Update: (after your corrections)

Seems your widget crash or not loaded due to size problems. In viewWillAppear try to launch this method:

func setPreferredContentSize() {
        var currentSize: CGSize = self.preferredContentSize
        currentSize.height = 190.0
        self.preferredContentSize = currentSize
}