iOS Dev cần biết những gì để thực hiện công việc hàng ngày?

Thảo luận trong 'iOS' bắt đầu bởi nhatlectv, 3/2/18.

  1. nhatlectv

    nhatlectv Stanford - Nâng tầm tri thức Thành viên BQT

    5. Dependency Manager
    CocoaPods và Carthage là một trong những dependency manager phổ biến (dùng để quản lý phiên bản library) mà dev hay dùng cho các dự án Swift và Objective-C.
    CocoaPods lưu trữ lượng lớn các libraries, quản lý giúp chúng ta các phiên bản được cập nhật/release liên tục. Cách cài đặt đơn giản với Ruby sử dụng command line như sau:

    $sudo gem install cocoapods

    Sau khi cài đặt xong, chúng ta cần tạo file Podfile cho dự án:

    $pod init
    Sau đó thì tạo nội dung podfile với cấu trúc như sau, để lấy library về:

    target'Projecct'do
    use_frameworks!
    pod'Alamofire',"4.4.0"
    pod'FacebookCore', "0.2.0"
    pod'FacebookShare',"0.2.0"
    pod'Firebase/Core',">=3.6"
    pod'FirebaseCrash',"1.1.6"
    pod'Firebase/Messaging', "3.16.0"
    pod'GoogleAnalytics',"3.17.0"
    end

    Sau đó chạy:

    $pod install

    Sau đó, mở file project’s .xcworkspace và import các dependeny vào.

    Còn với Carthage, là một dependency manager kiểu phân tán, nó ngược với CocoaPod , là kiểu tập trung. Nhược điểm của Carthage là chúng ta phải thêm các framework bằng tay các thứ, còn ưu điểm thì tốc độ build project nhanh hơn.

    6. Storing information
    Có nhiều cách để lưu giữ data trong ứng dụng của dev. Phổ biến nhất là NSUserDefaults, cho phép lưu trữ các user data mặc đinh, được sử dụng khi app load lần đầu. Các type được phép lưu trữ bao gồm:

    • NSData
    • NSDate
    • NSNumber
    • NSDictionary
    • NSString
    • NSArray
      Để tương thích với Swift, NSNumber được chấp nhận với các kiểu data sau:
    • UInt
    • Int
    • Float
    • Double
    • Bool
    Các Object có thể lưu vào NSUserDefault theo cách sau (tất nhiên trước hết cần tạo constant để keep các key cho các object được save)

    let keyConstant="objectKey"
    let defaults=NSUserDefaults.standardsUserDefaults()
    defaults.setObject("Object to save",objectKey:keyConstant)

    Để đọc object từ NSUserDefault, chúng ta cần :

    iflet name=defaults.stringForKey(keyConstant){
    print(name)
    }


    Tiếp theo, chúng ta tìm hiểu về Keychain, là hệ thống quản lý password, chứa password, các chứng chỉ xác thực (certififcate), private key hoặc là private notes, tóm lại là các thông tin nhạy cảm. Keychain có 2 mức mã hoá device (device encryption). Mức đầu tiên sử dụng passcode của màn hình khoán như là mã hoá key (encryption key). Mức thứ 2 sử dụng một key được phát hành và lưu trữ trên device. Điều này không thực sự an toàn, đặc biệt khi bạn không sử dụng passcode ở màn hình lock. Có nhiều cách để truy cập vào key được sử dụng ở mức 2, vì nó được lưu trên device. Do vậy, cách tốt nhất là bạn không nên lưu trữ key trên device.

    CoreData, là framework được thiết kế/cung cấp với chính chủ Apple, dùng cho ứng dụng của bạn trong việc kết nối với database. Nó khá là đơn giản khi xử lý, giảm thiểu mã hoặc lược bỏ đi khi cần phải test.
    Nên dùng CoreData khi mà app của bạn có các thông tin của dữ liệu thường xuyên được truy cập và gần như không có thay đổi trong tương lai. Nó cung cấp các solution để đơn giản hoá quá trình xử lý, truy cập data, mà bạn không cần phải tự xây dựng lại các comunication với DB hoặc test lại.

    7.CollectionView và TableView
    Để hiển thị dữ liệu, hầu hết các app đều sử dụng hoặc collection view hoặc table view. Biết chúng hoạt động ra sao, khi nào sử dụng cái này, không sử dụng cái kia sẽ tránh được những thay đổi phức tạp tới app của bạn trong tương lai.
    TableView hiển thị các item dưới dạng list, trong một cột đơn, và giới hạn scroll theo trục dọc. Mỗi item đươc thể hiện dưới dạng UITableViewCell, hoàn toàn có thể custom theo ý muốn. Chúng được lưu trữ trong các section và các row.
    CollectionView cũng hiển thị các item dưới dạng list, tuy nhiên, chúng có thể có nhiều cột và hàng, ví dụ dưới dạng lưới chẳng hạn. Chúng có thể scroll theo trục dọc hoặc trục ngang, mỗi item được biểu diễn bởi UICollectionViewCell. Cũng tương tự như UITableViewCell, các cell này có thể tuỳ biến được, trong sắp xếp trong các section và row tương ứng.
    Cả 2 loại view phổ biến trên đều có chức năng tương tự nhau, đểu tái sử dụng cell để nâng cao độ mượt của ứng dụng. Lựa chọn cái nào bạn cần phải dựa vào mức độ phức tạp của list item bạn có. Lựa chọn phổ biến là hay sử dụng UICollectionView vì tính đa dạng của nó. Ví dụ, bạn muốn hiện thị một danh sách danh bạ chẳng hạn, với đơn giản là 1 column thôi, đơn giản chúng ta sẽ lựa chọn UITableView. Mọi thứ vẫn bình thường, nhưng sau một thời gian thì Designer muốn thay đổi danh bạ nên được hiện thị dưới dạng grid thì tốt hơn, thay vì dạng list. Để làm được điều này, bạn phải chuyển đổi code từ UITableView sang UICollectionView. Cũng khá bất tiện, việc thay đổi code đâu có dễ như thay đổi design? Như vậy, tốt nhất ngay từ đầu nên chọn UICollectionView, dễ cho việc tuỳ biến sau này.

    8. Storyboad vs Xibs vs Programatic UI
    Các phương pháp trên có thể được sử dụng độc lập với nhau để tạo UI, tuy nhiên, không có điều gì ngăn cản bạn kết hợp chúng lại với nhau.
    Storyboads cho phép một chúng ta quan sát một cái nhìn toàn diện về project, dưới dạng các screen và mối quan hệ giữa chúng, đây là điều mà designer rất thích, bởi vì họ có thể quan sát toàn bộ flow tất cả các màn hình. Nhưng điểm trừ là khi càng thêm vài màn hình mới vào, các kết nối giữa các màn hình càng trở nên phức tạp và khá là rối, đôi khi nó còn ảnh hưởng đến việc thời gian build ứng dụng, vì phải loading khá là lâu file storyboard. Một trong những issue làm đau đầu dev là công việc xử lý conflict khi phải merge các file storyboard như thế này. Quá nhiều UI phải phụ thuộc vào storyboard, mất khá nhiều thời gian khi phải sửa chữa lỗi merge, làm lại có khi còn nhanh hơn.
    Xib, đơn giản hơn, chung cấp một view cận cảnh, rõ ràng hơn của từng màn hình hoặc từng khu vực của màn hình. Lợi thế của nó là rất dễ để tái sử dụng, khi merge thì không gặp nhiều khó khăn, vì nó được tách bạch rõ cho từng màn hình.
    Programming, tức là tự code lấy UI, chúng ta có nắm được cụ thể từng vị trí, từng component của view, tốn ít sức merge khi xảy ra conflict nhất. Nhược điểm của nó là đôi khi quá chi tiết, mất thời gian kiểm soát từng dòng code một.

    Có một vài phương pháp tiếp cận khác nhau để tạo ra UI. Lời khuyên đưa ra là nên kết hợp cả 3 phương pháp. Sử dụng Storyboard để control flow màn hình, bằng cách nhóm từng màn hình trong từng storyboard, còn với Xib, sử dụng cho các màn hình cụ thể hơn, mà nó không phải là màn hình chính, và cuối cùng sử dụng programing để xử lý các control của từng vị trí cụ thể, (chẳng hạn như la thay đổi state label, button các thứ).

    9. Protocols
    Protocols tồn tại trong cuộc sống hàng ngày của chúng ta để chắc chắn rằng, trong tình huống nhất định nào đó, chúng ta biết phải phản ứng như nào. Ví dụ, bạn là một người lính, trong một tình huống khẩn cấp, tất cả các lính cứu hoả phải đảm bảo đáp ứng được nguyên tắc là tất cả các thiết bị luôn trong trạng thái sẵn sàng phản hồi/xử lý khi có đám cháy xảy ra.
    Quay lại protocol trong Objective-C/Swift, các protocol định nghĩa sẵn một list các method, thuộc tính hoặc yêu cầu gì đo, mang tính chất giả định thôi, cho các chưc năng nhất định nào đó. Nó có thể được thực thi ở class, structure hoặc một enumeration nào đó, và nó sẽ được thực hiện cụ thể trong requirement nào đó.
    Ví dụ dưới đây mô tả một protocol được tạo ra và sử dụng như thế nào.
    Tôi cần phải tạo ra một enum các nguyên – vật liệu khác nhau có thể phải được sử dụng trong việc giải quyết một đám cháy.

    enumExtinguisherType:String{
    casewater,foam,sand
    }


    Tiếp theo, tôi sẽ tạo một protocol để phản hồi khi có đám cháy thực sự xảy ra.

    protocolRespondEmergencyProtocol{
    func putOutFire(with material:ExtinguisherType)
    }


    Tiếp, tôi sẽ tạo một fireman, để conform cái protocol kia:

    classFireman:RespondEmergencyProtocol{
    func putOutFire(with material:ExtinguisherType){
    print("Fire was put out using \(material.rawValue).")
    }
    }


    Xong, hãy xem khi có đám cháy xảy ra, fireman sẽ phải làm gì?

    varfireman:Fireman=Fireman()
    fireman.putOutFire(with:.foam)

    Kết quả là, “Fire was put out using foam.”!

    Protocol đươc sử dụng phổ biến trong pattern Delegation (Uỷ nhiệm). Nó cho phép một class hay struct “uỷ nhiệm” một chức năng nhất định cho một “thể hiện” của type khác. Một protocol được tạo ra, chịu trách nhiệm thực thị quyền uỷ nhiệm đó, đảm bảo các chức năng function được đáp ứng đầy đủ.
    Ví dụ nhanh như sau:

    protocolFireStationDelegate{
    func handleEmergency()
    }


    Một firestation uỷ nhiệm một hành động xử lý tình huống khẩn cấp cho fireman.

    classFireStation{
    vardelegate:FireStationDelegate?
    fun emergencyCallReceived(){
    delegate?.handleEmergency()
    }
    }


    Điều này có nghĩa là fireman sẽ phải conform cái protocol FireStationDelegate ngay khi xảy ra sự kiện.

    classFireman:RespondEmergencyProtocol,FireStationDelegate{
    func putOutFire(with material:ExtinguisherType){
    print("Fire was put out using \(material.rawValue).")
    }
    func handleEmergency(){
    putOutFire(with:.water)
    }
    }


    Fireman sẽ thực hiện các action mà fire station “uỷ nhiệm” cho, anh ta sẽ xử lý khi nhận được cuộc gọi khẩn cấp khi sự kiện xảy ra

    let firestation:FireStation=FireStation()
    firestation.delegate=fireman
    firestation.emergencyCallReceived()


    Kết quả là, “Fire was put out using water.”
     

Chia sẻ trang này