[解決済み] パラメータ付きSwift GETリクエスト
質問
私はswiftの初心者なので、おそらく私のコードには多くの欠陥があるでしょう。
GET
リクエストをパラメータ付きでローカルホストサーバーに送信することです。もっと言うと、私は私の関数が2つのパラメータを取ることを考えると、それを達成しようとしています。
baseURL:string,params:NSDictionary
. 私はそれらの2つを実際のURLRequestに結合する方法がわからないのですか?以下は、私がこれまでに試したものです。
func sendRequest(url:String,params:NSDictionary){
let urls: NSURL! = NSURL(string:url)
var request = NSMutableURLRequest(URL:urls)
request.HTTPMethod = "GET"
var data:NSData! = NSKeyedArchiver.archivedDataWithRootObject(params)
request.HTTPBody = data
println(request)
var session = NSURLSession.sharedSession()
var task = session.dataTaskWithRequest(request, completionHandler:loadedData)
task.resume()
}
}
func loadedData(data:NSData!,response:NSURLResponse!,err:NSError!){
if(err != nil){
println(err?.description)
}else{
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println(jsonResult)
}
}
どのように解決するのですか?
を構築する際に
GET
リクエストを構築する場合、リクエストのボディはなく、 すべてが URL になります。URL を構築するために (そして適切にパーセントエスケープするために)
URLComponents
.
var url = URLComponents(string: "https://www.google.com/search/")!
url.queryItems = [
URLQueryItem(name: "q", value: "War & Peace")
]
唯一のトリックは、ほとんどのウェブサービスが
+
文字がパーセントエスケープされていることです (これは
application/x-www-form-urlencoded
仕様
). しかし
URLComponents
はそれをパーセントエスケープしないでしょう。Apple は次のように主張しています。
+
はクエリで有効な文字であり、したがってエスケープされるべきではないと主張しています。技術的には、URI のクエリで許可されていることは正しいのですが、この文字は
application/x-www-form-urlencoded
リクエストでは特別な意味を持ち、本当にエスケープされずに渡されるべきではありません。
をパーセントでエスケープする必要があることを Apple は認めています。
+
文字をパーセントでエスケープする必要があることを認めていますが、それを手動で行うように助言しています。
var url = URLComponents(string: "https://www.wolframalpha.com/input/")!
url.queryItems = [
URLQueryItem(name: "i", value: "1+2")
]
url.percentEncodedQuery = url.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
これは非効率的な回避策ですが、動作はしますし、クエリに
+
文字が含まれ、それをスペースとして解釈するサーバーがある場合、Apple が推奨する方法です。
というわけで、これをあなたの
sendRequest
ルーチンと組み合わせると、次のようなものが出来上がります。
func sendRequest(_ url: String, parameters: [String: String], completion: @escaping ([String: Any]?, Error?) -> Void) {
var components = URLComponents(string: url)!
components.queryItems = parameters.map { (key, value) in
URLQueryItem(name: key, value: value)
}
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
let request = URLRequest(url: components.url!)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard
let data = data, // is there data
let response = response as? HTTPURLResponse, // is there HTTP response
200 ..< 300 ~= response.statusCode, // is statusCode 2XX
error == nil // was there no error
else {
completion(nil, error)
return
}
let responseObject = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any]
completion(responseObject, nil)
}
task.resume()
}
といった感じで呼び出すのでしょう。
sendRequest("someurl", parameters: ["foo": "bar"]) { responseObject, error in
guard let responseObject = responseObject, error == nil else {
print(error ?? "Unknown error")
return
}
// use `responseObject` here
}
個人的には
JSONDecoder
を返すようになりました。
struct
を返すようになりましたが、これはここではあまり関係ありません。これで、GETリクエストのURLにパラメータをパーセントエンコードする方法の基本的な考え方が示されたかと思います。
参照 この回答の前の改訂版 をご覧ください。
関連
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Swiftでindexとelementでループを反復させる方法
-
[解決済み] Swiftの@selector()?
-
[解決済み] iPhone UITextField - プレースホルダーの文字色を変更する
-
[解決済み] UINavigationBarの1px下の行を非表示にする方法
-
[解決済み] Swiftを使用してアプリのバージョンとビルド番号を取得するにはどうすればよいですか?
-
[解決済み] NSNotificationCenterのaddObserver in Swift
-
[解決済み] UIImageのサイズを変更する最も簡単な方法?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[iOS]コンパイルエラー:ld: アーキテクチャ x86_64 のシンボルが見つかりません。
-
[エラー処理】iOSのエラー、アーキテクチャx86_64の未定義シンボルについて
-
[解決済み] iOSのステータスバーの文字色を変更する方法
-
[解決済み] 文字列の長さを取得する
-
[解決済み] SwiftでStringを配列に分割する?
-
[解決済み] iOS7でスタイルUITableViewStyleGroupedを持つUITableViewの上部に余分なパディングがあるのはなぜですか?
-
[解決済み] Xcode 12、iOS Simulator用にビルドしても、iOS用にビルドされたオブジェクトファイルでは、アーキテクチャ「arm64」用にリンクされます。
-
[解決済み] UIViewの左上と右上だけにcornerRadiusを設定する方法は?
-
[解決済み] iOS 11、Apple TV 4Kなどを搭載したXcode 9でワイヤレスデバッグを行う方法とは?
-
[解決済み】SwiftでPOSTメソッドを使ったHTTPリクエスト