skip to Main Content

As the title says, I have a function with these parameters:

typealias Handler = (Swift.Result<Any?, APIErrors>) -> Void

func viewApi (ownerId: String, accessToken: String, completionHandler: @escaping Handler ){
var viewArray: [Information] = [Information]()
    
    let headers: HTTPHeaders = [
            
        .authorization("Bearer (accessToken)")
    
    ]
    
    let viewUrl = "(viewTaskUrl)?userId=(ownerId)"
           
    let url = URL(string: viewUrl)
    var request = URLRequest(url: url!)
   
    request.method = .get
    request.headers = headers
    
    var taskList:[Task] = []
    
    AF.request(request).responseJSON(completionHandler: { (response) in
        
        var holder = Information(id: 0, title: "", description: "", status: "")
        switch response.result {
            
        case .success(let data):
            do{
                if response.response?.statusCode == 200 {
//                        completionHandler(.success("JSON HERE: 

    (String(describing: json))"))
                        let jsonData = try JSONSerialization.data(withJSONObject: data)
                        let jsonString = String(data: jsonData, encoding: .utf8)
                    
                    let trySplit = jsonString?.components(separatedBy: ",")
                    
                    for i in 0...trySplit!.count-1{

                        if trySplit![i].contains("id"){
                            let id = trySplit![i].components(separatedBy: ":")[1]
                            holder.id = Int(id)!
                        }

                        if trySplit![i].contains("title"){

                            let title = trySplit![i].components(separatedBy: ":")[1]
                            holder.title = title
    //                            print("TITLE: (title)")
                            
                        }
                        
                        if trySplit![i].contains("description"){

                            let desc = trySplit![i].components(separatedBy: ":")[1]
                            holder.description = desc
                            
                        }
                        
                        if trySplit![i].contains("status"){

                            let stat = trySplit![i].components(separatedBy: ":")[1]
                            let edited = stat.replacingOccurrences(of: "}", with: "")
                            holder.status = edited
                            
                            viewArray.append(holder)
                            
                        }
                    }
                }else{
//                       completionHandler(.failure(.custom(message: "Please check your network connectivity")))
                    print("Error")
                }
            
            }catch{
                
                print(error.localizedDescription)
                
            }
            
            case .failure(let err):
            print (err)
            
        }
        print("ARRAY: (viewArray)")
        for i in 0 ..< viewArray.count {
            
            let task = Task()
            
            let edited = viewArray[i].status.replacingOccurrences(of: "]", with: "")
            let new = viewArray[i].title.replacingOccurrences(of: """, with: "")
            
            task.taskName = new
            task.id = viewArray[i].id
            task.taskStatus = edited
            task.taskDescription = viewArray[i].description
            task.email = ownerId
            
            taskList.append(task)
        }
        try! self.realm.write{
            self.realm.add(taskList)
        }
        
    }).resume()
    
}

and that function runs well, it does what it needs to do by returning a JSON object and storing the contents in Realm but when I call it in my main ViewController, it does not go in the completionHandler and tries to store the contents from Realm into an array returns an empty array even though the Realm is populated. Here is the call in my ViewController:

self.APIManager.viewApi(ownerId: self.userId!, accessToken: self.token!) { (result) in
            switch result{
            case .success(_):
                //does not run
                print("SUCCESS COMPLETION")
            case .failure(let err):
                print(err.localizedDescription)
            }
        }

Is there any way for the function to run before the rest of the code is executed so that the array is not empty and so that it actually goes in my completionHandler?

P.S. Don’t mind the janky way I’m storing the JSON Object since I still have to find a better way to store it into an array besides converting it to string and then cutting it

2

Answers


  1. what is your Handler type ? and why the completion handler is not setting

    return the handler type according to the failure, success example.

    self.APIManager.viewApi(ownerId: self.userId!, accessToken: self.token!, completionHandler: CompletionHandler) { (result) in
                switch result{
                case .success(_):
                    
                    completionHandler(success:true)
                case .failure(let err):
                    print(err.localizedDescription)
                   completionHandler(success: false)
                }
            }
    

    you can return the raw response as it is in the completion, write a helper class to process the json response as per your requirement

    Login or Signup to reply.
  2. try something like this approach:

    func viewApi (ownerId: String, accessToken: String, completionHandler: @escaping Handler ) {
        //...
        AF.request(request).responseJSON { response in  // <-- here
            //...
            completionHandler(.success("JSON HERE:(String(describing: json))"))  // <-- here
            //...
        }
        //...
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search