3223


以下の `curl` のコマンドを Swift で実現したいです。しかしヘッダ部分の記述方法がわかりません。

[code]

    curl -X GET \
         --header "X-Auth-Token: abcdef" \
         https://devapi.thecurrencycloud.com/v2/rates/detailed?buy_currency=EUR&sell_currency=USD&fixed_side=buy&amount=1000
    
[/code]

こちらが私のコードです。しかしエラーとなってしまいました。解決方法をご教示頂きたいです。

[code]

    func exchangerate(){
        let token = "abcdef"
        let request = NSMutableURLRequest(URL: NSURL(string: "https://devapi.thecurrencycloud.com/v2/rates/detailed")!)
        var buyCurrency = "EUR"
        var sellCurrency = "USD"
        var fixSide = "buy"
        var amount = "1000"
        var postString:NSString = "buy_currency=\(buyCurrency)&sell_currency=\(sellCurrency)&fixed_side=\(fixSide)&amount=\(amount)"
    
        request.HTTPMethod = "GET"
        request.setValue(token, forHTTPHeaderField: "X-Auth-Token")
        request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in
    
            if error != nil {
                println("error=\(error)")
                return
            }
    
            println("response = \(response)")
    
            let responseStringExchangeRate = NSString(data: data, encoding: NSUTF8StringEncoding)
            println("responseStringExchangeRate = \(responseStringExchangeRate)")
        }
        task.resume()
    
    }
    
[/code]

エラー:

[code]

    error=Error Domain=NSURLErrorDomain 
          Code=-1005 
          "The operation couldn’t be completed. (NSURLErrorDomain error -1005.)" 
          UserInfo=0x7fea7b4d63f0
          {
             NSErrorFailingURLStringKey=https://devapi.thecurrencycloud.com/v2/rates/detailed,
            NSErrorFailingURLKey=https://devapi.thecurrencycloud.com/v2/rates/detailed,             _kCFStreamErrorDomainKey=4,
            _kCFStreamErrorCodeKey=-4, 
            NSUnderlyingError=0x7fea7d805ba0
            "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1005.)"
          }
    
[/code]


CC BY-SA 3.0
2015-01-06T23:19:23.080
3222
2015-01-07T02:00:03.460
2015-01-06T23:52:54.480
4978
6098
question
swift http nsurlsession
`curl --header $1` と同じことを Swift で実現したい (NSURLSessionのヘッダの記述)


~~`request.HTTPMethod = "POST"` ですかね？~~

以下を test.swift として保存。(以下、修正します)

[code]

    import Foundation
    
    func exchangerate(){
        let token = "abcdef"
        // let request = NSMutableURLRequest(URL: NSURL(string: "https://devapi.thecurrencycloud.com/v2/rates/detailed")!)
        var buyCurrency = "EUR"
        var sellCurrency = "USD"
        var fixSide = "buy"
        var amount = "1000"
        //var postString:NSString = "buy_currency=\(buyCurrency)&sell_currency=\(sellCurrency)&fixed_side=\(fixSide)&amount=\(amount)"
        let request = NSMutableURLRequest(URL: NSURL(string: "https://devapi.thecurrencycloud.com/v2/rates/detailed?buy_currency=\(buyCurrency)&sell_currency=\(sellCurrency)&fixed_side=\(fixSide)&amount=\(amount)")!)
    
    
        request.HTTPMethod = "GET"
        //request.HTTPMethod = "POST"
    
        request.setValue(token, forHTTPHeaderField: "X-Auth-Token")
        // request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in
    
            if error != nil {
                println("error=\(error)")
                return
            }
    
            println("response = \(response)")
    
            let responseStringExchangeRate = NSString(data: data, encoding: NSUTF8StringEncoding)
            println("responseStringExchangeRate = \(responseStringExchangeRate)")
        }
        task.resume()
    }
    
    // for debug.
    exchangerate()
    sleep(10)
    
[/code]

実行。

[code]

    $ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift test.swift
    response = <NSHTTPURLResponse: 0x7f8390793810> { URL: https://devapi.thecurrencycloud.com/v2/rates/detailed } { status code: 401, headers {
        Connection = "keep-alive";
        "Content-Length" = 176;
        "Content-Type" = "application/json";
        Date = "Wed, 07 Jan 2015 00:11:17 GMT";
        Server = nginx;
        "X-Content-Type-Options" = nosniff;
        "X-Request-Id" = 2693396219771410479;
    } }
    responseStringExchangeRate = Optional({"error_code":"auth_failed","error_messages":{"username":[{"code":"invalid_supplied_credentials","message":"Authentication failed with the supplied credentials","params":{}}]}})
    $
    
[/code]

  

## 追記

(以下、ちょっと乱暴な説明です、ごめんなさい)

質問にあった GET でのリクエストは、サーバに対して、

[code]

    GET /v2/rates/detailed HTTP/1.1
    Host: devapi.thecurrencycloud.com
    X-Auth-Token: abcdef
    (空行)
    buy_currency=EUR&sell_currency=USD&fixed_side=buy&amount=1000
    
[/code]

のような文字列を送信しているのだと思います。

対して私が回答したものは、

[code]

    GET /v2/rates/detailed?buy_currency=EUR&sell_currency=USD&fixed_side=buy&amount=1000 HTTP/1.1
    Host: devapi.thecurrencycloud.com
    X-Auth-Token: abcdef
    (空行)
    
[/code]

という文字列を送信します。

また、POST の場合は、

[code]

    POST /v2/rates/detailed HTTP/1.1
    Host: devapi.thecurrencycloud.com
    X-Auth-Token: abcdef
    (空行)
    buy_currency=EUR&sell_currency=USD&fixed_side=buy&amount=1000
    
[/code]

といった文字列を送信します。

(空行)以前が、いわゆるHTTP リクエストヘッダで、以降はリクエストボディ(request.HTTPBody)です。

サーバ側で、GET でリクエストを受けたなら、 リクエストボディは読まないで、レスポンスをしてしまうのだと思います。また、POST
であれば、リクエストボディまでちゃんと読んでくれてたのだと思います。

なので、エラーメッセージが

`"The operation couldn’t be completed. (NSURLErrorDomain error -1005.)`

となって、「まだ、サーバに話したいことがあるのに(リクエストボディを送っていないのに)。。」(超意訳)

となったのだと思います。


CC BY-SA 3.0
2015-01-07T00:16:11.293
3223
2015-01-07T02:00:03.460
2015-01-07T02:00:03.460
2992
2992
3222
answer