15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

30分で終わる「iOSアプリの通信入門」 with "GAE/Go"

Last updated at Posted at 2018-01-24

こんな人向け

  • 自作アプリ専用のWebAPIを作りたい
  • SwiftとGoで通信処理を実装してみたい
  • **Google App Engine**を使ってみたい

何をするの?

WebAPIを自作し、iOSからそのAPIを叩いてデータを取得する」を簡潔に行う。
GETをメインに書きましたが、POSTも書いてます。

#サーバーサイド(GAE/Go)

公式チュートリアル

まずはこれを終える。
チュートリアルの指示に従って、ハローワールドを出すだけです。
エラーに出くわしたら、多分PATHまわりだと思います。
vim ~/.bashrcでbashrcを開き、

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
export PATH=$PATH:$HOME/Downloads/google-cloud-sdk/bin

みたいに設定しておきましょう。
編集したら、source ~/.bashrcの実行を忘れずに。

チュートリアルを終えれば準備万端!
こっからが楽しい本番!!(30分かかんないはず!)

APIを自作

  1. 先ほどの、チュートリアルのhelloworldプロジェクトに移動する
  2. go get github.com/gin-gonic/ginginをダウンロードする 1
  3. hello.goに以下をコピペ
hello.go
package hello

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

type User struct {
		ID           string `json:"id"`
		Name         string `json:"name"`
		Introduction string `json:"introduction"`
}

// 初期化
func init() {
	http.Handle("/", GetEngine())
}

// APIのルーティング
func GetEngine() *gin.Engine {
	router := gin.Default()
	router.GET("/", func(c *gin.Context) {
		c.String(http.StatusOK, "yea! rootだね!")
	})
	router.GET("/api/users/:id", GetUser)
    router.POST("/api/users", SaveUser)
	return router
}

// Userをjsonで返す
func GetUser(c *gin.Context) {
    // パラメータを抽出
    id := c.Param("id")
    // Userを生成
    u := User{
		ID:           id,
		Name:         "jsonてすと君",
		Introduction: "ハロー iOSさん",
	}
    // jsonとして返す
    c.JSON(http.StatusOK, u)
}

// Userをデータストアに保存する
func SaveUser(c *gin.Context) {
	u := User{}
    // POSTで渡ってきたjsonを構造体に埋め込む
	c.BindJSON(&u)

	// >> 本来はここでデータストアへの保存処理などを行う。今回は省略。 <<

    // 今回はただ出力するだけ
	c.String(http.StatusOK, "SaveUser Success. %+v", u)
}

  1. dev_appserver.py app.yamlを実行し、ブラウザで「localhost:8080/」を見てみる。→「yea! rootだね!」を確認
    5)ブラウザに 「localhost:8080/api/users/好きな数字」を打ち込み、jsonが返ってくることを確認。
    以下は「localhost:8080/api/users/1」の例
スクリーンショット 2018-01-24 21.51.19.png 感動ですね!!

クライアント(iOS/Swift)

XcodeでSingle Viewのプロジェクトを作り、ViewController.swiftに以下をコピペ

ViewController.swift
import UIKit

// jsonの変換先となる構造体(初期値あり)
struct User : Codable {
    var id           : String = "0"
    var name         : String = "加賀鉄男"
    var introduction : String = "将棋が強い"
}

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // サーバーからUser情報を取得
        let user = getUser()
        // Userを出力してみる
        print("GETの結果: ", user)
        
        // サーバーにPOSTしてみる
        postUser()
    }
    
}

func getUser() -> User {
    // 情報の欲しいユーザーIDを指定
    let id = 1
    // URLを指定(今回はローカルサーバー)
    let url = URL(string: "http://localhost:8080/api/users/\(id)")!
    
    let decoder: JSONDecoder = JSONDecoder()
    
    do {
        // jsonを取得
        let data = try Data(contentsOf: url, options: [])
        // User構造体に値を埋め込む
        let user = try decoder.decode(User.self, from: data)
        return user
    } catch {
        print(error)
        return User()
    }
}

func postUser() {
    // URLを指定(今回はローカルサーバー)
    let url = URL(string: "http://localhost:8080/api/users")!
    
    // POSTリクエストを生成
    let request = NSMutableURLRequest(url: url)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    
    // POSTで渡したいパラメータを生成
    let params:[String:Any] = [
        "id": "789",
        "name": "postテストさん",
        "introduction": "Hello Go I'm Post",
        ]
    
    // それをjsonとして生成し、httpBodyに付加
    do {
        let json = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
        request.httpBody = json
    } catch {
        print("Error:\(error)")
        return
    }
    
    // POSTリクエストを発行
    let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error in
        if error != nil {
            print("Connection Error: ", error!)
            return
        }
        if let httpResponse = response as? HTTPURLResponse {
            let result = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!
            if httpResponse.statusCode != 200 {
                print(httpResponse)
            }
            print("POSTの結果:", result)
        }
    })
    task.resume()
}

さあ、シュミレータを起動してみましょう!
スクリーンショット 2018-01-29 17.53.30.png

最高ですね!!!

データストアについて

本記事はデータストア処理を省略しています。
実際の開発では、GETでデータストアのデータを取得したり、POSTでデータストアにデータを保存したりするはずです。
その際は、GAE/GoのDatastoreチートシート with "goonライブラリ"が参考になれば嬉しいです。

真にローカルから抜け出すには?

チュートリアルにもあるように、hello.goのあるディレクトリでgcloud app deploy app.yamlを実行するだけで、GCP上にデプロイされます。
あとは、swiftのURL指定部分を任意のURLに変えるだけです

なお、料金については小規模なら無料です。

おわりに

このような一連の流れをまとめた記事があまりなかったので、筆者なりに書いてみました。
30分以上かかってたらごめんなさい:bow_tone1:

  1. もちろん入れなくても書けます。最近はgorilla系の方が人気ぽい

15
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?