代码之家  ›  专栏  ›  技术社区  ›  ankit

后请求出现NSURLSession序列化错误

  •  1
  • ankit  · 技术社区  · 9 年前

    我正在尝试获取Instagram的访问令牌,但经常出错 You must provide client id . 我认为这是一个序列化问题,因为我的参数没有正确序列化。 我试过了 POSTMAN 它运行良好,但仍在继续 NSURLSession 它抛出错误。

    错误

    {
        code = 400;
        "error_message" = "You must provide a client_id";
        "error_type" = OAuthException;
    }
    

    在序列化时,我在这里做错了什么。

    let instaInfoDict = NSDictionary(objects: ["client_id","client_secret","grant_type","redirect_uri","code"], forKeys: [kCLientIdInstagram,kCLientSecretIdInstagram,"authorization_code",kRedirectUriInstagram,code])
    // Hit post request with params
    WebServices().postRequest(kAccessTokenGenerationInstagram, bodyData: instaInfoDict, completionBlock: { (responseData) in
                    print(responseData)
    
    })
    
    
    //WEBSERVICE CLASS:
    
     func postRequest(url:String, bodyData:NSDictionary, completionBlock:WSCompletionBlock){
            if let url = NSURL(string: url){
                let headers = [
                    "Accept": "application/json",
                    "content-type": "application/json"]
    
                let session = NSURLSession.sharedSession()
    
                let request = NSMutableURLRequest(URL: url, cachePolicy: .UseProtocolCachePolicy, timeoutInterval: 10)
                request.HTTPMethod = "POST"
                request.allHTTPHeaderFields = headers
    
                request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(bodyData, options: [.PrettyPrinted])
    
                let task =  session.dataTaskWithRequest(request, completionHandler: { (data, response, error) in
           if error != nil {
                // Handle error
    
    
                completionBlock!(responseData:nil)
            }
            else{
    //Parsing the data
                let parsedData = parseJson(response as? NSData)
    
                completionBlock!(responseData: parsedData)
    
            }
    
                })
    
                task.resume()
            }
    
    
        }
    

    我也试过这个

    request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(bodyData, options: NSJSONWritingOptions(rawValue: 0))
    
    1 回复  |  直到 9 年前
        1
  •  2
  •   tolkiana    9 年前

    似乎问题是内容类型应该是 application/x-www-form-urlencoded 而不是 application/json ,同样,使用这种内容类型发送参数的方式也发生了一些变化。

    我做了一个小测试,这个代码对我很有用:

    static func generateAccessToken() {
    
        let params = ["client_id": "your_id",
                      "client_secret": "your_client_secret",
                      "grant_type": "authorization_code",
                      "redirect_uri": "http://tolkianaa.blogspot.com/",
                      "code": "the_code"]
    
    
        guard let url = NSURL(string: "https://api.instagram.com/oauth/access_token") else {
            return
        }
        let request = NSMutableURLRequest(URL: url)
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.HTTPMethod = "POST"
    
        let stringParams = params.paramsString()
        let dataParams = stringParams.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
        let paramsLength = String(format: "%d", dataParams!.length)
        request.setValue(paramsLength, forHTTPHeaderField: "Content-Length")
        request.HTTPBody = dataParams
    
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
            var json: AnyObject = [:]
    
            guard let data = data else {
                return
            }
    
            do {
                json = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
            } catch {
                // Do nothing
            }
    
            print(json)
        }
    
        task.resume()
    }
    

    为了获取字符串形式的参数,我做了以下扩展:

    extension Dictionary {
    
    func paramsString() -> String {
        var paramsString = [String]()
        for (key, value) in self {
            guard let stringValue = value as? String, let stringKey = key as? String else {
                return ""
            }
            paramsString += [stringKey + "=" + "\(stringValue)"]
    
        }
        return (paramsString.isEmpty ? "" : paramsString.joinWithSeparator("&"))
    }
    

    }

    希望能有所帮助!