AFNetworking 从响应中修剪字符

Posted

技术标签:

【中文标题】AFNetworking 从响应中修剪字符【英文标题】:AFNetworking Trim Characters From Response 【发布时间】:2018-07-27 14:12:46 【问题描述】:

我正在使用 AFNetworking 使用基本身份验证调用 Web 服务。问题是我得到了

FAILURE: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo=NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.

当我允许片段时,我得到

Invalid value around character 0

我与我们的 Web 开发人员交谈过,无论出于何种原因,他都在 JSON 响应前加上“//”,因此我需要先修剪这些内容,然后才能使用 JSON。我的问题是我不确定如何访问响应来修剪它并使用它,因为代码会立即进入失败块。

let manager = AFHTTPSessionManager(baseURL: URL(string: "http://mydev1.kyfb.com/remote/appinfo.cfc?method=GetMemberInfo"))
            manager.requestSerializer.setAuthorizationHeaderFieldWithUsername(emailTextField.text!, password: passwordTextField.text!)
            // manager.responseSerializer = AFJSONResponseSerializer(readingOptions: .allowFragments)
            // manager.responseSerializer = AFHTTPResponseSerializer()
            manager.post("", parameters: nil, progress: nil, success: 
                (task, responseObject) -> Void in
                // TODO: If error message returned in JSON response, display error
                // else login was successful. Save user info to User object and push AccountTableViewController
                print("RESPONSE OBJECT: \(responseObject!)")
                let responseJSON = responseObject as? [String: AnyObject]
                print("RESPONSE JSON: \(responseJSON)")
                if responseJSON!["MEMBERSHIPNUMBER"] != nil 

                

            , failure: 
                (operation, error) -> Void in
                // TODO: Display error
                print("FAILURE: \(error)")
            )
        

【问题讨论】:

使用manager.responseSerializer = AFHTTPResponseSerializer() 而不是AFJSONResponseSerializer。那么responseObject 应该是(NS)Data 一个。将// 转换为(NS)Data 并将其从responseObject 中删除。 (或直接检查"//".data(encoding: .utf8) 的值以拥有(NS)Data)。然后执行responseJSON = JSONSerialization.object(withData: newResponseObject, options: []) 或类似的操作。 【参考方案1】:

如果您将responseSerializer 设置为AFHTTPResponseSerializer 与:manager.responseSerializer = AFHTTPResponseSerializer(),那么responseObject 应该是(NS)Data 对象。

做什么: 获取"//" 的值(我们称之为prefixData)。 检查responseObject 是否有前缀。 如果需要,请删除。

let prefixData = "//".data(using: .utf8)!        
//OR let prefixData = Data(bytes: [0x2F, 0x2F])

let responsePrefix = responseObject.subdata(in: Range(0..<2))
if responsePrefix == prefixData 
    let jsonData = responseObject.subdata(in: Range(2..<responseObject.count))
    //You got your JSON to serialize with Codable or JSONSerialization

出于逻辑考虑,带有强制解包和静默尝试(尝试?)(不要那样做)的示例代码:

let prefixData = "//".data(using: .utf8)!
print("prefixData from String: \(prefixData as NSData)")

let prefixData2 = Data(bytes: [0x2F, 0x2F])
print("prefixData from Bytes: \(prefixData2 as NSData)")

if prefixData == prefixData2 
    print("prefixData == prefixData2, use the one you want")


let responseObject = "//\"key\":\"value\"".data(using: .utf8)!
print("responseObject: \(responseObject as NSData)")

let responsePrefix = responseObject.subdata(in: Range(0..<2))
if responsePrefix == prefixData 
    let jsonData = responseObject.subdata(in: Range(2..<responseObject.count))
    print("jsonData: \(jsonData as NSData)")
    let json = try? JSONSerialization.jsonObject(with: jsonData, options: [])
    print("json: \(json!)")
    let jsonString = String(data: jsonData, encoding: .utf8)
    print("jsonString: \(jsonString!)")
 

输出:

$>来自字符串的前缀数据: $>prefixData 来自字节: $>prefixData == prefixData2,使用你想要的 $>响应对象: $>jsonData: $>json:可选( 键=值; ) $>jsonString: "key":"value"

【讨论】:

以上是关于AFNetworking 从响应中修剪字符的主要内容,如果未能解决你的问题,请参考以下文章

[AFN]AFNetworking错误总结

AFNetworking:无法从 AFHTTPRequestOperation 获取响应字符串

IOS AFN (第三方请求)

如何从服务器获取 AFNetworking 中的完整响应字符串?

AFN2.0到3.0的迁移

iOS开发之AFN的基本使用