Swift API接続注意点1 忘備録 読まないこと!

大切なものは3つ

1-リクエスト

UserRequestと 汎用的に利用できる APIRequestクラスを作成する

2-レスポンス

3-エラー処理

リクエストは表示するだけなので、値を持っていれば良い リクエストでどんなパラメータが必要か? 一覧でよければ、パラメーターは必要ない。 リクエストクラスには、どんな情報が返却されるのかわからないので、リクエストに必要な情報だけ記載すれば良い。 例 url セッション

レスポンスは、保存処理などが走るので、テーブルに応じたモデルを用意しておかなくてはいけない。 WEBのDBもモデルがUser なら struct Userなど同じ名前が望ましい。そこに記載する カラムに当てはまるようなプロパティを書いておく

リクエスト と レスポンスの構造体が必要になる

リクエストを投げる

URLRequestは httpbody というプロパティを持っている

developer.apple.com

HTTP POST要求など、要求のメッセージ本文として送信されたデータ。だそうです。

そもそもbodyとは ?

HTTPリクエストは3つの部分からなっている

1.HTTPリクエストライン(リクエストライン)

2.HTTPリクエストヘッダ(ヘッダ)

改行、空行が入る

3.HTTPリクエストメッセージボディ(メッセージボディ)

POSTのとき、受け渡すパラメーターの内容が書いてある。 GETのときは何も書いていない。 今回はログインだからBodyに書いてあるはず。

encode とは Swiftの型-> json

decodeとは json-> Swiftの型 へ変換するもの

それぞれData型で返却される

下記参照

developer.apple.com ちなみに encodeはこちら

developer.apple.com

ここのソースはわかりやすい

//まず構造体を定義 これがbody部のもととなる
struct GroceryProduct: Codable {
    var name: String
    var points: Int
    var description: String?
}

//ここで上記のインスタンスを生成
let pear = GroceryProduct(name: "Pear", points: 250, description: "A ripe pear.")

let encoder = JSONEncoder()
//これはただ、出力を読みやすくするだけ、必要ない
encoder.outputFormatting = .prettyPrinted

//encodeします。このときエラー処理が必要 try
let data = try encoder.encode(pear)
print(String(data: data, encoding: .utf8)!)

//こんな感じで、body部が出来ている。
/* Prints:
 {
   "name" : "Pear",
   "points" : 250,
   "description" : "A ripe pear."
 }
*/

jsondecodeのインスタンスを作らないと何も始まらない。

urlRequest.httpBody = try! encoder.encode(httpBody)

とすると cannot invoke ~ 呼び出せないよとエラー

stackoverflow.com

ここを見ると、ジェネリクスで作れと書いてある。よって変更する。 プロトコルのジェネリクスってどうやってかくの?

stackoverflow.com

associatedtype  を使いなさいと。

protocol GitHubRequest{
    //プロトコルでのジェネリクス
    associatedtype Response: Decodable
//ここでジェネリクスを指定
    associatedtype HTTPBody: Encodable
    //直接アクセスできないようにGetterがある
    var baseURL: URL {get}
    var path: String {get}
    var method: HTTPMethod {get}
    //URLQueryItem   URLのクエリ部分からの単一の名前と値のペア。
    var queryItems: [URLQueryItem] {get}
    
//HTTPBody型に変更
    var httpBody :HTTPBody {get}
    
}

case .post:
            let encoder = JSONEncoder()
//associatedtype HTTPBody: Encodable これによりここのエラーが消える
            urlRequest.httpBody = try! encoder.encode(httpBody)