Skip to main content

Posts

Showing posts from May, 2020

iOS > Android: View Life Cycle

Here’s a quick comparison of the most common lifecycle methods on the two platforms, and where they fit into the life cycle of the view.

MVVM và VIPER: Con đường trở thành Senior

Trong bài viết trước chúng ta đã tìm hiểu về MVC và MVP để ứng dụng cho một iOS App đơn giản. Bài này chúng ta sẽ tiếp tục ứng dụng 2 mô hình MVVM và VIPER . Nhắc lại là ứng dụng của chúng ta cụ thể khi chạy sẽ như sau: Source code đầy đủ cho tất cả mô hình MVC, MVP, MVVM và VIPER các bạn có thể download tại đây . MVVM MVVM có thể nói là mô hình kiến trúc được rất nhiều các cư dân trong cộng đồng ưa chuộng. Điểm tinh hoa của kiến trúc này là ở ViewModel , mặc dù rất giống với Presenter trong MVP tuy nhiên có 2 điều làm nên tên tuổi của kiến trúc này đó là: ViewModel không hề biết gì về View , một ViewModel có thể được sử dụng cho nhiều View (one-to-many). ViewModel sử dụng Observer design pattern để liên lạc với View (thường được gọi là binding data , có thể là 1 chiều hoặc 2 chiều tùy nhu cầu ứng dụng). Chính đặc điểm này MVVM thường được phối hợp với các thư viện hỗ trợ Reactive Programming hay Event/Data Stream , đây là triết lý lập trình hiện đại và hiệu

MVC, MVP, MVVM, VIPER nên xài cái nào (P1)

Xin chào các công dân mới toanh vừa gia nhập thế giới kiến trúc ứng dụng. Tính bài trước, các bạn đã là bước chân vào thế giới này rồi. Hôm nay với vai trò là một công dân "già", mình sẽ giới thiệu các bạn đến một số "địa điểm" nổi tiếng nhất của thế giới này: MVC : V iew - C ontroller - M odel MVP : V iew - P resenter - M odel MVVM : V iew - V iew M odel - M odel VIPER : V iew - P resenter (with R outer/Wireframe) - I nteractor - E ntity (Model) Trong các mô hình trên mình cố tình ghi các thành phần theo đúng với mối liên hệ của chúng để các bạn dễ hình dung. Nhưng các bạn có thấy điểm chung nào giữa chúng không ? Điểm chung đó chính là View và Model luôn ở đầu và cuối và có xu hướng rời xa nhau. Mối liên kết giữa View - Model trong kiến trúc ứng dụng Ta đang nói về kiến trúc ứng dụng, nghĩa là thiết kế kiến trúc cho ứng dụng. Ứng dụng thì sẽ luôn có giao diện người dùng ( graphic user interface - GUI ) và phần code cũng như dữ liệu ( data - mod

Thread safe singleton’s in Swift

What are singletons? — Singleton is design patterns which says that there should be only one instance of the class for the lifetime of the application. One the best example of Singleton is AppDelegate . How to write a singleton class ? class DefaultDict{ private var dict:[String:Any] = [:] public static let sharedManager = DefaultDict() private init(){ } public func set(value:Any,key:String){ dict[key] = value } public func object(key:String) -> Any?{ dict[key] } public func reset(){ dict.removeAll() } }   Testing singleton class under concurrent circumstances. We are going to write an example where we will set values in dict from various threads and even try to access some with different threads. When we do this we will encounter a crash. If you look closely it will be because of race condition and the crash will be on line set(value:Any,key:String) . class ViewController: UIViewController { ov

Loading images asynchronously

There are a few details that need to be paid attention to when loading images from URLs in your Swift code: loading and decoding the image on a background thread updating the UIImageView on the main thread not starting too many parallel downloads cancelling downloads when images are not needed anymore I recommend to use one of the two popular libraries that do the trick in just a few lines of code: SDWebImage or Kingfisher . Both are easy to get via CocoaPods and are quite similar in API and supported features. SDWebImage After adding the SDWebImage pod to the project: pod 'SDWebImage' Given an image view and a URL to load the image from, loading the image with an activity indicator is as simple as: import UIKit import SDWebImage class ExampleViewController : UIViewController { @IBOutlet weak var imageView : UIImageView ! // ... func loadImage () { let imageURL = URL ( string : "https://uploa

Dùng thư viện RXSWIFT để cải tiến hiệu suất cho dự án iOS của bạn — phần 5

Trong phần này mình sẽ giới thiệu về RXCocoa vs Binding RXCocoa : sử dụng RX đã được viết extension sẵn để tương tác với các UI Controls.Mình sẽ giới thiệu 1 số control hay dùng UIButton : on click btn.rx. controlEvent (UIControlEvents.touchUpInside).subscribe { (event) in print("Btn Clicked") } btn.rx. tap .bind { (event) in print("Btn Clicked") } UITextfield : text change tf.rx. text .asObservable().subscribe(onNext: { (text) in guard let textGet = text else { return } print("Tf change : \(textGet)") }) UIScrollView : bắt event contentOffset change , didScroll. scrollView.rx. contentOffset .subscribe(onNext: { (point) in print("Scroll offset : \(point)") }) scrollView.rx. didScroll .subscribe(onNext: { _ in print("Did scroll : \(self.scrollView.contentOffset)") }) UISlider : value change slider.rx. value .asObservable().subscribe(onNext: { (value) in

Dùng thư viện RXSWIFT để cải tiến hiệu suất cho dự án iOS của bạn — phần 4

Phần tiếp theo chúng ta sẽ tìm hiểu các operator còn lại 4.Create Operator Create : khởi tao 1 obervable, trả về các observer dùng onNext,onComplete,OnError. func createGoogleDataObservable() -> Observable<String> { return Observable<String>. create ({ (observer) -> Disposable in let session = URLSession.shared let task = session.dataTask(with: URL(string:" https://www.simple.com ")!) { (data, response, error) in DispatchQueue.main.async { if let err = error { observer. onError (err) } else { if let string = String(data: data!, encoding: .ascii) { observer. onNext (string!) } else { observer. onNext ("Error! Parse!") } observer.