ERNiftyFoundation
示例
要运行示例项目,请克隆仓库,然后首先从 Example 目录中运行 pod install
。
安装
ERNiftyFoundation 通过 CocoaPods 提供。要安装它,只需将以下行添加到 Podfile:
pod "ERNiftyFoundation"
关于
在开发了几款应用程序之后,您可能会注意到每个项目中都有一些重复的主题。我们尽最大努力在项目之间复制和共享基础代码,有时发现自己在重新集成我们最喜欢的 pods。ERNiftyFoundation 的目标是成为您开始建立一个美观的现代化 iOS 应用程序所需一切功能的单个 pod。
添加依赖项
- Alamofire - 最好的HTTP网络库
- ERNiftyExtensions - 为Foundation类提供了一系列扩展,使开发更简便
- Kingfisher - 极棒的异步图片下载库,为UIImageView提供扩展
- NVActivityIndicatorView - 精美且可定制的活动指示器
- PhoneNumberKit - 优雅且简单的处理电话号码的工具包
- Starscream - WebSocket客户端
- Unbox - 我最喜欢的JSON到模型对象的解码器;try/catch + 泛型 = 极棒!
- Wrap - 一款惊人的自动模型到JSON编码器,无需键/值映射
功能
- 提供最易使用的pods
- 围绕Alamofire设计的超级易用的RESTful API管理器
- 令牌身份验证
- 使用Starscream提供Websocket连接和定制API
- Apple Push通知的设置和处理程序。
- 大量有用的Foundation扩展
使用说明
入门教程
在你的AppDelegate中,配置网络层。首先创建一些ERAPIEnvironment对象来表示我们的开发和生产环境。然后使用环境配置ERAPIManager。对于DEBUG构建(iOS模拟器和通过Xcode运行的设备),ERAPIManager将使用开发环境的URL进行网络请求。对于RELEASE构建(Test Flight,App Store),ERAPIManager将使用生产环境。
import ERNiftyFoundation
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Create a dev environment.
let development = ERAPIEnvironment(
type: .development,
apiURL: "https://dev.myapi.mydomain.com/v1/",
webSocketURL: "ws://dev.myapi.mydomain.com/ws"
)
// Create a prod environment.
let production = ERAPIEnvironment(
type: .development,
apiURL: "https://prod.myapi.mydomain.com/v1/",
webSocketURL: "ws://prod.myapi.mydomain.com/ws"
)
// Configure the manager.
ERAPIManager.configureFor(development: development, production: production)
return true
}
}
如果你希望在开发环境中使用 localhost:8080
,可以传递可选的布尔参数。
ERAPIManager.configureFor(development: development, production: production, usesLocalHost: true)
模型
太好了。现在让我们创建一个模型,比如 User.swift
。只需遵循 ERModelType
协议,并实现以下要求
- 必须有一个 String 类型的 id 属性。
- 必须是类。
- 必须实现
init(unboxer: Unboxer)
import ERNiftyFoundation
import Unbox
import Wrap
public final class User: ERModelType {
public let id: String
public let fullName: String
init(id: String, fullName: String) {
self.id = id
self.fullName = fullName
}
public convenience init(unboxer: Unboxer) throws {
let id: String = try unboxer.unbox(key: "id")
let fullName: String = try unboxer.unbox(key: "full_name")
self.init(id: id, fullName: fullName)
}
}
得益于 ERModalType
,编码和解码从未如此简单
let user = try? User(JSON: someJSON)
let someJSON = user.JSON
底层,ERModelType
遵循 class
、Equatable
、Unboxable
和 WrapCustomizable
。这意味着我们的模型始终是类、可比较的,并且可以进行 JSON 编码和解码。
借助 WrapCustomizable
,我们可以覆盖一个有用的变量 wrapKeyStyle
,以便使 JSON 编码器将所有属性使用驼峰式命名
extension User {
public var wrapKeyStyle: WrapKeyStyle { return .convertToSnakeCase }
}
端点
ERNiftyFoundation 提供了一种方便的方法来构建您的 API 端点。首先,让我们使用 ERAPIManager.endpoint(components: String...)
创建一个简单的端点对象。
let endpoint = ERAPIManager.endpoint(components: "users", "23foh34gfoiherglkjsneflibweg")
事实上,这个对象表示端点 http://<base>/users/23foh34gfoiherglkjsneflibweg
,其中基本组件是由 APIManager 当前环境的 apiURL
属性导出的。
您可以传递字符串作为组件,或使用方便的 ERAPIPathComponent
结构。这使得构建端点更加容易,特别是在使用 .id(String)
静态变量时。两种方式都可以,因为它们都遵循 ExpressibleByStringLiteral
协议
extension ERAPIPathComponent {
public static var users: ERAPIPathComponent { return "users" }
}
let endpoint = ERAPIManager.endpoint(components: .users, .id("23foh34gfoiherglkjsneflibweg"))
请求
现在是时候创建请求了
func getUser(withId idValue: String) {
let endpoint = ERAPIManager.endpoint(components: .users, .id(idValue))
ERAPIManager.request(on: endpoint) { (user: User?, error) in
guard let user = user else { print(error); return }
print("Here is the user - ID: \(user.id) Full name: \(user.fullName)")
}
}
请求具有与 Alamofire 请求相同的外观和感觉,但使用泛型和 ERModalType
的力量自动将响应 JSON 解码到您的模型中。
func getAllUsers() {
let endpoint = ERAPIManager.endpoint(components: .users)
ERAPIManager.request(on: endpoint) { (users: [User]?, error) in
guard let users = users else { print(error); return }
for user in users {
print("Here is a user - ID: \(user.id) Full name: \(user.fullName)")
}
}
}
您甚至可以使用 ERNiftyFoundation 提供的 JSONObject
别名(对应于 [String:Any]
)
func getAllUsers() {
let endpoint = ERAPIManager.endpoint(components: .users)
ERAPIManager.request(on: endpoint) { (users: [JSONObject]?, error) in
guard let users = users else { print(error); return }
for user in users {
print("Here is a user JSON: \(user) ")
}
}
}
WebSocket
ERNiftyFoundation不仅提供了一个APIManager,还提供了一个SocketManager,因此您不必担心维护连接、多线程和计时器。它甚至可以处理应用程序生命周期的相关事件,例如进入后台/前台时自动连接和重新连接。使用起来非常简单,只需以下两行代码即可
ERSocketManager.shared.connect()
ERSocketManager.shared.disconnect()
连接URL将从ERAPIManager当前的webSocketURL环境中获取。
推送通知
每个优秀的应用程序都会告诉用户他们为什么应该回来,甚至更好地,他们错过了什么。ERNiftyFoundation提供了一个管理器来完成这个任务。当您的用户使用您的API成功认证后,这是一个设置APN管理器的良好位置。
ERAPNManager.shared.setup(options: [.badge, .alert, .sound]) { error in
print("Something went wrong: \(error)")
}
这个简单而有效的函数会从设备请求APN令牌,如果成功获取则无错误地调用完成处理程序。如果没有获取,APNManager会自动显示一个弹出窗口告知用户推送通知已被禁用,他们必须在设置应用程序中允许这一操作。
杂项
ERNiftyFoundation还提供了方便的小工具,如ERDevice
来了解您正在运行的是哪款设备,以及ERTargetMode
来了解您是否正在iOS模拟器、真实设备、DEBUG或RELEASE模式下运行。
作者
erusso1,[email protected]
许可
ERNiftyFoundation在MIT许可证下提供。有关更多信息,请参阅LICENSE文件。