Swift   发布时间:2022-04-30  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了在swift中具有多个闭包/ API请求的函数中的异步完成处理大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我刚刚开始使用 Swift进行开发,所以我对闭包很新.我也是新手如何处理异步API请求.

我已经阅读了很多类似的问题,例如How to get data to return from NSURLSessionDataTask in SwiftHow to use completionHandler Closure with return in Swift?.这些对我有帮助,但我的问题有点不同.

在我的函数中,我想首先发出一个API请求来获取JSON有效负载.对于此JSON有效内容中的一些数据,我想要进行多个其他API请求.在这种情况下,我将为每个API请求接收一个JSON有效负载,我想在我自己的JSON数据结构中存储一些数据.

问题是,对于我生成的每个多个API请求,我只能在CompletionHandler中返回我自己的JSON数据的一部分 – 据我所知,这是在使用闭包发出API请求时返回数据的唯一方法.

因此,在调用我的函数时,我不想获得多个完成处理程序,而只是希望收到一个.

事情是我不知道如何完成处理函数中的几个闭包,在这种情况下是两个闭包.

我在下面发布了我的代码 – 我知道它很长,也许不那么干净.
但是,重点是当我更新我的storeDict提供时,这将是空的,因为提供Dict数组从第二个闭包内部获取其信息.这显示函数底部.

func getOffersFromWishList(offerWishList: [String],latitude: Double,longitude: Double,radius: Int,completionHandler: ([NSDictionary] -> Void)) {

        var master: [NSDictionary] = []

        var nearby_params: NSDictionary = ["r_lat": latitude,"r_lng": longitude,"r_radius": radius]
        //println(nearby_params)
        var store_id_list: [String] = []


        // Get all store_ids for store which are nearby (Radius determines how nearby)
        singleton_eta.api("/v2/stores",type: ETArequestTypeGET,parameters: nearby_params,useCache: true,completion: { (response,error,fromCachE) -> Void in

            if error == nil {

                let json = JSON(responsE)
                storeArray = json.arrayValue
                //println(storeArray)

                for store in storeArray {

                    var storeDict = [String: AnyObject]()
                    var MetaData = [String: String]()
                    var offers: [NSDictionary] = []

                    let name = store["branding"]["name"].stringvalue
                    let store_id = store["id"].stringvalue
                    let street = store["street"].stringvalue
                    let city = store["city"].stringvalue
                    let zip_code = store["zip_code"].stringvalue
                    let dealer_id = store["dealer_id"].stringvalue
                    let logo = store["branding"]["logo"].stringvalue

                    MetaData = ["name": name,"store_id": store_id,"street": street,"city": city,"zip_code": zip_code,"dealer_id": dealer_id,"logo": logo]

                    store_id_list.append(store_id)

                    //println("Butiks ID: \(store_id)")

                    var offset = 0
                    let limit = 100

                    // Loop through the offers for the specific store id - only possible to request 100 offers each time
                    // A while loop would be more suitable,but I dont kNow when to stop,as the length of the offerArray can not be counted as it is cant be accessed outside of the closure.
                    for x in 1...2 {

                        var store_params: NSDictionary = ["store_ids:": store_id,"limit": limit,"offset": offset]
                        println(store_params)
                        // Get offers for a specific store_id
                        singleton_eta.api("/v2/offers",parameters: store_params,fromCachE) -> Void in

                            if error == nil {

                                offerArray = JSON(responsE).arrayValue
                                //println( "Typename0 = \(_stdlib_getTypename(offerArray))")

                                //Loop through the recieved offers
                                for of in offerArray {

                                    let name = of["branding"]["name"].stringvalue
                                    let dealer_id = of["dealer_id"].stringvalue
                                    let heading = of["heading"].stringvalue
                                    let description = of["description"].stringvalue
                                    let price = of["pricing"]["price"].stringvalue
                                    let image = of["images"]["view"].stringvalue


                                    //println(heading)

                                    // Loop through our offerWishList
                                    for owl in offerWishList {

                                        let headingContainswish = (heading.lowercaseString as NSString).containsString(owl.lowercaseString)

                                        // check if offer match with our wish list
                                        if(headingContainswish) {

                                            // Save neccesary Meta data about each offer to a tuple array
                                            var offer = Dictionary<String,String>()
                                            offer = ["name": name,"heading": heading,"description": description,"price": price,"image": image,"offerWishItem": owl]

                                            offers.append(offer)


                                        }

                                    }

                                }


                            }

                        })
                        //println(storeDict)
                        offset = offset + limit + 1

                    }

                    storeDict.updateValue(MetaData,forKey: "Meta_data")
                    storeDict.updateValue(offers,forKey: "offers")  // offers is empty due to its appending inside the closure
                    master.append(storeDict)

                }
             completionHandler(master)

            }

            else {
                println(error)
            }


        })

    }

调用上述功能

getOffersFromWishList(offerWishList,latitude,longitude,radius) { (master) -> Void in
       println(master)
    }

这是主人在调用函数时打印的内容,其中商品是空的.

{
"Meta_data" =     {
    city = "Kongens Lyngby";
    "dealer_id" = d8adog;
    logo = "https://d3ikkoqs9ddhdl.cloudfront.net/img/logo/default/d8adog_3qvn3g8xp.png";
    name = "d\U00f8gnNetto";
    "store_id" = d2283Zm;
    street = "Kollegiebakken 7";
    "zip_code" = 2800;
};
offers =     (
);
}
{ 
  ...
}

所以我的问题是,将数据从第二个闭包返回到函数内的第一个闭包的正确方法是什么?或者我是以完全错误的方式做到这一点?
问题是,我需要所有这些数据用于tableview,因此需要一次性所有数据.

解决方法

几点想法:

>如果有可能在服务器的单个请求中返回所有这些,则可能提供更好的性能.通常,与网络延迟相比,在服务器上执行请求所需的时间是无关紧要的.如果您可以避免需要发出一个请求,获得响应,然后发出更多请求,这将是理想的.

或者您可能提前在一定距离内请求位置,缓存该位置,然后“向我显示附近位置的交易”可能不需要这两组请求.

(我认识到这些都不适合你,但是如果可以的话,这是需虑的事项.如果你可以消除连续的请求并专注于大部分并发请求,你将获得更好的性能.)
>让我们假设一秒钟以上不是一个选项,并且你被困在一个请求以获得附近的位置和另一个集合来获得交易.然后你有几个选择:

>你肯定可以通过一次回调继续前进.例如,您可以发出所有请求,在发出每个请求之前执行dispatch_group_enter,在每个请求完成时执行dispatch_group_leave,然后发出dispatch_group_notify,当每个输入调用相应的偏移时,将调用dispatch_group_notify离开电话.因此,在每个请求完成时构建您的响应对象,并且只有在它们完成时,才调用完成闭包.>另一种方法是使一个闭包更像一个枚举闭包,一个在每个站点的交易进入时调用.这样,UI可以随着事物的进入而更新,而不是等待一切.如果您的网络速度很慢,那么在数据输入时更新UI可能会更容易接受. (例如,虑10个请求,每个请求在慢速3G蜂窝连接上完成1秒钟:观看它们每秒一次弹出比10秒钟看不到任何东西要容易得多).>话如此,你可能想完全放弃关闭.您可以虑委托协议模式,在其中为请求指定委托,然后为从服务器获取的每个响应实现协议方法.这样你可以在新的响应进入时更新UI,而不是在最后一个响应进入之前保留所有内容.但我们认识到有非常不同类型的响应(一个站点列表,另一个是列表处理给定的站点,第三个是“我已经完成”和/或“有错误”,所以当它开始变得复杂时,为这个接口定义一个协议可能会更好,并且这样处理它.

大佬总结

以上是大佬教程为你收集整理的在swift中具有多个闭包/ API请求的函数中的异步完成处理全部内容,希望文章能够帮你解决在swift中具有多个闭包/ API请求的函数中的异步完成处理所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。