将curl命令转换为iOS

3
以下curl命令适用:
curl -G -H "api_key: MYAPIKEY" https://api.semantics3.com/test/v1/products -d 'q={"upc":"70411576937"}'

然而,当我试图将其转换为iOS时,我遇到了以下错误:
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." {NSErrorFailingURLStringKey=https://api.semantics3.com/test/v1/products,...}

以下是我的代码,但我认为我的问题出在提交到URL的JSON数据前面的“q =”上。如果是这样,这叫什么名字,我该如何在我的JSON数据之前加上“q =”?由于iOS始终能够提供与错误消息无关的信息,所以我不能确定。谢谢。

    var urlString = "https://api.semantics3.com/test/v1/products"
    var request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
    var response: NSURLResponse?
    var error: NSErrorPointer = nil
    var reqText = ["upc": "70411576937"]
    var err: NSError?

    request.HTTPBody = NSJSONSerialization.dataWithJSONObject(reqText, options: nil, error: &err)
    request.HTTPMethod = "GET"
    request.addValue("MYAPIKEY", forHTTPHeaderField: "api_key")
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    var session = NSURLSession.sharedSession()

    var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
        if(err != nil) {
            println(err!.localizedDescription)
        }
        else {
            //this is where the error is printed
            println(error)
            var parseError : NSError?
            // parse data
            let unparsedArray: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: &parseError)
            println(parseError)
            if let resp = unparsedArray as? NSDictionary {
                println(resp)
            }
        }
    })
    task.resume()

我知道这听起来很傻,但是试着退出模拟器并重新运行应用程序。有时候我的模拟器在闲置一晚或更长时间后会失去连接。 - AdamPro13
2个回答

1

在GET http方法中不使用Body。使用以下代码来连接您的参数:

extension String {

    /// Percent escape value to be added to a URL query value as specified in RFC 3986
    ///
    /// This percent-escapes all characters besize the alphanumeric character set and "-", ".", "_", and "~".
    ///
    /// http://www.ietf.org/rfc/rfc3986.txt
    ///
    /// :returns: Return precent escaped string.

    func stringByAddingPercentEncodingForURLQueryValue() -> String? {
        let characterSet = NSMutableCharacterSet.alphanumericCharacterSet()
        characterSet.addCharactersInString("-._~")

        return self.stringByAddingPercentEncodingWithAllowedCharacters(characterSet)
    }

}

extension Dictionary {

    /// Build string representation of HTTP parameter dictionary of keys and objects
    ///
    /// This percent escapes in compliance with RFC 3986
    ///
    /// http://www.ietf.org/rfc/rfc3986.txt
    ///
    /// :returns: String representation in the form of key1=value1&key2=value2 where the keys and values are percent escaped

    func stringFromHttpParameters() -> String {
        let parameterArray = map(self) { (key, value) -> String in
            let percentEscapedKey = (key as! String).stringByAddingPercentEncodingForURLQueryValue()!
            let percentEscapedValue = (value as! String).stringByAddingPercentEncodingForURLQueryValue()!
            return "\(percentEscapedKey)=\(percentEscapedValue)"
        }

        return join("&", parameterArray)
    }

}


var urlString = "https://api.semantics3.com/test/v1/products"
var reqText = ["upc": "70411576937"]
var err: NSError?

let parameterString = reqText.stringFromHttpParameters()
let requestURL = NSURL(string:"\(urlString)?\(parameterString)")!

var request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
var response: NSURLResponse?
var error: NSError?

request.HTTPMethod = "GET"
request.addValue("MYAPIKEY", forHTTPHeaderField: "api_key")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var session = NSURLSession.sharedSession()

部分编辑:SWIFT 2.1(更新)
extension Dictionary {

    func stringFromHttpParameters() -> String {
        let parameterArray = self.map { (key, value) -> String in
            let percentEscapedKey = (key as! String).stringByAddingPercentEncodingForURLQueryValue()!
            let percentEscapedValue = (value as! String).stringByAddingPercentEncodingForURLQueryValue()!
            return "\(percentEscapedKey)=\(percentEscapedValue)"
        }

        return parameterArray.joinWithSeparator("&")
    }

}

1
谢谢。我的问题是我的NSURL没有识别花括号,但是stringByAddingPercentEncodingForURLQueryValue()方法为我解决了这个问题。 - Jason Javier
使用Swift 2时,在扩展Dictionary的第二行中出现错误,错误信息为:“Cannot invoke 'map' with an argument list of type '(Dictionary<Key,Value),(_,_) -> String)'”。有任何修复方法吗? - SMKS
我更新了Dictionary扩展,使其与Swift 2.1兼容。但我仍不确定为什么必须将函数分成两部分才能编译。一旦在map的闭包中声明一个带有let的变量,编译器就会抱怨。我可能会再发一个问题来解决这个问题。 - John Difool
我认为我找到了问题所在。闭包需要指定返回类型,但我认为它可以从代码中推断出来。这似乎是编译器中的一个错误。 - John Difool

0

将您的JSON转换为字符串,将q=添加到此字符串前面,然后将结果字符串转换为数据并将其分配给请求的HTTPBody。

可能像这样:

let array = [ "one", "two" ]
let data = NSJSONSerialization.dataWithJSONObject(array, options: nil, error: nil)
let body= "q=" + NSString(data: data!, encoding: NSUTF8StringEncoding)
request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接