rails

Swift: Webアプリ(API)へPOSTしてみる!


どうも、ささおです!

今回はAPIKitを使用してデータをwebに送ります(POSTします)!

前回はGETメソッドでwebアプリ側のデータを引っ張ってきています。こちらの続きなので一読いただけると楽だと思います!

RailsのWebアプリとSwiftのiOSアプリを連携させてみた

 

新しいリクエスト作成

前回はFetchNoteRequestというNoteの一覧(indexアクション)を取得してくるリクエストを作成しました。

今回はNoteをWebに送って、作成する(createアクション)リクエストを作成します。

名付けて「CreateNoteRequest」!!

import Foundation
import Himotoki
import APIKit

protocol WebRequest: Request {
    
}

extension WebRequest {
    var baseURL: URL {
        return URL(string: "http://前回の最後を参照してください。")!
//        return URL(string: "http://localhost:3000")!
    }
}

extension WebRequest where Response: Decodable {
    
}

struct FetchNoteRequest: WebRequest {
    
    var path: String {
        return "/notes"
    }
    typealias Response = [Note]
    
    var method: HTTPMethod {
        return .get
    }
    
    func response(from object: Any, urlResponse: HTTPURLResponse) throws -> FetchNoteRequest.Response {
        return try decodeArray(object)
    }
}

// ここから新しい!
struct CreateNoteRequest: WebRequest {
    
    var path: String {
        return "/notes"
    }
    typealias Response = Note
    
    var method: HTTPMethod {
        return .post
    }
    
    var title: String?
    var content: String?
    
    
    var bodyParameters: BodyParameters? {
        let titlePart = MultipartFormDataBodyParameters.Part(data: (title?.data(using: .utf8))!, name: "note[title]")
        let contentPart = MultipartFormDataBodyParameters.Part(data: (content?.data(using: .utf8))!, name: "note[content]")
        return MultipartFormDataBodyParameters(parts: [titlePart, contentPart])
    }
    
    func response(from object: Any, urlResponse: HTTPURLResponse) throws -> CreateNoteRequest.Response {
        return try decodeValue(object)
    }
}

Noteはtitleプロパティとcontentプロパティを持っているので、その二つを送れるようにします。

method

こちらは説明不要かと思いますが、

.postにします。

bodyPrameters

データを送る場合(POSTの場合)、bodyPrametersに送るデータを格納する必要があります。

特に難しいのはこちらですよね・・・

let titlePart = MultipartFormDataBodyParameters.Part(data: (title?.data(using: .utf8))!, name: “note[title]”)

MultipartFormDataBodyParameters.PartによってPOSTで送れるデータに変換しています。

data: title?.data(using: .utf8)でSwiftのstring型のデータをutf8にして、
name: “note[title]”で名前をつけています。Railsでは、基本的にparams[:???]でデータを受け取りますから、名前をつけないとRailsで送られてきたデータを受け取ることができないので注意が必要です。

さらに注意が必要なのが、今回のRailsはただのparamsではなくてStrongParameterなので、

“title”ではダメです。“note[title]”にしましょう。

そして作成したデータを配列にしてMultipartFormDataBodyParameters(parts:)に格納します。

 

Form画面の作成

ここは簡単です。

まずはファイルを作成します。

CreateViewController.swiftを作成してください。

import UIKit

class CreateViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

 

Storyboardで新しいUIViewControllerを作成して、UITextFieldを2枚、UIButtonを1枚配置してください。

(前回から続きでご覧いただいている方は、新しいUIViewControllerに繋ぐ導線を繋いであげましょう。)

このように配置できたらIBOutlet接続、IBAction接続をします。

import UIKit

class CreateViewController: UIViewController {

    @IBOutlet weak var titleTextField: UITextField!
    @IBOutlet weak var contentTextField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    @IBAction func actionCreate(_ sender: Any) {
    }
}

 

ここまで完了したら、
actionCreateの中にリクエストを投げる処理を記述します。

前回とほぼ一緒です。

import UIKit
import APIKit

class CreateViewController: UIViewController {

    @IBOutlet weak var titleTextField: UITextField!
    @IBOutlet weak var contentTextField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    @IBAction func actionCreate(_ sender: Any) {
        Session.send(CreateNoteRequest(title: titleTextField.text, content: contentTextField.text)) { result in
            switch result {
            case .success( _):
                print("作成完了!")
            case .failure( _):
                print("失敗しました!")
            }
        }
    }
}

 

ほぼ前回と変わりませんが、リクエストの引数に値が入力させているところは違いますね。

 

実行

それでは実行してみましょう!(railsの方もサーバーを立てるのを忘れないでください!)

UITextFieldに入力して、createボタンをクリックしてみてください。

iOSにはなんの変化もありませんが、webの方を確認してみると変化があると思います。


ABOUT ME
ささお
3年目iOSエンジニア。 スタートアップで働いておりやす。 プログラミングスクールとエンジニアのキャリアを考えたい。 作ったアプリ - https://apps.apple.com/us/app/loverprofile/id1463563845?l=ja&ls=1