Search code examples
swiftloopsparse-platformswift3backend

Swift/Parse: how to get most recent item that has data filled in?


Ok I have not found this anywhere. In Swift I need to get the most recently added Parse item THAT HAS 2 certain columns filled in with non nil data. If the MOST recent has 1 or more columns that IS nil, I need the query to "select" and get the data from the next most recent item that does have all its data.

This is how Ive tried - I can successfully get most recent item using the .order(byDescending: "createdAt") but being that I need to get Strings and images, I cant make it select the most recent one that has all its data filled in.

I tried to iterate through the objects array and select a PFObject but this created an error because I don't want to make the VC class a PFSubclassing class.

//Parse - store global values
            var query = PFQuery(className: PARSE_CLASS!)
            query.order(byDescending: "createdAt")
            query.limit = 1
            query.findObjectsInBackground {
                (objects, error) -> Void in

                var objToUse = PFObject()

                if error == nil {
                    //get obj
                    for o in objects!
                    {
                        if(o["testTxt"] != nil && o["testImg"] != nil)
                        {
                            objToUse = o
                        }
                    }

                    //--------------------------------------------------->
                    for item in contentLinkKeys
                    {

    //                txtSources[item] = (objects?.first?["\(item)-blurb"] as! String)
                        if(objToUse["testTxt"] != nil && objToUse["testImg"] != nil)
                        {

                            txtSources[item] = ((objToUse["testTxt"] as! String) as! String)

                        if let validObjects = objects {
                            for object in validObjects {
                                let thumbnail = objToUse["testImg"] as? PFFile
                                thumbnail?.getDataInBackground (block: { (data, error) -> Void in
                                    //read image here
                                    var img = UIImage(data: data!)
                                    imgSources[item] = img

                                })
                            }
                            }


                        } //if }

                    } //for bracket
                }

How can I do this?Right now if the most recent one has a nil image or whatever, it just doesn't display an image. How can I make it know to go iterate and find the next most recent that does have all the columns filled in?


Solution

  • you can do something like the following. What's happening here is that we are first fetching all data in created date order and then filter out those which are valid i.e those have the all the required fields. Then we download the data for image and add it to source item.

    class ParseObject: PFObject, PFSubclassing {
    
        @NSManaged var testTxt: String?
        @NSManaged var testImage: PFFile?
    
        class func parseClassName() -> String {
            return "ParseClassName"
        }
    }
    
    
    func test() {
    
        var itemSource = [UIImage]()
    
        let query = PFQuery(className: "ParseClassName")
        query.order(byDescending: "createdAt")
        //query.limit = 1 why 1 it will always fetch one object we have to iterate so let gets some more
        query.findObjectsInBackground { (objects, error) in
            if let error = error {
                //error occured
                print(error.localizedDescription)
            }
            else {
                //now we have the objects so we filter the once that doesn't have nil data for those fields
                if let objects = objects as? [ParseObject] {
                    let filteredObjects = objects.filter{ ($0.testTxt != nil && $0.testImage != nil)}
    
                    /////// If you want all the objects that are valid i.e tesTxt and testImage are certainly in there //////////
    
                    for parseObject in filteredObjects {
                        let thumbnail = parseObject.testImage!
                        thumbnail.getDataInBackground(block: { (data, error) in
                            if let error = error {
                                //error
                                print(error.localizedDescription)
                            }
                            else {
                                if let image = UIImage(data: data!) {
                                    //set the image
                                    itemSource.append(image)
                                }
                            }
                        })
                    }
                }
            }
    
        }
    
    }
    

    But instead of appending or adding image directly inside collection is not good idea. You can use collections of Objects and download the image when required