12/08/2018, 17:09

Chỉ 30 phút nhập môn truyền tin Client/Server trong iOS app với "GAE/Go"

Mục tiêu hướng đến những người Muốn tự tạo WebAPI cho App Muốn thực thi xử lý truyền tin bằng Swift (và Go) Muốn dùng thử Google App Endgine Sẽ làm gì? Thực hiện đơn giản việc tạo WebAPI, từ iOS thông qua API để nhận dữ liệu về. Chủ yếu là giao thức GET tuy nhiên cũng có một chút giao ...

Mục tiêu hướng đến những người

  • Muốn tự tạo WebAPI cho App
  • Muốn thực thi xử lý truyền tin bằng Swift (và Go)
  • Muốn dùng thử Google App Endgine

Sẽ làm gì?

Thực hiện đơn giản việc tạo WebAPI, từ iOS thông qua API để nhận dữ liệu về. Chủ yếu là giao thức GET tuy nhiên cũng có một chút giao thức POST

Server side (GAE/Go)

Hướng dẫn chính thức

Đầu tiên chúng thay hãy tham khảo hướng dẫn chính thức này theo chỉ dẫn đó ta viết một đoạn code HelloWorld. Nếu như có lỗi phát sinh thì có lẽ là lỗi do ta chưa thiết lập môi trường PATH cho Go chúng ta mở file bashrc bằng vim : vim ~/.bashrc

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

và Setting như trên, sau khi edit xong các bạn đừng quên thực hiện source ~/.bashrc và như vậy là xong bước chuẩn bị môi trường!!!1

Tự làm API

  1. Di chuyển về project HelloWorld đã download từ trang hướng dẫn ở bên trên
  2. Download Lib gin về bằng câu lệnh go get github.com/gin-goinc/gin
  3. Copy file hello.go như bên dưới
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. Thực hiện lệnh dev_appserver.py app.yaml , sau đó ta xem trên Browser "localhost:8080" để thấy được trang chủ (root)
  2. Để xác nhận được json trả về ở địa chỉ "localhost:8080/api/users/id" với id là một chữ số nào đó. VD ở đây ta cho id = 1 thì ta sẽ có msg trả về là

Client (iOS/Swift)

Sử dụng Xcode tạo project Single View, copy code sau vào file 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()
}

Và ta thực thi trên Simulator thôi nào

Ngon!!

Về Datastore

Ở bài viết này phần xử lý Datastore đã được giản lược Thực tế khi phát triển ta dùng GET để lấy dữ liệu từ Datastore, và dùng POST để lưu data trên Datastore.

Deploy từ local lên Cloud

Ở trong hướng dẫn cũng đã có , cùng thư mục với file hello.go ta thực hiện lệnh gcloud app deploy app.yaml thì app sẽ được deploy trên GCP. Sau đó chúng ta sẽ chỉ định URL ở trong Swift. Và nếu chỉ sử dụng đơn giản thì sẽ là miễn phí trên Cloud

Kết luận

Trên đây là những tóm tắt của mình để thực hiện một ví dụ đơn giản về truyền tin từ client lên server thông qua "GAE/Go", nếu có dài hơn 30 thì cho mình xin lỗi nhé             </div>
            
            <div class=

0