12/08/2018, 16:09

Sử dụng Firebase Remote Config trong iOS.

1. Tổng quan Chúng ta đã quen với việc sử dụng các biến global để config cho ứng dụng của mình, ví dụ: static let baseUrl = "api.url.com" Như ở trên mình đã tạo ra một biến biến baseUrl để chứa đường dẫn của api. Giờ câu hỏi đặt ra, làm sao có thể thay đổi được đường dẫn trên khi mà ứng ...

1. Tổng quan

Chúng ta đã quen với việc sử dụng các biến global để config cho ứng dụng của mình, ví dụ:

    static let baseUrl = "api.url.com"

Như ở trên mình đã tạo ra một biến biến baseUrl để chứa đường dẫn của api. Giờ câu hỏi đặt ra, làm sao có thể thay đổi được đường dẫn trên khi mà ứng dụng đã lên Apple Store rồi. Cách đầu tiên ai cũng nghĩ đến đó là, thay đổi gía trị baseUrl trong code, build lại, upload một bản cập nhật mới, yêu cầu Apple Review lại. Hạn chế của cách trên đó là mất nhiều thời gian, và yêu cầu người dùng phải cập nhật ứng dụng, thì giá trị của biến baseUrl mới được cập nhật theo. Hôm nay mình sẽ giới thiệu cho các bạn một cách cực ký nhanh chóng, hiệu quả đó là thông qua một dịch vụ miễn phí của google, được gọi là Firebase Remote Config. Dịch vụ này cho phép chúng lưu trữ, lấy thông tin từ cloud của google, hiểu đơn giản là ta sẽ lưu biến basUrl trên cloud, và lúc này chỉ cần thay đổi giá trị của nó ở cloud thì ứng dụng sẽ tự động cập giá trị của biến đó nhât mà người dùng không hề hay biết.

2. Config Console.firebase.google.com

  • Đăng kí sử dụng https://console.firebase.google.com/: Việc đầu tiên cần phải làm là đăng kí ngay một tài khoản dịch vụ, việc này cực kì đơn giản và ai cũng có thể làm được.
  • Log in mà trang quản lý, chọn"Add Project", điền đầy đủ thông tin: project name, region... su đó chọn Create Project. Sau khi tạo được project, chúng ta sẽ được đưa đến trang quản lý của ứng dụng đó. Tại đây chọn tiếp Add Fireabase to iOS App. Một cửa sổ sẽ hiện lên, giống như bên dưới. Các bạn có thể nhìn thấy 4 step (trên ảnh) mà cần phải làm để có thể sự dụng được Firebase trong iOS. Ở #step1 thì quan trọng nhật đó phải điền bundle id sao cho giống với config trong Xcode, ví dụ mình sẽ đăng kí một app có id là com.firebase.demo, sau đó nhận Register App, sau khi hoàn thành thì bạn sẽ được đưa sang #step2 Download config file, vì từ #step2 đến #step4 đều liên quan đến coding nên mình sẽ nó ở phần 3 của bài. Quay trơ lại với câu hỏi ban đầu, làm thế nào để thay đổi biến baseUrl khi ứng dụng đã lên store. Sau khi đăng kí thành công ứng dụng, chúng ta quay trơ lại màn hinh quản lý, và để ý mục Remote Config (khoanh tròn trong bức ảnh). Click vào đó, chúng ta sẽ đến một trang quản lý khác, tại đó chọn "ADD YOUR FIRST PARAMETER". Như trong ảnh dưới mình tạo tạo ra môt parameter có key là "api_url" và giá tri là "api.url.com". Key rất quan trọng, vì trong code chúng ta sẽ fetch data từ cloud về và lấy giá trị ra theo key. OK vậy là phần config trên cloud đã xong, giờ bắt tay vào code.

3. Coding

  • Đầu tiên tạo một Xcode project với bundle id là com.firebase.demo trùng với id của project mà ta đã đăng kí trên web. Quay trở lại #step2 : Download config file (step 2 ở hình ảnh đầu tiên). Sau khi đăng kí được app, thì Firebase sẽ tạo cho chúng một file config, việc của chúng ta là download về và ném vào project.
  • Tiếp theo, cũng là #step3: Add Firebase to your iOS project, việc này rất đơn giản thôi, chúng ta sử dụng cocoapod, thêm pod 'Firebase/Core' vào trong pod file rồi chạy lệnh pod install, nếu chưa biết sử dụng cocoapod thì bạn có thể google thêm. Vậy là đã nhúng được firebase vào trong project.
  • #step4 Add init code copy đoạn code sau vào AppDelegate class.
func application(_ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)
    -> Bool {
    FirebaseApp.configure()
    return true
  }
}

Mình đã tạo ra một class dùng để tương tác với Firebase, và sẽ giải thích cụ thể từng đoạn code

import Foundation
import FirebaseRemoteConfig
(1)
enum RemoteConfigKey: String {
    case serverUrl = "api_url"
}

struct RemoteConfigManager {
  (2)
  // local default value
    static let baseUrl = "api.local.url"
 
    static let shared = RemoteConfigManager()
    
    fileprivate var remoteConfig: RemoteConfig
    
    fileprivate init() {
        self.remoteConfig = RemoteConfig.remoteConfig()
        self.setDefaultValue()
        #if DEBUG
            if let debugSetting = RemoteConfigSettings(developerModeEnabled: true) {
                self.remoteConfig.configSettings = debugSetting
            }
        #endif
    }
    (3)
     func setDefaultValue() {
        let url = RemoteConfigManager.baseUrl as NSString
        remoteConfig.setDefaults([RemoteConfigKey.serverUrl.rawValue: url])
    }
    
    (4)
    func getValue(fromKey key: RemoteConfigKey) -> String {
        
        if let value = self.remoteConfig.configValue(forKey: key.rawValue).stringValue {
            return value
        }
        return ""
    }
    
    (5)
    func fetchRemoteConfig(_ finish: DefaultVoidClosure?) {
        var expirationDuration = 0
        if self.remoteConfig.configSettings.isDeveloperModeEnabled {
            expirationDuration = 0
        }
        remoteConfig.fetch(withExpirationDuration: TimeInterval(expirationDuration)) { (status, _) in
            Log.debugLog("RemoteConfigManager fetchRemoteConfig status = (status.rawValue)")
            if status == RemoteConfigFetchStatus.success {
                self.remoteConfig.activateFetched()
                let url =  RemoteConfigManager.shared.getValue(fromKey: .serverUrl)
                Log.debugLog(" RemoteConfigManager RemoteConfigFetchStatus.success 
 new URL = (url)")
            }
            finish?()
        }
    }
    
}
  • (1) đây là nơi mình định nghĩa các key, giá trị các key này chính là tên các parameter mà ta đã tạo ra trên console.fire.goolge.
  • (2): khởi tạo trị default, vì việc fetch dữ liệu từ cloud có thể thất bại, vậy nên để app có đảm bảo luôn hoạt động được, chúng ta cần phải có giá trị default sẽ được sử dụng.
  • (3) đây là nơi là sẽ set giá trị default cho các key đã được địn nghĩa ở (1)
  • (4) func getValue(fromKey key: RemoteConfigKey) -> String hàm này cho phép chúng ta lấy được giá trị của một key đã được định nghĩa ở (1)
  • (5) hàm này rất quan trọng, chúng ta sẽ fetch dữ liệu từ cloud về, trường hợp đã fetch thành công, cần phải active dữ liệu đó, mới có thể sử dụng được, bằng đoạn code dưới.
 if status == RemoteConfigFetchStatus.success {
                self.remoteConfig.activateFetched()
                let url =  RemoteConfigManager.shared.getValue(fromKey: .serverUrl)
                Log.debugLog(" RemoteConfigManager RemoteConfigFetchStatus.success 
 new URL = (url)")
}

Vậy sau khi đoạ hàm trên chạy thành công, nếu chúng ta có thể lấy được giá trị mới nhất để sử dụng, ví dụ

        let newUrl = RemoteConfigManager.shared.getValue(fromKey: .serverUrl)

Thông thường mình sẽ fetch dữ liệu từ cloud khi app khởi chạy, đảm bảo dữ liệu mới nhất trước khi sử dụng.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        RemoteConfigManager.shared.fetchRemoteConfig {
        // do somethings
           }
        return true
    }
0