Search code examples
iosiphonexcodeswift3nested-loops

How to code Nested Loop with synchronous in swift?


In my project, I call getMain() and that has nested loop. That loop call setUp(). My problem is setUp() before finish, upper loop is quit.

Firstly call getMian():

func getMain(){

    let entityDescription = NSFetchRequest<NSFetchRequestResult>(entityName: "MainThemeHome")
    do{
        let results = try context.fetch(entityDescription)

        if(results.count) > 0 {

            sections.removeAll()
            debugPrint(results.count)
            outer_count = results.count

                for i in 0 ..< (results.count){


                        let match = results[i] as! NSManagedObject

                        let associated_url = match.value(forKey: "main_associated_url") as! String

                        let name = match.value(forKey: "main_name") as! String

                       //call function
                             self.setUpViews(associated_url: associated_url, main_name: name, i: i )
                                                   self.myGroup.leave()


                }

                       }else{

        }

    }catch{}


}

Loop call setUp() is below,

  private func setUp(associated_url : String , main_name: String,i : Int) {

        if Reachability().isInternetAvailable() == true {

            self.rest.auth(auth: self.prefs.value(forKey: "access_token") as! String!)
            self.rest.get(url: StringResource().mainURL + associated_url ,  parma: [ "show_min": "true" ], finished: {(result : NSDictionary, status : Int) -> Void in

                self.assetsTable.removeAll()
                if(status == 200){
                    let data = result["data"] as! NSArray

                        for item in 0…data.count - 1 {



                            let themes : AnyObject = data[item] as AnyObject
                            let created = themes["created"] as! String
                            let assets_id = themes["id"] as! Int
                            let name = themes["name"] as! String
                            var poster_img_url = themes["poster_image_url"] as! String
                            let provider_id = themes["provider_id"] as! Int

                            poster_img_url = StringResource().posterURL + poster_img_url


                            self.assetsTable.append(AssetsTableItem(created: created, assets_id: assets_id, name: name, poster_image_url: poster_img_url , provider_id: provider_id))

                        }

      }


                    self.sections.append(SectionsHome(package_name: main_name, package_url: associated_url,i: i,packageTable: self.assetsTable))
                    self.inner_count = self.sections.count


                }else{


                }
            })
    }
    }

How to control setUp() is completely finished, loop will be increase count and quit. How to solve this problem. Please help.


Solution

  • You need to use closures in setUp function so that when the setUp if finished you will get the callback

     private func setUp(associated_url : String , main_name: String,i : Int, ,sucess:((Void) -> Void)?,failure:((Void?) -> Void)?) {
    
            if Reachability().isInternetAvailable() == true {
    
                self.rest.auth(auth: self.prefs.value(forKey: "access_token") as! String!)
                self.rest.get(url: StringResource().mainURL + associated_url ,  parma: [ "show_min": "true" ], finished: {(result : NSDictionary, status : Int) -> Void in
    
                    self.assetsTable.removeAll()
                    if(status == 200){
                        let data = result["data"] as! NSArray
    
                            for item in 0…data.count - 1 {
    
    
    
                                let themes : AnyObject = data[item] as AnyObject
                                let created = themes["created"] as! String
                                let assets_id = themes["id"] as! Int
                                let name = themes["name"] as! String
                                var poster_img_url = themes["poster_image_url"] as! String
                                let provider_id = themes["provider_id"] as! Int
    
                                poster_img_url = StringResource().posterURL + poster_img_url
    
    
                                self.assetsTable.append(AssetsTableItem(created: created, assets_id: assets_id, name: name, poster_image_url: poster_img_url , provider_id: provider_id))
    
                            }
    
          }
    
    
                        self.sections.append(SectionsHome(package_name: main_name, package_url: associated_url,i: i,packageTable: self.assetsTable))
                        self.inner_count = self.sections.count
                    sucess!()
    
                    }else{
                 failure!()
    
                    }
                })
        }
        }
    

    And change the way you call the function as

        self.setUp(associated_url: associated_url, main_name: name, i: i, sucess: { () in
         debugPrint("SUCCESS")
    }) { () in
        debugPrint("FAILURE")
        }