AFNetworking Trim Characters From Response

亡梦爱人 提交于 2019-12-11 19:26:22

问题


I am using AFNetworking to call a web service using basic auth. The issue is that I get

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.}

When I allow fragments, I get

Invalid value around character 0

I spoke with our web developer and he is prefixing the JSON response with '//' for whatever reason so I need to trim those before I can use the JSON. My issue is that I'm not sure how to access the response to trim it and use it since the code immediately goes to the failure block.

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)")
            })
        }

回答1:


If the you set the responseSerializer as AFHTTPResponseSerializer with : manager.responseSerializer = AFHTTPResponseSerializer(), then responseObject should be a (NS)Data object.

What to do:
Get the value for "//" (let's call it prefixData).
Check if responseObject has it in prefix.
Remove if needed.

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
}

Sample code with force unwrap and silent try (try?) (don't do that) for the sake of the logic:

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!)")
} 

Output:

$>prefixData from String: <2f2f>
$>prefixData from Bytes: <2f2f>
$>prefixData == prefixData2, use the one you want
$>responseObject: <2f2f7b22 6b657922 3a227661 6c756522 7d>
$>jsonData: <7b226b65 79223a22 76616c75 65227d>
$>json: Optional({
key = value;
})
$>jsonString: {"key":"value"}



来源:https://stackoverflow.com/questions/51559807/afnetworking-trim-characters-from-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!