问题
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