Udacity OnTheMap:无法使用JSONSerialization将数据解析为JSON

时间:2016-12-26 13:31:21

标签: json swift3

我正在研究Udacity OnTheMap项目,由于某些原因无法在JSON中成功转换数据。我试图在Udacity的论坛上发帖,但没有得到及时回复,因此这里的帖子。验证udacity的功能是这样的:

func authenticateToUdacity(_ email: String, _ password: String, completionHandlerForAuth: @escaping (_ session: AnyObject?, _ error: NSError?) -> Void) {
    let request = NSMutableURLRequest(url: URL(string: "https://www.udacity.com/api/session")!)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = "{\"udacity\": {\"username\": \"\(email)\", \"password\": \"\(password)\"}}".data(using: String.Encoding.utf8)

    let session = URLSession.shared
    let task = session.dataTask(with: request as URLRequest) { data, response, error in
        if error != nil {
            print(error)
            completionHandlerForAuth(nil, NSError(domain: "authenticateToUdacity", code: 1, userInfo: nil))
            return
        }
        let range = Range(uncheckedBounds: (5, data!.count - 5))
        let newData = data?.subdata(in: range) /* subset response data! */
        print(NSString(data: newData!, encoding: String.Encoding.utf8.rawValue)!)
        print(NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!)


        let parsedResult: [String: AnyObject]!
        do {
            parsedResult = try JSONSerialization.jsonObject(with: newData!, options: .allowFragments) as? [String: AnyObject]
            print(parsedResult)                
        } catch {
            print("Error parsing result as JSON")
            completionHandlerForAuth("" as AnyObject?, nil)               
            return
        }

        completionHandlerForAuth("" as AnyObject?, nil)

    }
    task.resume()        
}

请注意,子数据的原因是因为前5个字符用于安全目的,我们需要截断前5个字符。

在这里,我总是得到“将结果解析为JSON的错误”,我怀疑数据和newData格式错误。当我同时打印newData(截断的)和数据(未截断)时,我的怀疑来了,结果如下:

  

{“account”:{“registered”:true,“key”:“xxxxxxxxxx”},“session”:{“id”:“yyyyyyyyyyyyyyyyyyyyy”,“expiration”:“2017-02-24T13:29: 05.59684   )]}“

     

{“account”:{“registered”:true,“key”:“xxxxxxxxxx”},“session”:{“id”:“yyyyyyyyyyyyyyyyyyyyy”,“expiration”:“2017-02-24T13:29: 05.596840Z“}}

无论如何,我尝试将两者都序列化,但两者似乎都没有成功解析。有人帮忙吗?

1 个答案:

答案 0 :(得分:0)

您需要在分析前删除前5个字符

类似的东西

guard let data = data.dropFirst(5) else {
        return
        }

您的代码将变为

func authenticateToUdacity(_ email: String, _ password: String, completionHandlerForAuth: @escaping (_ session: AnyObject?, _ error: NSError?) -> Void) {
    let request = NSMutableURLRequest(url: URL(string: "https://www.udacity.com/api/session")!)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = "{\"udacity\": {\"username\": \"\(email)\", \"password\": \"\(password)\"}}".data(using: String.Encoding.utf8)

    let session = URLSession.shared
    let task = session.dataTask(with: request as URLRequest) { data, response, error in
        guard let data = data.dropFirst(5) else {
        return
        }
        if error != nil {
            print(error)
            completionHandlerForAuth(nil, NSError(domain: "authenticateToUdacity", code: 1, userInfo: nil))
            return
        }
        let range = Range(uncheckedBounds: (5, data!.count - 5))
        let newData = data?.subdata(in: range) /* subset response data! */
        print(NSString(data: newData!, encoding: String.Encoding.utf8.rawValue)!)
        print(NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!)


        let parsedResult: [String: AnyObject]!
        do {
            parsedResult = try JSONSerialization.jsonObject(with: newData!, options: .allowFragments) as? [String: AnyObject]
            print(parsedResult)                
        } catch {
            print("Error parsing result as JSON")
            completionHandlerForAuth("" as AnyObject?, nil)               
            return
        }

        completionHandlerForAuth("" as AnyObject?, nil)

    }
    task.resume()        
}