カテゴリー: iOS

[Swift]AlamofireでファイルのUploadをしてみる

はじめに

こんばんは、suzukiです。
今更感がありますが、Alamofireを使って通信周りについてまとめさせていただきます。
最近プロジェクトの修正や追加開発が多く、Carthageでライブラリの導入を行う際に少しつまづきました、、、
備忘も兼ねてそちらも記述致します。
それではよろしくお願い致します。

CarthageでAlamofireを導入する

個人的にCarthageとCocoaPodsだとCocoaPodsの方が使用頻度が高いです。
今回は最初でも書きましたがCarthageで導入します。
Carthageについてはこちらが参考になります。

Carthageは下記コマンドで簡単に導入可能です。

$ brew update
$ brew install carthage

CartFileの作成とライブラリのダウンロード

ターミナルから作成していきましょう。

// cd コマンドで対象のディレクトリに移動
$ cd /Users/suzuki/project/TestNetWork 
// vi Cartfileで github "Alamofire/Alamofire" を記述
$ vi Cartfile
// carthageの作成 --platform iOSと記述することでiOS用のライブラリのみ導入
$ carthage update --platform iOS

Xcodeの設定

carthage update コマンドが完了するとCarthageディレクトリが作成されます。
Carthageディレクトリ内に今回アプリに組み込むライブラリがございます。
それでは実際にXcodeに設定してみましょう。

手順は下記の3手順です。
・Build Phases > Link Binary With Librariesに追加
・Run Script に/usr/local/bin/carthage copy-frameworksと記述
・Input Filesの項目にライブラリのディレクトリを記述する
 ※dyld: Library not loaded: @rpath/Alamofire.framework/Versions/A/Alamofire Reason: image not found等の表示が出たらここを一度確認してみてください。以前にここのディレクトリに変な空白が入っていたせいでアーカイブだけ失敗したことがあったような、、、

手順完了後の画像です。

Alamofireとは

SwiftでHTTP通信を行う際に利用が多いライブラリです。
 ・リクエストの設定
 ・レスポンスの扱い
上記がURLSessionと比較して使いやすく下記のようにシンプルな形で記述ができます。
今回は疎通確認のためGitHubのリポジトリ検索のAPIを使っています。

        guard let url = URL(string: "https://api.github.com/search/repositories?q=examplepost") else{
            return
        }
        Alamofire.request(url).response { response in
            if let data = response.data ,
                let str = String(data: data, encoding: .utf8){
                print(str)
            }
        }

AlamofireのHTTPMethod

AlamofireのHTTPMethodは省略が可能です。
設定がされていない場合はGETが設定されます。
AlamofireではHTTPMethodがEnumで定義されており、requestを作成する際に送信することが可能です。
 ・GET リソースの取得
 ・POST 子リソースの作成、リソースへのデータ追加、その他処理
 ・PUT リソースの更新、リソースの作成
 ・PATCH リソースの部分更新
 ・DELETE リソースの削除
 ・TRACE プロキシ動作の確認
 ・CONNECT プロキシ動作のトンネル接続への変更
 ・OPTIONS リソースがサポートしているメソッドの取得
上記が設定可能です。

GETに関して
先ほど通信のように特に設定を行わずrequestを作成するとGETが設定されます。
明示的に指定することも可能で、requestの作成を行う際にURLと一緒にmethodの引数に.getを渡すだけです。

        //HTTPMethodの指定を行う
        Alamofire.request(url, method: .get).response { (response) in
        }

その他のHTTPMethodの指定方法
Getで説明したmethodに対象のHttpMethodを設定するだけで使用可能です。
またMethodの指定だけではなくrequestの作成を行う際に
・Parameterの指定 [String:Any]型
・Headerの指定   [String:String]型
上記の指定が可能です。

let request = Alamofire.request(url, method: .post, parameters:param , headers:headers)

※GitHubの検索APIがGETでしか使えないため、今回のURLではエラーが発生します。

ファイルのアップロード

以前の記事でAlamofireを使ってファイルをDLしてみるがあったので、今回の記事ではファイルのアップロードを行ってみます。
送信する際にはファイル以外の通信もまとめて行うことが考えられるためmultipart/form-dataで送信します。

        //URLの作成
        guard let url = URL(string: "https://api.github.com/search/repositories") else{
            return
        }
        let data = "test".data(using: .utf8)
        let data2 = "end".data(using: .utf8)
        //multipart/form-dataでデータを送信する方法
        Alamofire.upload(multipartFormData: { multipartFormData in
            //multipartFormDataオブジェクトに対してデータの追加を行う
            if let data = data,
                let data2 = data2{
                multipartFormData.append(data, withName: "data" , mimeType: "text/plain")
                multipartFormData.append(data2, withName: "data2", mimeType: "text/plain")
            }
            
            print(multipartFormData)
        }, to: url) { encodingResult in
            //encodingが成功するとこのハンドラが呼ばれる
            switch encodingResult {
            case.success(let upload, _ ,_):
                print(upload)
                //ベーシック認証が必要な場合は.authenticateで対応できます。
                upload
                    .authenticate(user: "user", password: "password")
                    .uploadProgress(closure: { (progress) in
                        //進捗率の取得
                        print("Upload Progress: \(progress.fractionCompleted)")
                    })
            case.failure(let error):
                print(error)
            }
        }

クロージャーが二つあるため、少しわかりずらいかもしれません。
multipartFormData:でアップロードを行うファイルを追加を行い
・上記のエンコードが終了したらencodingResultでエンコード結果を受け取り
・エンコード結果が成功だったらベーシック認証を行い進捗を確認
上記の流れでプログラムを書いております。

さいごに

最後までありがとうございます。
APIのテスト環境の構築を行いもう少しテストを行いたかったのですが、本日はこちらで完了とさせていただきます。
通信については何度も通信箇所を書くのではなく、基底クラスを作成し継承等で実装することが多いかと思います。
現在の案件では基底クラスをしばらく触っていませんが、Swift3→Swift4.1の際に作りを変更予定です。
参照されている箇所が多いので、慎重に変更を加えていきたいです。

おすすめ書籍

    

— NORMAL —
suzuki

シェア
執筆者:
suzuki
タグ: Swift

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

3週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

1か月 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前