Swift 中 AFNetworking 2.0 中的 Web 服务调用问题

Posted

技术标签:

【中文标题】Swift 中 AFNetworking 2.0 中的 Web 服务调用问题【英文标题】:Web Service call issue in AFNetworking 2.0 in swift 【发布时间】:2015-08-31 19:03:38 【问题描述】:

我正在使用 AFNetworking 2.0 快速调用 api如下 http://api.openweathermap.org/data/2.5/weather?q=Delhi

当我们在浏览器上点击这个 URL 时,我们会得到一个 JSON。这是一个 GET 请求。在邮递员上点击这个 api 也会产生相同的结果 现在我创建了一个帮助类 WebService.swift 并在其中调用了成功和错误块

我的WebService.swift类如下

import UIKit

class WebService: NSObject 

static let sharedInstance = WebService()


func weatherService(loginCode:String, requestData:NSMutableDictionary, successBlock: (response: AnyObject!,headers: NSDictionary, callBack:String ) -> Void, errorBlock: (error: NSError,headers:NSDictionary,responseObject:AnyObject!) -> Void)

    var serviceURL = "http://api.openweathermap.org/data/2.5/weather?q=Delhi"
    var manager = AFHTTPRequestOperationManager()
    manager.requestSerializer = AFJSONRequestSerializer()

    manager.responseSerializer.acceptableContentTypes = NSSet(objects: "text/html","application/json")  as? Set<NSObject>


    manager.requestSerializer.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")

    manager.GET(serviceURL, parameters: requestData, success:  (operation:AFHTTPRequestOperation, responseObject:AnyObject) -> Void in
        var headersCollection = operation.valueForKey("response")?.valueForKey("allHeaderFields") as! NSDictionary
        var headers = headersCollection.mutableCopy() as! NSMutableDictionary
        headers["statusCode"] = NSNumber(integer: operation.response!.statusCode)
           var _callBack = requestData["callBack"] as! String
        successBlock(response:responseObject,headers:headers,callBack: _callBack)


        )  (operation:AFHTTPRequestOperation, error:NSError) -> Void in


            var headersCollection = operation.valueForKey("response")?.valueForKey("allHeaderFields") as! NSDictionary
            var headers = headersCollection.mutableCopy() as! NSMutableDictionary
            headers["statusCode"] = NSNumber(integer: operation.response!.statusCode)

            errorBlock(error: error, headers: headers, responseObject: operation.responseObject)
    




 

我从视图控制器中调用的方法确实加载了

        let params = ["callBack": String(format: "%d", "weatherAPI")] as NSMutableDictionary

        WebService.sharedInstance.weatherService("URLHardcodedInWebServiceClass", requestData: params, successBlock:  (response, headers, callBack) -> Void in

            var dict = response as! NSDictionary


                println("Success with \(callBack)")

            )  (error, headers, responseObject) -> Void in

                println("failed")

        

现在的问题是,每次我进入 webservice 类的错误块时,作为 NSMutableDictionary 的标题的内容是


"Access-Control-Allow-Credentials" = true;
"Access-Control-Allow-Methods" = "GET, POST";
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Type" = "application/json; charset=utf-8";
Date = "Mon, 31 Aug 2015 18:53:36 GMT";
Server = nginx;
"Transfer-Encoding" = Identity;
"X-Source" = back;
statusCode = 200;
  

当我看到它显示的 NSError 时

打印错误描述:

Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" 
(JSON text did not start with array or object and option to allow fragments not set.) 
UserInfo=0x7fdb6865d5a0 NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.

我收到的状态码是 200 当我这样做时 po operation.responseString 我明白了

json 在那里,但有错误,我猜它的格式不正确。我尝试了内容类型为 text/html 的其他服务,它运行良好,因为我必须更改行

manager.requestSerializer.setValue("text/html; charset=utf-8", forHTTPHeaderField: "Content-Type")

其他服务的 URL 是 http://bluesapphireindia.in/WebService.asmx/GetEmployessJSON

这段代码运行良好

可能是什么原因。任何人都可以帮我解决这个问题。谢谢

【问题讨论】:

您是否尝试将响应序列化器设置为 afhttpresponseserializer 或 afjsonresponseserializer ? 【参考方案1】:

通过在Swift 中使用AFNetworking 中的AFHTTPRequestOperation 类,我在当前项目中以不同的方式做了同样的事情。希望对你有帮助。

 func afnStartConnectionWithURL(urlEndPoint: String, enumName: enumAPIname, httpMethod: String, httpBody: AnyObject, headerValue: String)

    var _URL = NSURL(string: kBaseURL + urlEndPoint)
    var currentTime: NSTimeInterval = 10

    var request = NSMutableURLRequest(URL: _URL!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: currentTime)
    request.HTTPMethod = httpMethod
    var err: NSError?
    if(httpMethod == kPOST)

        let jsonData:NSData = NSJSONSerialization.dataWithJSONObject(httpBody, options: .PrettyPrinted, error: nil)!
        request.HTTPBody = jsonData
    
    request.addValue(headerValue, forHTTPHeaderField: "Authorization")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    var op = AFHTTPRequestOperation(request: request)
    op.responseSerializer = AFJSONResponseSerializer()
    op.setCompletionBlockWithSuccess( (operation: AFHTTPRequestOperation!, responseObject: AnyObject!) -> Void in

        operation.cancel()
        var dicConnectionResponse:NSDictionary = responseObject as! NSDictionary
        self.afnConnection_Result(dicConnectionResponse, enumName: enumName, afhttpRequestOperation: operation)

        ,

        failure:  (operation: AFHTTPRequestOperation!, error:NSError!) -> Void in

            operation.cancel()
            self.afnConnection_Error(operation, enumName: enumName, error: error)
    )

    op.start()

这里的afnConnection_ResultafnConnection_Error 是回调委托方法。

【讨论】:

以上是关于Swift 中 AFNetworking 2.0 中的 Web 服务调用问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在旧的 AFNetworking 中使用 AFNetworking 2.0+?

从 AFNetworking 1.3 迁移到 AFNetworking 2.0 的问题

AfNetworking 2.0 发布问题

在 Afnetworking 2.0 中取消发布请求

Afnetworking 2.0 参数编码

AFNetworking 2.0 setImageWithURLRequest