Lập trình IOS: Triển khai MVVM cho prject swift (phần 1)

Công Nghệ
Lập trình IOS: Triển khai MVVM cho prject swift (phần 1)
Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh Hôm nay chúng ta sẽ làm 1 ứng dụng nho nhỏ, hiển thị danh sách các loại động vật, như hình ảnh: Danh sách các loại động vật Đầu tiên là tải source code của tôi tại đây: https://github.com/codetoanbug/MVVMSample Tôi hướng dẫn các bạn tải code về bằng git 1 xíu nhé. Là git command line nha các bạn. Rx-MVVM(1): Cấu trúc project – lib manager Rx-MVVM(2): Cấu trúc project – quản lý thư viện sử dụng trong dự án Đầu tiên là bạn mở terminal và gõ: git clone https://github.com/codetoanbug/MVVMSample.git Sau đó bạn cd vào thư mục code MVVMSample. Mẹo là gõ cd MV, nhấn nút tab trên bàn phím nó cũng ra lệnh như sau: cd MVVMSample Tiếp theo gõ để show toàn bộ branch: git branch -a Bạn sẽ thấy branch master, bai1… Mỗi branch sẽ chứa code của 1 bài. Ở đây ta chỉ quan tâm code bài 1 nên bạn cần chuyển qua code của bài 1 bằng cách gõ như sau: git checkout bai1 Như vậy là bạn đã có code của bài hôm nay rồi đấy. Đơn giản đúng không? Để triển khai mô hình MVVM, chúng ta cần nắm qua mô hình này xem nó hoạt động như thế nào. Hãy tiếp cận 1 cách đơn giản nhất nhé. Mặc định khi bạn tạo 1 project thì Xcode nó tự render các file theo tiêu chuẩn MVC của họ. M là Model, V là View, còn C là Controller. Tuy nhiên, ở đây chúng ta sẽ hay xử lý logic để lấy dữ liệu cho view và hiển thị view chung vào ViewController. Nếu tiếp cận cách đơn thuần như thế, thì cái table của bạn muốn có dữ liệu...

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

Hôm nay chúng ta sẽ làm 1 ứng dụng nho nhỏ, hiển thị danh sách các loại động vật, như hình ảnh:

Lập trình IOS: Triển khai MVVM cho prject swift(phần 1)Lập trình IOS: Triển khai MVVM cho prject swift(phần 1)
Danh sách các loại động vật

Đầu tiên là tải source code của tôi tại đây:

https://github.com/codetoanbug/MVVMSample

Tôi hướng dẫn các bạn tải code về bằng git 1 xíu nhé. Là git command line nha các bạn.

Đầu tiên là bạn mở terminal và gõ:

git clone https://github.com/codetoanbug/MVVMSample.git

Sau đó bạn cd vào thư mục code MVVMSample. Mẹo là gõ cd MV, nhấn nút tab trên bàn phím nó cũng ra lệnh như sau:

cd MVVMSample

Tiếp theo gõ để show toàn bộ branch:

git branch -a

Bạn sẽ thấy branch master, bai1… Mỗi branch sẽ chứa code của 1 bài. Ở đây ta chỉ quan tâm code bài 1 nên bạn cần chuyển qua code của bài 1 bằng cách gõ như sau:

git checkout bai1

Như vậy là bạn đã có code của bài hôm nay rồi đấy. Đơn giản đúng không?

Để triển khai mô hình MVVM, chúng ta cần nắm qua mô hình này xem nó hoạt động như thế nào.

Hãy tiếp cận 1 cách đơn giản nhất nhé. Mặc định khi bạn tạo 1 project thì Xcode nó tự render các file theo tiêu chuẩn MVC của họ. M là Model, V là View, còn C là Controller. Tuy nhiên, ở đây chúng ta sẽ hay xử lý logic để lấy dữ liệu cho view và hiển thị view chung vào ViewController.

Nếu tiếp cận cách đơn thuần như thế, thì cái table của bạn muốn có dữ liệu thì bạn phải tạo được data cho nó ở trong ViewController luôn. Rồi ngày qua ngày, cái table view này nó thêm nhiều tính năng mới. Ví dụ như khi chạm vào từng cell trên table thì phải kiểm tra xem cell đó là con gì, mở màn hình detail tương ứng. Hoặc trong cái view controller của bạn sếp yêu cầu phải lấy data từ trên server về thay vì tạo data set cứng trong nó. Bạn phải xử lý khi có data thì hiển thị như nào, khi không có data thì hiển thị như nào. Rồi một ngày đẹp trời nữa sếp bạn yêu cầu tao muốn hiển thị nhiều loại cell khác nhau, mỗi loại cell 1 loại data khác nhau… Code cứ dài càng dài, và càng khó chỉnh sửa sau này.

Vấn đề của MVC ở đây là xử lý hết logic trong View, thì code nhiều. Mà nhiều thì khó đọc, cáu, chửi thề, và cuối cùng là đấm sếp rồi nghỉ việc 

Có rất nhiều developer đã căng thẳng như thế, tóc bạc đi nhiều sau nhiều năm code MVC thuần. Rồi họ bắt đầu bực bội và muốn thay đổi điều gì đó để cho công việc đơn giản hơn. Họ nghĩ ngay “tại sao không đưa các xử lý logic về data sang 1 file khác, còn view chỉ đơn thuần là find data vào thôi?” Và rồi họ quyết định làm điều đó. Ra ban công làm khói, ngắm hàng xóm và tiếp tục đọc nhé.

Thành phần mới này họ đặt tên là View Model – nghĩa là nó giao thông qua lại giữa view và model. Cái tên rất sát nghĩa đúng không? 

Thôi nói lan man. Ở đây tôi sẽ trình bày cách triển khai từng phần 1 cho dễ hiểu nha.

Đầu tiên bạn tạo mới 1 project bằng Xcode, đặt tên nó là gì cũng được. Vào file Main.storyboard và kéo thả 1 cái tableview, 1 cái title như hình:

Lập trình IOS: Triển khai MVVM cho prject swift(phần 1)Lập trình IOS: Triển khai MVVM cho prject swift(phần 1)
Kéo thả title và tableview

Bước tiếp theo bạn tạo mới 1 file AnimalViewController kế thừa từ UIViewController, chọn nó quản lý cái file giao diện bạn vừa làm. Tiến hành kéo thả các liên kết từ view vào UIViewController này.

Giả sử tôi kéo thả tableview và được code như sau:

 @IBOutlet weak var tableView: UITableView!
 

Chưa xong, đã có tableview rồi thì phải tạo cell cho nó. Vậy bạn hãy tạo 1 cái lớp MyTableViewCell kế thừa từ UITableViewCell. Và lại kéo thả! Việc nhẹ lương cao nhỉ 

Hình nó như này:

Lập trình IOS: Triển khai MVVM cho prject swift(phần 1)Lập trình IOS: Triển khai MVVM cho prject swift(phần 1)
Bên trái là label, bên phải là image.

Nhớ auto layout cho nó nhé. Không biết auto layout thì tôi đấm luôn. Chú ý cái khoanh đỏ tôi lười nên hay lấy cái identifier này trùng với tên class cell. Để cho dễ nhớ và copy cho tiện. Mục đích của nó là sau tái sử dụng.

Code như sau:

@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var animalImageView: UIImageView!

Rồi, và bây giờ để code clean thì bạn tạo cho tôi 1 cái hàm ở AnimalViewController có nội dung như sau:

/// Init table view
    private func initTableView() {
        tableView.register(UINib(nibName: "MyTableViewCell", bundle: nil), forCellReuseIdentifier: "MyTableViewCell")
        tableView.delegate = self
        tableView.dataSource = self
    }

Rất basic, ở đây nó có ý nghĩa là table đăng ký cell để tí dùng. Kế thừa các hàm delegate và datasource. Những công việc mà newbie nào cũng cần biết nhỉ. Sau đó ném cái hàm vào trong hàm viewDidLoad nhé. Vẫn chưa thấy view model đâu. Bây giờ là chuyên mục chính này.

Đầu tiên là bạn phải tạo cái model để chứa dữ liệu animal của tôi, bao gồm 1 cái tên và 1 cái hình. Tôi tạo code bằng 1 cái struct như sau:


struct Animal {
    let name: String
    let image: String
}

Struct vì nó là giá trị, không có dùng class à nha. Class để giành cho View model.

Rồi, bây giờ ta sẽ nghĩ ngay đến việc là cần 1 cái view model để xử lý các công việc sau:

  1. Tạo datasource cho tableview, chắc chắn phải ném nó vào hàm init của view model
  2. Tạo các hàm trả về cho delegate và datasource của tableview.

Cụ thể bạn tạo file AnimalViewModel và code như sau:

class AnimalViewModel {
    private var animals: [Animal]

    init() {
        animals = []

        // Create data source
        animals.append(Animal(name: "Alligator", image: "Alligator"))
        animals.append(Animal(name: "Anteater", image: "Anteater"))
        animals.append(Animal(name: "Armadillo", image: "Armadillo"))
    }

    func numberOfRowsInSection(section: Int) -> Int {
        return animals.count
    }

    func cellForRowAt(indexPath: IndexPath) -> Animal {
        return animals[indexPath.row]
    }
}

Code thì dài dòng, nhưng để đơn giản thì tôi tạo data ở local, bài sau tôi sẽ hướng dẫn lấy data từ đâu đó trên mạng nha. Các công việc như sau:

  1. Hàm init sẽ tạo datasource cho tableview
  2. Hàm numberOfRowsInSection tôi đặt giống hàm của table datasource, mục đích trả số row trên 1 section
  3. Hàm cellForRowAt cũng vậy, mục đích là để bind data cho cell nhá

Và quay lại file AnimalViewController, bạn viết thêm cho tôi dòng này:

var animalViewModel: AnimalViewModel!

Khi tạo xong view model rồi, thì bạn phải ném nó vào view controller. Sau đó, lại để cho code clean, bạn tạo 1 hàm xử lý view model cho nó. Code như sau:

private func bindViewModel() {
        animalViewModel = AnimalViewModel()
    }

Ở trên chỉ độc 1 dòng code là tạo view model. Tuy nhiên các dự án thực tế nó có nhiều setting khác, như các closure của view model. Nhưng khoan quan tâm, tôi sẽ trình bày ở các bài sau nhé.

Và bây giờ là cần xử lý cho table view, bạn viết đoạn code sau:

extension AnimalViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return animalViewModel.numberOfRowsInSection(section: section)
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableViewCell") as! MyTableViewCell
        cell.bindData(animal: animalViewModel.cellForRowAt(indexPath: indexPath))
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 80
    }
}

Đoạn code trên khá sạch sẽ, view controller sẽ lấy data thông qua view model, và bạn méo cần quan tâm trong đó có gì, chỉ cần view model mày trả data cho tao là được. Do vậy, view controller đã không phải xử lý các logic xử lý model nữa. Khỏe hẳn ra, cứ như là lấy vợ về có người nấu cơm cho ăn ấy.

Tuy nhiên, ở ví dụ này tôi có 1 loạt bức ảnh màu trắng, bạn có thể xem trong mục Assets như hình:

Lập trình IOS: Triển khai MVVM cho prject swift(phần 1)Lập trình IOS: Triển khai MVVM cho prject swift(phần 1)
Ảnh tôi chôm trên mạng

Do vậy để cho ứng dụng màu mè thì tôi viết thêm các extension tạo màu từ ảnh trắng này. Các bạn vào file Extensions để xem.

Trong UIImageView+Extensions tôi có code:

extension UIImageView {
  func setImageColor(color: UIColor) {
    let templateImage = self.image?.withRenderingMode(.alwaysTemplate)
    self.image = templateImage
    self.tintColor = color
  }
}

Đoạn này là tạo màu cho ảnh.

Trong UIColor+Extensions, là tạo màu random cho ảnh nó khác màu nhau nhá:

extension UIColor {
    static func random() -> UIColor {
        return UIColor(
           red:   .random(),
           green: .random(),
           blue:  .random(),
           alpha: 1.0
        )
    }
}

Ok, vậy là cơ bản đã xong rồi đó. Trong bài tiếp theo tôi sẽ làm thêm về phần request lên server nhé.

Bài viết gốc được đăng tải tại codetoanbug.com

Có thể bạn quan tâm:

Xem thêm Việc làm ios hấp dẫn trên Station D

                                                 Tuyển dụng swift lương cao cho bạn

Bài viết liên quan

Bộ cài đặt Laravel Installer đã hỗ trợ tích hợp Jetstream

Bộ cài đặt Laravel Installer đã hỗ trợ tích hợp Jetstream

Bài viết được sự cho phép của tác giả Chung Nguyễn Hôm nay, nhóm Laravel đã phát hành một phiên bản chính mới của “ laravel/installer ” bao gồm hỗ trợ khởi động nhanh các dự án Jetstream. Với phiên bản mới này khi bạn chạy laravel new project-name , bạn sẽ nhận được các tùy chọn Jetstream. Ví dụ: API Authentication trong Laravel-Vue SPA sử dụng Jwt-auth Cách sử dụng Laravel với Socket.IO laravel new foo --jet --dev Sau đó, nó sẽ hỏi bạn thích stack Jetstream nào hơn: Which Jetstream stack do you prefer? [0] Livewire [1] inertia > livewire Will your application use teams? (yes/no) [no]: ... Nếu bạn đã cài bộ Laravel Installer, để nâng cấp lên phiên bản mới bạn chạy lệnh: composer global update Một số trường hợp cập nhật bị thất bại, bạn hãy thử, gỡ đi và cài đặt lại nha composer global remove laravel/installer composer global require laravel/installer Bài viết gốc được đăng tải tại chungnguyen.xyz Có thể bạn quan tâm: Cài đặt Laravel Làm thế nào để chạy Sql Server Installation Center sau khi đã cài đặt xong Sql Server? Quản lý các Laravel route gọn hơn và dễ dàng hơn Xem thêm Tuyển dụng lập trình Laravel hấp dẫn trên Station D

By stationd
Principle thiết kế của các sản phẩm nổi tiếng

Principle thiết kế của các sản phẩm nổi tiếng

Tác giả: Lưu Bình An Phù hợp cho các bạn thiết kế nào ko muốn làm code dạo, design dạo nữa, bạn muốn cái gì đó cao hơn ở tầng khái niệm Nếu lập trình chúng ta có các nguyên tắc chung khi viết code như KISS , DRY , thì trong thiết kế cũng có những nguyên tắc chính khi làm việc. Những nguyên tắc này sẽ là kim chỉ nam, nếu có tranh cãi giữa các member trong team, thì cứ đè nguyên tắc này ra mà giải quyết (nghe hơi có mùi cứng nhắc, mình thì thích tùy cơ ứng biến hơn) Tìm các vị trí tuyển dụng designer lương cao cho bạn Nguyên tắc thiết kế của GOV.UK Đây là danh sách của trang GOV.UK Bắt đầu với thứ user cần Làm ít hơn Thiết kế với dữ liệu Làm mọi thứ thật dễ dàng Lặp. Rồi lặp lại lần nữa Dành cho tất cả mọi người Hiểu ngữ cảnh hiện tại Làm dịch vụ digital, không phải làm website Nhất quán, nhưng không hòa tan (phải có chất riêng với thằng khác) Cởi mở, mọi thứ tốt hơn Bao trừu tượng luôn các bạn, trang Gov.uk này cũng có câu tổng quát rất hay Thiết kế tốt là thiết kế có thể sử dụng. Phục vụ cho nhiều đối tượng sử dụng, dễ đọc nhất nhất có thể. Nếu phải từ bỏ đẹp tinh tế – thì cứ bỏ luôn . Chúng ta tạo sản phẩm cho nhu cầu sử dụng, không phải cho người hâm mộ . Chúng ta thiết kế để cả nước sử dụng, không phải những người đã từng sử dụng web. Những người cần dịch vụ của chúng ta nhất là những người đang cảm thấy khó sử dụng dịch...

By stationd
Hiểu về trình duyệt – How browsers work

Hiểu về trình duyệt – How browsers work

Bài viết được sự cho phép của vntesters.com Khi nhìn từ bên ngoài, trình duyệt web giống như một ứng dụng hiển thị những thông tin và tài nguyên từ server lên màn hình người sử dụng, nhưng để làm được công việc hiển thị đó đòi hỏi trình duyệt phải xử lý rất nhiều thông tin và nhiều tầng phía bên dưới. Việc chúng ta (Developers, Testers) tìm hiểu càng sâu tầng bên dưới để nắm được nguyên tắc hoạt động và xử lý của trình duyệt sẽ rất hữu ích trong công việc viết code, sử dụng các tài nguyên cũng như kiểm thử ứng dụng của mình. Cách để npm packages chạy trong browser Câu hỏi phỏng vấn mẹo về React: Component hay element được render trong browser? Khi hiểu được cách thức hoạt động của trình duyệt chúng ta có thể trả lời được rất nhiều câu hỏi như: Tại sao cùng một trang web lại hiển thị khác nhau trên hai trình duyệt? Tại sao chức năng này đang chạy tốt trên trình duyệt Firefox nhưng qua trình duyệt khác lại bị lỗi? Làm sao để trang web hiển thị nội dung nhanh và tối ưu hơn một chút?… Hy vọng sau bài này sẽ giúp các bạn có một cái nhìn rõ hơn cũng như giúp ích được trong công việc hiện tại. 1. Cấu trúc của một trình duyệt Trước tiên chúng ta đi qua cấu trúc, thành phần chung và cơ bản nhất của một trình duyệt web hiện đại, nó sẽ gồm các thành phần (tầng) như sau: Thành phần nằm phía trên là những thành phần gần với tương tác của người dùng, càng phía dưới thì càng sâu và nặng về xử lý dữ liệu hơn tương tác. Nhiệm...

By stationd
Thị trường EdTech Vietnam- Nhiều tiềm năng nhưng còn bị bỏ ngỏ tại Việt Nam

Thị trường EdTech Vietnam- Nhiều tiềm năng nhưng còn bị bỏ ngỏ tại Việt Nam

Lĩnh vực EdTech (ứng dụng công nghệ vào các sản phẩm giáo dục) trên toàn cầu hiện nay đã tương đối phong phú với nhiều tên tuổi lớn phân phối đều trên các hạng mục như Broad Online Learning Platforms (nền tảng cung cấp khóa học online đại chúng – tiêu biểu như Coursera, Udemy, KhanAcademy,…) Learning Management Systems (hệ thống quản lý lớp học – tiêu biểu như Schoology, Edmodo, ClassDojo,…) Next-Gen Study Tools (công cụ hỗ trợ học tập – tiểu biểu như Kahoot!, Lumosity, Curriculet,…) Tech Learning (đào tạo công nghệ – tiêu biểu như Udacity, Codecademy, PluralSight,…), Enterprise Learning (đào tạo trong doanh nghiệp – tiêu biểu như Edcast, ExecOnline, Grovo,..),… Hiện nay thị trường EdTech tại Việt Nam đã đón nhận khoảng đầu tư khoảng 55 triệu đô cho lĩnh vực này nhiều đơn vị nước ngoài đang quan tâm mạnh đến thị trường này ngày càng nhiều hơn. Là một trong những xu hướng phát triển tốt, và có doanh nghiệp đã hoạt động khá lâu trong ngành nêu tại infographic như Topica, nhưng EdTech vẫn chỉ đang trong giai đoạn sơ khai tại Việt Nam. Tại Việt Nam, hệ sinh thái EdTech trong nước vẫn còn rất non trẻ và thiếu vắng nhiều tên tuổi trong các hạng mục như Enterprise Learning (mới chỉ có MANA), School Administration (hệ thống quản lý trường học) hay Search (tìm kiếm, so sánh trường và khóa học),… Với chỉ dưới 5% số dân công sở có sử dụng một trong các dịch vụ giáo dục online, EdTech cho thấy vẫn còn một thị trường rộng lớn đang chờ được khai phá. *** Vừa qua Station D đã công bố Báo cáo Vietnam IT Landscape 2019 đem đến cái nhìn toàn cảnh về các ứng dụng công...

By stationd