

Nature RemoのローカルAPIを使用したくてプログラムを書いてるのですが上手くいきません。  
ネットの記事を参考にしつつ、URLリクエストを送るプログラムを書きました。MacのターミナルでAPIを使用することはできたので、それをswiftで使用できないかと奔走中です。

ターミナルでは以下の通り実行するとAPIを使用できます。  
（AAAAAの部分はデバイスID、XXXは数字）  
http通信用のATSも試してみましたが上手くいきません。

ステータスコードが400なのでリクエストの内容が悪いのでしょうか。  
右も左もわからないほぼ初心者なので誰か教えていただけると嬉しいです。

**実行したコマンド:**

[code]

    curl -X POST 'http://AAAAA/messages' -H 'X-Requested-With: curl' -H 'accept: application/json' -d '{"format":"us","freq”:BB,”data":[XXX,XXX,XXX,XXX,・・・・・]}'
    
[/code]

**Swiftのコード:**

[code]

    import UIKit
        
    class ViewController: UIViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
        }
        
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
        
        @IBOutlet weak var label: UILabel!
        @IBAction func button(_ sender: Any) {
            
            // create the url-request
            let url = URL(string: "http://XXXXXX/messages")!
            var request = URLRequest(url: url)
            
            //set the method
            request.httpMethod = "POST"
            //add the header
            request.setValue("X-Requested-With: curl", forHTTPHeaderField: "Expect")
            request.setValue("accept: application/json", forHTTPHeaderField: "Content-Type")
            
            // set the request-body(JSON)
            let json:[String:Any] = [
                "format":"us",
                "freq":"38",
                "data":[8918,4554,473,657,476,654,500,631,504,627,499,637,503,1739,530,590,481,1762,494,1741,499,1744,494,1738,509,614,522,1720,478,1762,500,639,469,1763,498,1738,471,655,478,661,506,1721,547,586,479,1765,470,1771,494,1738,472,665,466,1768,469,1767,553,574,476,1767,470,660,499,632,474,675,455,39790,553,199,329,192,204,189,174,226,171,227,184,205,251,198,170,195,174,197,171,199,147,196,194,199,171,198,197,171,168,252,189,233,161,208,172,200,170,192,200,197,170,200,169,2464,351
                ],
            ]
            
            //add the "json" as a top level ovject's fact
            request.httpBody = try? JSONSerialization.data(withJSONObject: json)
            
            // use URLSessionDataTask
            let session = URLSession.shared
            session.dataTask(with: request) {(data, response, error) in
                if error == nil, let data = data, let response = response as? HTTPURLResponse {
                    
                    // HTTPヘッダの取得
                    print("Content-Type: \(response.allHeaderFields["Content-Type"] ?? "")")
                    // HTTPステータスコード
                    print("statusCode: \(response.statusCode)")
                    print(String(data: data, encoding: String.Encoding.utf8) ?? "")
                }
            }.resume()
            
        }
        
    }
    
[/code]


CC BY-SA 4.0
2020-11-22T19:00:09.467
72151
2020-11-24T00:52:23.143
2020-11-24T00:35:56.607
3060
42832
question
swift api
Nature RemoのローカルAPIをswiftで使用したい。しかしステータスコード400が表示される。


記載がないので直接関係しているか不明ですが、Appleのアプリケーションはhttp通信に`ATS`というセキュリティ設定が必用で、`https://`な通信のみ許可され、`http://`な通信は不許可になっていると思います。  
ソースコードを実行したときにデバッグエリアに`ATS`に関する警告が出ていないか確認して下さい。  
これを回避するためにそのアプリケーションのプロジェクトファイルの、`Info.plist`に

[code]

    <key>NSAppTransportSecurity</key>
        <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>AAAAA/key>
                <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
            </dict>
        </dict>
    </dict>
    
[/code]

のような記載が必用かと思いますが、この設定をされているでしょうか？  
この例が間違っている可能性もあるので、詳しくは`ATS` `http` `許可`等で調べて正しい値を設定することが必用です。


CC BY-SA 4.0
2020-11-22T19:20:51.923
72152
2020-11-22T19:20:51.923
14745
72151
answer


Чайка さんへのコメントに、「ステータスコードは400でした」と書かれているので、「元々400だった」と判断しました。

Nature
Remoの現物はありませんので、ご質問・コメントの内容から考えての1つの可能性としか言えませんが、現在のあなたのSwiftコードは「APIを使用できます」と書かれたcurlが送信するヘッダとは異なるヘッダを送信していますので、まずはそこを修正してみてください。

curlで`-H 'X-Requested-With: curl'`と指定する場合、ヘッダフィールド名が`X-Requested-
With`で、その値が`curl`です。

したがって、あなたのcurlコマンドに合わせたヘッダを送信するSwiftコードは以下のようになります。

[code]

            //add the header
            request.setValue("curl", forHTTPHeaderField: "X-Requested-With")
            request.setValue("application/json", forHTTPHeaderField: "accept")
    
[/code]

こちらの手元で試すことができないので確実なことが言えなくて申し訳ありませんが、当然 Чайка
さんの書かれたATS設定は正しいか、curlで指定した`http://AAAAA/messages`とSwiftコード中の`http://XXXXXX/messages`は本当に同じURLなのか(`AAAAA`と`XXXXXX`と使い分けられている点が気になります)などの点については、何度でも再チェックした上で試してみてください。


CC BY-SA 4.0
2020-11-24T00:52:23.143
72169
2020-11-24T00:52:23.143
13972
72151
answer