HomeiOS Developmentios - The way to convert escaping closure code to async-await code...

ios – The way to convert escaping closure code to async-await code that makes use of URLSession? Swift


I’m attempting to transform escaping closure code to async-await code in a sure file. I’m caught with implementing the async-await half, particularly whether or not to nonetheless use a do block, with catch and resume, or to not use a do block, and assign the road of code with “attempt await URLSession.shared.dataTask(with: request)” (that is commented out in File1-GettingSelectedRestaurantBusinessDataUsingAsync-AwaitAndNotUsingCodable.swift on this put up beneath, and meant for use within the resolution makes an attempt to this file) to a variable, then use that variable later just like how the file File2-GettingRestaurantBusinessDataUsingAsync-AwaitAndUsingCodable.swift does, which is posted additional beneath on this put up.

*Word: I used async-await and codable to get the restaurant enterprise knowledge for a sure searched metropolis (thats searched by the person) which is completed in a distinct file (and performance). The file I’m having bother with although is for getting the chosen restaurant enterprise’s element information (title, deal with, enterprise hours, and so on.), and I’m not utilizing codable on this file as a result of a few of the knowledge I get when doing this URL request, I get through the use of NSDictionary; not codable.

How do I accurately implement this async-await idea in my file? The file I’m implementing this in is File1-GettingSelectedRestaurantBusinessDataUsingAsync-AwaitAndNotUsingCodable.swift which is posted additional beneath on this put up.

I’ve posted some tried options up to now, that are incomplete, since I’m having the issues talked about within the first paragraph of this put up. I do know they don’t work, however that is my thought course of up to now. These resolution makes an attempt are beneath the code information that I’m working with that are posted additional beneath.

I used the next article for studying extra about async-await earlier than trying to make this present implementation: https://www.avanderlee.com/swift/async-await/.

My code:

Code information that I’m working with:

File that I’m trying to implement this escaping closure to async-await idea in:

File1-GettingSelectedRestaurantBusinessDataUsingAsync-AwaitAndNotUsingCodable.swift:

import Basis
import UIKit
import CoreLocation

extension UIViewController {

    func retrieveSelectedRestaurantDetailViewInfo(
        selected_restaurant_business_ID: String) async throws -> SelectedRestaurantDetailViewInfoNotUsingCodable? {

            // MARK: Make API Name
            let apiKey = "API key"

            /// Create URL
            let baseURL =
            "https://api.yelp.com/v3/companies/(selected_restaurant_business_ID)"

            let url = URL(string: baseURL)

            /// Creating Request
            var request = URLRequest(url: url!)
            request.setValue("Bearer (apiKey)", forHTTPHeaderField: "Authorization")
            request.httpMethod = "GET"

            ///Initialize session and job
            //V1: Code for utilizing escaping closure model code.
            URLSession.shared.dataTask(with: request) { (knowledge, response, error) in
             
            //This model commented out proper now, to indicate the place I am at with this proboem for readability. This model is included within the resolution makes an attempt; each SoultionAttempt1 and SolutionAttempt2.
            

                if let error = error {
                    completionHandler(nil, error)
                }
            
            //V2: Code for what I feel is appropriate for utilizing async-await model code. Not utilizing the completionHandler right here.
//            URLSession.shared.dataTask(with: request)

                do {
                    /// Learn knowledge as JSON
                    let json = attempt JSONSerialization.jsonObject(with: knowledge!, choices: [])

                    /// Fundamental dictionary
                    guard let responseDictionary = json as? NSDictionary else {return}

                    //Code for accessing restaraunt element view information, and assigning it to selectedRestarauntDetailViewInfo view mannequin thats a struct.
                    var selectedVenue = SelectedRestaurantDetailViewInfoNotUsingCodable()
                    
                    
                    //Remainder of code for accessing restaraunt element view information, and assigning it to seelctedRestarauntDetailViewInfo view mannequin thats a struct.
                    selectedVenue.title = responseDictionary.worth(forKey: "title") as? String
                    
                    //*Remainder of code for getting enterprise information together with deal with, hours, and so on..*
                    
                    //Commented out for now, as a result of am going with model 2 beneath.
                    //V1: Makes use of escaping closure code model.
//                    completionHandler(selectedVenue, nil)
                    
                    //V2: Used for Async/Await code model.
                    return selectedVenue
                    
                } catch {
                    print("Caught error")
                }
                }.resume()
    }
}

File (file I am referring to is beneath; is File2-GettingRestaurantBusinessDataUsingAsync-AwaitAndUsingCodable.swift) that makes use of async-await for getting the preliminary restaurant enterprise knowledge, after the person selects a metropolis, which I’m utilizing for reference for making the acknowledged change from the escaping closure code to the async-await code in File1-GettingSelectedRestaurantBusinessDataUsingAsync-AwaitAndNotUsingCodable.swift above:

File2-GettingRestaurantBusinessDataUsingAsync-AwaitAndUsingCodable.swift:

import UIKit
import Basis
import CoreLocation

class YelpApiSelectedRestaurantDetailViewInfo {
    personal var apiKey: String

    init(apiKey: String) {
        self.apiKey = apiKey
    }

    func searchBusinessDetailViewInfo(selectedRestaurantBusinessID: String) async throws -> SelectedRestaurantDetailViewInfo {

        var resultsForTheSelectedRestaurantDetailViewInfo: SelectedRestaurantDetailViewInfo

        // MARK: Make URL Request.
        var urlComponents = URLComponents(string: "https://api.yelp.com/v3/companies/(selectedRestaurantBusinessID)")

        guard let url = urlComponents?.url else {
            throw URLError(.badURL)
        }

        var request = URLRequest(url: url)
        request.setValue("Bearer (self.apiKey)", forHTTPHeaderField: "Authorization")

        let (knowledge, _) = attempt await URLSession.shared.knowledge(for: request)

        let businessDetailViewInfoResults = attempt JSONDecoder().decode(SelectedRestaurantDetailViewInfo.self, from: knowledge)

        
        resultsForTheSelectedRestaurantDetailViewInfo = businessDetailViewInfoResults

        return resultsForTheSelectedRestaurantDetailViewInfo
    }
}

Answer Makes an attempt:

*Word:

-Each of the beneath resolution try code snippets begin on the line of code: URLSession.shared.dataTask(with: request) { (knowledge, response, error) in in File1-GettingSelectedRestaurantBusinessDataUsingAsync-AwaitAndNotUsingCodable.swift, and goes by the remainder of that file, and ends on the identical finish level as that file (as file File1-GettingSelectedRestaurantBusinessDataUsingAsync-AwaitAndNotUsingCodable.swift).

-Additionally, the file that these resolution makes an attempt are to be applied in is File1-GettingSelectedRestaurantBusinessDataUsingAsync-AwaitAndNotUsingCodable.swift.

SolutionAttempt1-DoesntUseDoBlock.swift:

                    ///Initialize session and job
                    attempt await URLSession.shared.dataTask(with: request)
                        
                    /// Learn knowledge as JSON
                    let json = attempt JSONSerialization.jsonObject(with: knowledge!, choices: [])

                    /// Fundamental dictionary
                    guard let responseDictionary = json as? NSDictionary else {return}

                    //Code for accessing restaraunt element view information, and assigning it to selectedRestarauntDetailViewInfo view mannequin thats a struct.
                    var selectedVenue = SelectedRestaurantDetailViewInfoNotUsingCodable()

                    //Remainder of code for accessing restaraunt element view information, and assigning it to seelctedRestarauntDetailViewInfo view mannequin thats a struct.
                    selectedVenue.title = responseDictionary.worth(forKey: "title") as? String

                    //*Remainder of code for getting enterprise information together with deal with, enterprise hours, and so on..*

                    return selectedVenue

                } catch {
                    print("Caught error")
                }
                }.resume()
    }
}

*Word in regards to the following resolution try file: The answer try right here in my view (SolutionAttempt2-DoesUseDoBlock.swift) might not have to incorporate indentation for the do block, the place the do block is inside the scope of the “attempt await URLSession.shared.dataTask(with: request)” line of code, however I included the beneath resolution try to have this indentation, as it might appear that the do block would have to be inside the scope of the “attempt await URLSession.shared.dataTask(with: request)” line of code, and the unique file model of File1-GettingSelectedRestaurantBusinessDataUsingAsync-AwaitAndNotUsingCodable.swift, that makes use of the escaping closure (not the file being edited/labored on right here) had the do block inside the “URLSession.shared.dataTask(with: request) { (knowledge, response, error) in” line of code’s scope, which is on the identical place because the “attempt await URLSession.shared.dataTask(with: request)” line of code on this SolutionAttempt2-DoesUseDoBlock.swift file beneath.

SolutionAttempt2-DoesUseDoBlock.swift:

            ///Initialize session and job
            attempt await URLSession.shared.dataTask(with: request)

                do {
                    
                    /// Learn knowledge as JSON
                    let json = attempt JSONSerialization.jsonObject(with: knowledge!, choices: [])
                    
                    /// Fundamental dictionary
                    guard let responseDictionary = json as? NSDictionary else {return}
                    
                    
                    //Code for accessing restaraunt element view information, and assigning it to seelctedRestarauntDetailViewInfo view mannequin thats a struct.
                    var selectedVenue = SelectedRestaurantDetailViewInfoNotUsingCodable()
                    
                    //Remainder of code for accessing restaraunt element view information, and assigning it to seelctedRestarauntDetailViewInfo view mannequin thats a struct.
                    selectedVenue.title = responseDictionary.worth(forKey: "title") as? String
                    
                    //*Remainder of code for getting enterprise information together with deal with, enterprise hours, and so on.*
                    
                    return selectedVenue
                    
                } catch {
                    print("Caught error")
                }
                }.resume()
    }
}

Thanks!

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments