ios - 如何使用 Alamofire 等待 api 响应

Posted

技术标签:

【中文标题】ios - 如何使用 Alamofire 等待 api 响应【英文标题】:ios - How to wait api response using Alamofire 【发布时间】:2018-02-28 10:55:54 【问题描述】:

我想在Alamofire 中询问Semaphore。 我希望应用程序等待来自服务器的数据返回成功并在(同步类型)之后继续执行代码。我用semaphore,但是调用api函数的时候,app被挂起...

这段代码是来自服务器的调用数据:

func getAllModels() -> [String] 
    var _modelList:[String] = []
    let url = BASE_URL + "getAllProductAndModelv2"

    let semaphore = DispatchSemaphore(value: 0)

    Alamofire.request(url, method:.get, parameters: [:], encoding: JSONEncoding.default).responseJSON  response in
        let data = NSData(contentsOf: URL(string: url)!)
        do 
            if let data = data, let json = try JSONSerialization.jsonObject(with: data as Data) as? [String: Any], let models = json["models"] as? [[String:Any]] 
                for model in models 
                    if let name = model["name"] as? String 
                        _modelList.append(name)
                    
                
            
        catch 
            print("error")
        
        semaphore.signal()
    
    semaphore.wait()
    return _modelList

而这段代码会得到结果:

let api = RestApiManager()
var result:[String] = api.getAllModels()
print(result)

如何解决这个问题? 谢谢

【问题讨论】:

使用闭包代替,您正在调用异步网络方法 使用完成闭包:***.com/questions/32371792/… 为什么不使用串行队列? 你的应用被暂停是什么意思? 除非您有经验,但似乎并非如此,否则不要使用信号量(恕我直言,这是高级编码),并避免将异步转换为同步,而是了解它的工作原理以及如何使用它。此外,您正在使用 Alamofire,然后在其中使用 NSData contentOfUrl,而您应该已经准备好数据,这是两次调用,并且 Alamofire 应该已经为您反序列化 JSON。否则,应用程序将暂停,因为您在等待响应(两次)时阻塞了当前线程(主线程)。 【参考方案1】:

使用补全

 func getAllModels( completion: @escaping ([String] ,Bool) -> Void) 

    var modelList:[String] = []

    let url = BASE_URL + "getAllProductAndModelv2"

    Alamofire.request(url, method:.get, parameters: [:], encoding: JSONEncoding.default).responseJSON  response in
        let data = NSData(contentsOf: URL(string: url)!)
        do 
            if let data = data, let json = try JSONSerialization.jsonObject(with: data as Data) as? [String: Any], let models = json["models"] as? [[String:Any]] 
                for model in models 
                if let name = model["name"] as? String 
                    modelList.append(name)
                
            

                completion(modelList,true)
            
        catch 
            print("error")
             completion([],false)
        

    


然后调用它

 self.getAllModels  (data, success) in

        if(success)
        
            // use data

        
    

【讨论】:

以上是关于ios - 如何使用 Alamofire 等待 api 响应的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Alamofire 进行贝宝付款 [iOS] [关闭]

等待多个 Alamofire 请求完成

Alamofire 等待完成

在 Alamofire 中,等待一组调用完成的正确方法是啥?

Swift Alamofire 检查等待超时并放置错误

更新到iOS 11.1后,Alamofire 4.5.1失败