[Swift]Alamofire – Design Pattern

Mở Đầu

Nói về alamofire chắc hẳn ai cũng biết đây là thư viện rất nổi tiếng về Networking trên swift, nhưng để design và sử dụng nó một cách hiệu quả thì lại là một câu chuyện khác. Hôm nay mình sẽ chia sẽ về cách mình sử dụng Alamofire hi vọng sẽ giúp ích cho các bạn. Lần đầu mình viết bài sẽ ko thể tránh khỏi những thiếu sót, rất mong nhận được sự góp ý từ mọi người.

Cách Dùng

Đa phần những mobile app ngày nay đều sử dụng rest để trao đổi bản tin và sử dụng JSON. Mình sẽ dựng một server demo và app client để mô tả một cách trực quan nhất có thể.

RESTFul

REST định nghĩa các quy tắc kiến trúc để bạn thiết kế Web services chú trọng vào tài nguyên hệ thống, bao gồm các trạng thái tài nguyên được định dạng như thế nào và được chuyển tải qua HTTP thông qua số lượng lớn người dùng và được viết bởi những ngôn ngữ khác nhau. Web service REST sẽ tuân thủ theo bốn nguyên tắc thiết kế cơ bản sau:

  • Sử dụng các phương thức HTTP một cách rõ ràng
    • Create (POST)
    • Read (GET)
    • Update (PUT)
    • Delete (DELETE)
  • Phi trạng thái
  • Hiển thị cấu trúc thư mục như URls
  • Chuyển đổi JavaScript Object Notation (JSON) và XML hoặc cả hai.

Web Services API

Là nơi để client và server có thể trao đổi với nhau. Giả sử bạn có ứng dụng tên là notes với api như sau:

Client

Ở client để sử dụng được app thì cần phải tạo tài khoản và đăng nhập sau đó mới được phép sử dụng. Client sẽ có 2 View là LoginViewController và NoteViewController, ứng dụng của bạn được phát triển bởi 2 dev và mỗi người sẽ làm 1 screen. Như vậy là cả 2 dev sẽ cùng tham gia viết tầng networking, sẽ rất dễ bị conflict code. Ta sẽ giải quyết vần đề này ở phần sau. Tiến hành dựng project iOS và cài đặt Alamofire. Mình khuyến cáo nên cài qua pod để hạn chế tối đa việc cấu hình lib = tay và tránh những lỗi stupid =)). Mở terminal trỏ đến project và dùng lệnh sau

pod init
nano Podfile
pod 'Alamofire', '~> 3.5'
pod install

Sau khi cài xong:

Việc cần làm lúc này là viết route. Thường thì ta sẽ viết như sau:

Alamofire.request("http://localhost:3000/api/users").responseJSON { response in ... }
Alamofire.request("http://localhost:3000/api/getUser").responseJSON { response in ... }

hoặc sẽ đóng gọi lại những phương thức get, post, put, delete sau đó sẽ viết những request dựa trên những phương thức trên:

func apiUserInfo(userId: Int, success: RequestSucceed, failure: RequestFailed) {
    let url = RequestURL.User.url()
    let params = [JSONKey.UserId: String(userId)]
    doGetRequestWithURLAndHeader(url, parameters: params, success: { (response) in
        success(jsonResponse: response)
        }) { (error, data) in
            failure(error: error, data: data)
    }
}

Cách viết thứ nhất rất xấu còn ở cách thứ hai thì bị dư thừa khá nhiều và bạn sẽ ko thể có đc cái nhìn tổng quan những action của user là gì nếu project của bạn phình to ra. Ta sẽ giải quyết vấn đề này. Nếu để ý một chút các bạn sẽ thấy Alamofire sử dụng URLRequestConvertible để thực hiện request. Bây giờ chỉ cần implement protocol này và bổ xung thêm những action của route user ở đây:

Cách dùng:

let email = "[email protected]"
let password = "123456"

Alamofire.request(User.LoginUser(parameters: ["email": email, "password": password]))
    .responseJSON { (reponse) in
        switch reponse.result {
        case .Success(let value):
            // Handler Login Success
            print(value)
        case .Failure(let error):
            // Handler Login Failure
            print(error)
        }
}

Khá clear phải ko. Với cách viết này thì dev thứ 2 cũng có thể làm song song phần neworking với bạn mà ko lo bị conflict hay phải đợi bạn làm xong rùi mới làm tiếp đc. Mình khuyến cáo các bạn khi viết mỗi route ở client sẽ ứng với 1 route trên server và các route đó sẽ ứng với 1 object hoặc resource cụ thể. Hi vọng bài viết sẽ giúp ich cho bạn. Thanks 4 reading 😃


All Rights Reserved