龙虾 3.1.1

龙虾 3.1.1

sgr-ksmt 维护。



龙虾 3.1.1

  • 岸木 巳徕

龙虾

类型安全的 Firebase-RemoteConfig 帮助库。

GitHub release Language

Carthage Compatible CocoaPods

功能

  • 可以从 RemoteConfig 获取值/安全地将值设置到 RemoteConfig。
  • 使用键值索引轻松设置 RemoteConfig 的默认值。
  • 支持自定义类型
    • String/Int 枚举
    • Decodable(只读) 和 Codable
  • 可以管理配置值的过期时长。
  • 支持 Combine 框架。

入门指南

基本用法

您可以通过以下几个步骤将 Lobster 集成到项目中

1. 定义 ConfigKey

extension ConfigKeys {
    static let welcomeTitle = ConfigKey<String>("welcome_title")
    static let welcomeTitleColor = ConfigKey<UIColor>("welcome_title_color")
}

2. 将值注册到 Firebase 项目

转到 Firebase 项目,并设置想要获取的值。

3. 让我们使用 Lobster

import Lobster

// Set default value
Lobster.shared[default: .welcomeTitle] = "Welcome"
Lobster.shared[default: .welcomeTitleColor] = .black

self.titleLabel.text = Lobster.shared[.welcomeTitle]

// Fetch remote-config
Lobster.shared.fetch { _ in
    dispatchQueue.main.async { [weak self] in
        self?.titleLabel.text = Lobster.shared[.welcomeTitle]
        self?.titleLabel.textColor = Lobster.shared[.welcomeTitleColor]
    }
}

给您的小贴士

组合

您可以使用 Combine 的流从 Lobster 获取值。
以下是一个示例 viewModel 类。

import Lobster
import Combine

extension ConfigKeys {
    static let title = ConfigKey<String>("title")
}

final class ViewModel: ObservableObject {
    @Published var title: String
    private var cancellables: Set<AnyCancellable> = []

    init() {
        title = Lobster.shared[.titleText]

        Lobster.shared.combine.fetched(.title)
            .receive(on: RunLoop.main)
            .assign(to: \.title, on: self)
            .store(in: &cancellables)
    }
}

注意:在使用之前,您需要安装 Lobster/Combine

使用下标语法获取值。

使用下标语法。

  • 非可选
extension ConfigKeys {
    static let text = ConfigKey<String>("text")
}

// Get value from config.
// If value didn't fetch from remote yet. returns default value (if exists).
let text: String = Lobster.shared[.text]

// Get value from only config.
// it is possible to crash if value didn't fetch from remote yet.
let text: String = Lobster.shared[config: .text]

// Get value from only default.
// It is possible to crash if the default value is not set yet.
let text: String = Lobster.shared[default: .text]

// [safe:], [safeConfig:], [safeDefault:] subscripting syntax.
// It is safe because they return nil if they have no value.(return type is `Optional<T>`.)
let text: String? = Lobster.shared[safe: .text]
let text: String? = Lobster.shared[safeConfig: .text]
let text: String? = Lobster.shared[safeDefault: .text]
  • 可选
extension ConfigKeys {
    static let textOptional = ConfigKey<String?>("text_optional")
}

let text: String? = Lobster.shared[.textOptional]
let text: String? = Lobster.shared[config: .textOptional]
let text: String? = Lobster.shared[default: .textOptional]

设置默认值

您可以使用代码中的subscripting语法或plist来设置默认值。

// Set default value using `[default:]` syntax.
Lobster.shared[default: .titleText] = "Cart Items"
Lobster.shared[default: .titleColor] = .black

// or load from `defaults.plist`
Lobster.shared.setDefaults(fromPlist: "defaults")

设置调试模式

// Enable debug mode (development only)
Lobster.shared.debugMode = true
Lobster.shared.fetchExpirationDuration = 0.0

isStaled

如果将isStaled设置为true,Lobster将忽略fetchExpirationDuration来提取远程值。
也就是说,在您将isStales设置为true之后调用fetch时,您可以立即检索配置值。
之后isStaled将被设置为false

Lobster.shared.fetchExpirationDuration = 60 * 12

Lobster.shared.isStaled = true

// Default expire duration is 12 hours.
// But if `isStaled` set to true,
// Lobster fetch values from remote ignoring expire duration.
Lobster.shared.fetch()

支持类型

Lobster默认支持以下类型:

  • 字符串
  • 整型
  • 浮点数
  • 双精度浮点数
  • 布尔值
  • 数据
  • URL
  • UIColor
  • 枚举(字符串/整型)
  • 可解码对象
  • 可编码对象
  • 集合(数组)
    • 字符串
    • 整型
    • 浮点数
    • 双精度浮点数
    • 布尔值
    • 数据
    • URL
    • 枚举(字符串/整型)
    • 可解码对象
    • 可编码对象

待办

  • CGPoint
  • CGSize
  • CGRect
  • 字典

URL

支持文本

UIColor

支持仅HEX字符串,如"#FF00FF"

枚举

支持IntString的原始值。它只能通过适配ConfigSerializable来使用。如果您想使用其他枚举,请参阅使用自定义值

符合Decodable类型

只读

符合Codable类型

可以设置默认值 / 读取配置值

高级用法

您可以轻松获取/设置自定义类型的值。
如果您想获取/设置ValueType(这是一个不支持的自定义类型),则需要实现以下步骤

  • ConfigSerializable遵守ValueType
  • 创建`ConfigBridge`
  • 定义ConfigKey

示例案例1:枚举

// Adapt protocol `ConfigSerializable`
enum Status: ConfigSerializable {
    // Define `_config`, `_configArray`(If needed).
    // Custom ConfigBridge's definition see below.
    static var _config: ConfigBridge<Status> { return ConfigStatusBridge() }
    static var _configArray: ConfigBridge<[Status]> { fatalError("Not implemented") }

    case unknown
    case active
    case inactive

    init(value: String?) {
        guard let value = value else {
            self = .unknown
            return
        }
        switch value {
        case "active": self = .active
        case "inactive": self = .inactive
        default: self = .unknown
        }
    }

    var value: String {
        switch self {
        case .active: return "active"
        case .inactive: return "inactive"
        default: return ""
        }
    }
}

// Define Bridge class
final class ConfigStatusBridge: ConfigBridge<Status> {
    typealias T = Status

    // Save value to default store
    override func save(key: String, value: T?, defaultsStore: DefaultsStore) {
        defaultsStore[key] = value?.value
    }

    // Get value from RemoteConfig
    override func get(key: String, remoteConfig: RemoteConfig) -> T? {
        return remoteConfig[key].stringValue.flatMap(Status.init(value:))
    }

    // Get value from default store
    override func get(key: String, defaultsStore: DefaultsStore) -> T? {
        return (defaultsStore[key] as? String).flatMap(Status.init(value:))
    }
}

// Define ConfigKey
extension ConfigKeys {
    static let status = ConfigKey<Status>
}

// Set default
Lobster.shared[default: .status] = .inactive

// Use value
Lobster.shared.fetch { _ in
    let currentStatus = Lobster.shared[.status]
}

定义下标可以访问自定义枚举。

示例场景 2:可解码兼容类型

只需将 DecodableCodable 应用到类或结构体,并适配 ConfigSerializable

struct Person: Codable, ConfigSerializable {
    let name: String
    let age: Int
    let country: String
}

extension ConfigKeys {
    static let person = CodableConfigKey<Person>("person")
}

在控制台中按以下方式定义配置值

要求

  • iOS 11.0+
  • Xcode 10+
  • Swift 5.0

安装

CocoaPods

龙虾 通过 CocoaPods 提供。要安装它,只需在 Podfile 中添加以下行

pod 'Lobster', '~> 3.1.0'

# If you want to use extensions of Combine, please install below:
pod 'Lobster/Combine'

并运行 pod install

开发

  • 1: 设置项目
$ cd path/to/Lobster
$ make
  • 2: 准备 GoogleService-Info.plist

由于安全问题,我无法提供 GoogleService-Info.plist 文件。因此,请在 Firebase 项目中自行准备。
然后请将 Firebase 应用程序的 bundle 标识符设置为 -.test.LobsterTests
之后,将它放入 LobsterTests/

通讯

  • 如果您发现了一个错误,请提交一个问题。
  • 如果您有一个功能请求,请提交一个问题。
  • 如果您想贡献力量,请提交一个拉取请求。💪

许可证

龙虾受MIT许可协议保护。更多详细信息请参阅LICENSE文件。