【Swift】Alamofire を使って色んなリクエストを投げてみる
iOSでHTTPリクエストをする際によく使われるAlamofire の使い方を紹介します。
Alamofire は HTTPリクエストをするのにrequest, download, upload メソッドが用意されています。
今回はこれらの基本的な使い方について紹介しようと思います。
事前に用意したものとしては、web サーバーを適当に立てています。
今回はRails で localhost:3000 でアクセスできるようにしておきました。
あと、xcode 上でhttps でなくても通信できようにInfo.plist に
NSAppTransportSecurity
をDictionaryで追加し、その下に
NSAllowsArbitraryLoads
を YES で設定しています。
ちなみに Alamofire のバージョンは4.7.2 です。
request メソッド
request はその名前の通りシンプルにHTTPリクエストをするのに使用されます。
http メソッドについては以下のようにenum が定義されており、まぁ全部網羅されてます。
public enum HTTPMethod: String { case options = "OPTIONS" case get = "GET" case head = "HEAD" case post = "POST" case put = "PUT" case patch = "PATCH" case delete = "DELETE" case trace = "TRACE" case connect = "CONNECT" }
get リクエストを投げてみます。
let urlString: String = "http://localhost:3000" let parameters: Parameters = ["foo": "bar"] Alamofire.request(urlString, method: .get, parameters: parameters) .downloadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in print("Progress: \(progress.fractionCompleted)") } .validate { request, response, data in // Custom evaluation closure now includes data (allows you to parse data to dig out error messages if necessary) return .success } .responseJSON { response in debugPrint(response) switch response.result { case .success: print("Success!") case .failure: print("Failure!") } }
上記の場合、シンプルにhttp://localhost:3000?foo=bar というURLのリクエストが送信されます。
responseJSON
としているので、レスポンスボディをjson パースできないとresponseSerializationFailed
というエラーになります。
また、公式のgithub のguide ページで紹介されているコードだと
Alamofire.request(urlString, method: .get, parameters: parameters, encoding: JSONEncoding.default)
となっていますが、encoding: JSONEncoding.default は、JSON形式でパラメータを送るためにリクエストヘッダーにContentType:application/json と付与する方法でここでは不要なのと、実際につけて送信すると、なぜかリクエストがTimeout になってしまいました。
.post では正常にリクエストされます。
timeout になったあとに、response をdebug してみるとどんなリクエストを送ったかわかるのですが、それと同じように curl コマンドなどでリクエストをしてみると正常に通るので、謎です。
調べたら、issue が立ってました。 https://github.com/Alamofire/Alamofire/issues/1819
まぁ、シンプルなパラメータ構造ならjson encoding は不要なので一旦飛ばします。
validate
上記コードのvalidate というメソッドですが、これはレスポンスを受け取ったあとに、ヘッダの情報をみてエラーと判断したい場合に有効です。
例えば、API通信をした際に、レスポンスヘッダのContent Type がキチンとapplication/json になっているかを確認し、なっていなかったら失敗としたい場合は
Alamofire.request(urlString, method: .get, parameters: parameters) .validate(contentType: ["application/json"]) .responseJSON { response in ...
とすればOKです。
download メソッド
download はHTTPリクエストした結果のレスポンスをローカルに保存するために使用されます。その用途としては例えば、web上にあるpdf をダウンロードしてビューアーで表示、みたいな感じです。
ここでは、それを実装してみます。
下記を参考にしました。
Swift3とAlamofireでPDFファイルをダウンロードしてReaderで表示する
Reader のライブラリは vfrReader というやつの2.8.6 を使っています。
class ViewController: UIViewController, ReaderViewControllerDelegate { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let urlString: String = "http://www.pdf995.com/samples/pdf.pdf" let destination = DownloadRequest.suggestedDownloadDestination() Alamofire.download(urlString, to: destination).validate().responseData { response in debugPrint(response) guard let pdfPath = response.destinationURL?.path, let document = ReaderDocument(filePath: pdfPath, password: nil), let readerVC = ReaderViewController(readerDocument: document) else { return } readerVC.delegate = self readerVC.modalPresentationStyle = .fullScreen self.present(readerVC, animated: false, completion: nil) } } ....
ポイントは download を使うと
response.destinationURL
というプロパティがセットされることです。
これがコンテンツをダウンロードしたローカルのパスになっています。
upload
Comming soon