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 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é :smiley:

    Tham khảo: Qiita

    Nguồn: Viblo


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới LaptrinhX, vui lòng đợi một lúc để chúng tôi thử kết nối lại.