GatheredKit 0.1.1

GatheredKit 0.1.1

Joseph Duffy维护。



  • 撰文
  • Joseph Duffy

GatheredKit

Build Status Documentation Carthage Compatible CocoaPods Compatible MIT License

GatheredKit是一个iOS框架,为iOS提供的一致且易于使用的API支持各种数据源。

代码源于Gathered应用程序,因此得名和标志。

快速链接

可用的来源

每个来源都是基于苹果提供的相应类的一个类,但具有简化且一致的API以接收更新。以下是GatheredKit所能提供的来源列表。未勾选的框表示将来会加入的来源。

  • 位置
  • Wi-Fi
  • 高度计
  • 麦克风
  • 蜂窝网络
  • 屏幕
  • 指南针
  • 磁力计
  • 陀螺仪
  • 加速度计
  • 设备方向
  • 接近度
  • 电池
  • 广告
  • 音频输出
  • 设备方向
  • 蓝牙
  • 存储
  • 内存
  • 设备元数据
  • 操作系统
  • CPU
  • 摄像头
  • 电池

API

GatheredKit的目标是通过包装在直观且一致的API中来抽象掉创建来源所使用的各种iOS框架的特定细节。

来源

GatheredKit 的核心是 来源 协议。

/**
 An object that can provide data from a specific source on the device
 */
public protocol Source: class, ValuesProvider {

    /// The availability of the source
    static var availability: SourceAvailability { get }

    /// A user-friendly name that represents the source, e.g. "Location", "Device Attitude"
    static var name: String { get }

    /// Creates a new instance of the source
    init()

}

本身它并没有太多功能,但当与 ValuesProvider 结合时,就构成了 GatheredKit 中所有类的基石。

ValuesProvider

/**
 An object that provides values
 */
public protocol ValuesProvider {

    /// An array of all the values provided by this object
    var allValues: [Value] { get }

}

实现还具有各自价值观的单独属性,例如 Screen 来源的 亮度 属性。

Controllable

Controllable 协议定义了一个可以自动更新其值的对象。这些自动更改可随时启动和停止。

/**
 An object that be started and stopped
 */
public protocol Controllable: class {

    /// A closure that will be called with the latest values
    typealias UpdateListener = (_ latestValues: [Value]) -> Void

    /// A boolean indicating if the `Controllable` is currently performing automatic updates
    var isUpdating: Bool { get }

    /**
     Starts automatic updates. Closures added via `addUpdateListener(_:)` will be
     called when new values are available
     */
    func startUpdating()

    /**
     Stops automatic updates
     */
    func stopUpdating()

    /**
     Adds a closure to the array of closures that will be called when any of the source's
     values are updated. The closure will be called with all values, but not all the values
     will neccessary be new.

     The returned object must be retained; the lifecycle of the listener is tied to the object. If
     the object is deallocated the listener will be destroyed.

     - parameter updateListener: The closure to call with updated values
     - parameter queue: The dispatch queue the listener should be called from
     - returns: An opaque object. The lifecycle of the listener is tied to the object
     */
    func addUpdateListener(_ updateListener: @escaping UpdateListener, queue: DispatchQueue) -> AnyObject

}

public extension Controllable {

    /**
     Starts automatic updates and adds a closure to the array of closures that will be called when
     any of the source's values are updated. The closure will be called with all values, but
     not all the values will neccessary be new.

     The returned object must be retained; the lifecycle of the listener is tied to the object. If
     the object is deallocated the listener will be destroyed.

     - parameter queue: The dispatch queue the listener should be called from
     - parameter updateListener: The closure to call with updated values
     - returns: An opaque object. The lifecycle of the listener is tied to the object
     */
    func startUpdating(sendingUpdatesOn queue: DispatchQueue, to updateListener: @escaping UpdateListener) -> AnyObject

    /**
     Starts automatic updates and adds a closure to the array of closures that will be called when
     any of the source's values are updated. The closure will be called on the main dispatch queue with
     all values, but not all the values will neccessary be new.

     The returned object must be retained; the lifecycle of the listener is tied to the object. If
     the object is deallocated the listener will be destroyed.

     - parameter updateListener: The closure to call with updated values
     - returns: An opaque object. The lifecycle of the listener is tied to the object
     */
    func startUpdating(sendingUpdatesTo updateListener: @escaping UpdateListener) -> AnyObject

}

CustomisableUpdateIntervalControllable

CustomisableUpdateIntervalControllable 是一个 Controllable,其中一个或多个值需要轮询以进行更新。

/**
 A source that supports updating its properties at a given time interval
 */
public protocol CustomisableUpdateIntervalControllable: Controllable {

    /// The default update interval that will be used when calling `startUpdating()`
    /// without specifying the update interval.
    /// This value is unique per-source and does not persist between app runs
    static var defaultUpdateInterval: TimeInterval { get set }

    /// The time interval between property updates. A value of `nil` indicates that
    /// the source is not performing periodic updates
    var updateInterval: TimeInterval? { get }

    /**
     Start performing periodic updates, updating every `updateInterval` seconds

     - parameter updateInterval: The interval between updates, measured in seconds
     */
    func startUpdating(every updateInterval: TimeInterval)

}

public extension CustomisableUpdateIntervalControllable {

    /// A boolean indicating if the source is currently updating its properties every `updateInterval`
    public var isUpdating: Bool

    /**
     Starts performing period updated. The value of the static variable `defaultUpdateInterval` will
     used for the update interval.
     */
    public func startUpdating()

    /**
     Start performing periodic updates, updating every `updateInterval` seconds.

     The passed closure will be added to the array of closures that will be called when any
     of the source's values are updated. The closure will be called with all values, but not
     all the values will neccessary be new.

     The returned object must be retained; the lifecycle of the listener is tied to the object. If
     the object is deallocated the listener will be destroyed.

     - parameter updateInterval: The interval between updates, measured in seconds
     - parameter queue: The dispatch queue the listener should be called from
     - parameter updateListener: The closure to call with updated values
     - returns: An opaque object. The lifecycle of the listener is tied to the object
     */
    public func startUpdating(every updateInterval: TimeInterval, sendingUpdatesOn queue: DispatchQueue, to updateListener: @escaping UpdateListener) -> AnyObject

}

ManuallyUpdatableValuesProvider

ManuallyUpdatableValuesProvider 是一个 ValuesProvider,可以通过调用 updateValues 函数手动更新。

/**
 A source that supports its properties being updated at any given time
 */
public protocol ManuallyUpdatableValuesProvider: ValuesProvider {

    /**
     Force the values provider to update its values.

     Note that there is no guarantee that the returned values will be new, even
     if the date has updated

     - returns: The values after the update
     */
    func updateValues() -> [Value]

}

安装

GatheredKit 可以使用以下任何一种方法进行安装。安装完成后,只需 import GatheredKit 即可开始使用。

Carthage

通过 Carthage 安装,请在您的 Cartfile 中添加以下内容:

github "JosephDuffy/GatheredKit"

运行 carthage update GatheredKit --platform iOS 来构建框架,然后将其拖入您的 Xcode 项目中。GatheredKit 提供预编译的二进制文件,这可能会引起一些符号问题。如果这是一个问题,请使用 --no-use-binaries 标志。

记得将 GatheredKit 添加到您的 Carthage 构建阶段

$(SRCROOT)/Carthage/Build/iOS/GatheredKit.framework

并且

$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/GatheredKit.framework

CocoaPods

通过 CocoaPods 安装,请将以下行添加到您的 Podfile 中:

pod 'GatheredKit'

然后运行 pod install

文档

GatheredKit 的文档包含在源代码中。可浏览的文档可在 https://josephduffy.github.io/GatheredKit/ 上找到。

运行测试

运行 GatheredKit 的测试需要 QuickNimble,可以使用 Carthage 进行安装。

carthage build --platform iOS --no-use-binaries

测试可以通过 Xcode 或 fastlane test 运行。

许可

项目采用MIT许可证发布。请参阅LICENSE文件以获取完整的许可证。