测试已测试 | ✗ |
语种语言 | SwiftSwift |
许可证 | MIT |
发布最新版本 | 2016年8月 |
SPM支持 SPM | ✗ |
由 Jason Welch 维护。
依赖 | |
Alamofire | >= 3.4 |
SwiftyJSON | >= 2.3 |
BrightFutures | >= 4.1 |
Result | >= 2.0 |
通过从 CRUDE 的各种协议继承,您可以轻松地在远程服务器上创建、读取、更新、删除和枚举您的数据模型。CRUDE-Futures 利用 BrightFutures 来异步加载数据模型,通过 Alamofire 发送请求,并通过 SwiftyJSON 映射返回的 JSON。
协议 | 路径覆盖 | 请求类型 | 便捷方法 | 返回 |
---|---|---|---|---|
CRUDECreatable | createPath | POST | createOnServer | Self |
createOnServerOkay | Okay | |||
CRUDEReadable | readPath | GET | readFromServer | Self |
readFromServerWithId | Self | |||
CRUDEUpdatabe | updatePath | PUT | updateOnServer | Self |
updateOnServerOkay | Okay | |||
CRUDEDeletable | deletePath | DELETE | deleteFromServer | Okay |
CRUDEEnumeratable | enumeratePath | GET | enumerateFromServer | [Self] |
CRUDE 只适用于返回 JSON 的 API 调用。
Crude-Futures 依赖于以下 pods...
CRUDE-Futures 可通过 CocoaPods 使用。要安装它,只需将以下行添加到您的 Podfile 中
pod 'CRUDE-Futures', '~> 0.1'
第一步也是最重要的一步是设置 CRUDE 以在您的应用中使用。在您的 AppDelegate
中导入 CRUDE_FUTURES
,然后在 application(application: didFinishLaunchingWithOptions:)
内调用 configure
。例如:
// AppDelegate
CRUDE.configure(baseURL: "https://mysite.com/api", headers: kDefaultHeaders)
如果您想让 CRUDE 在调用 API 时进行某种日志记录,您可以通过变量提供一个 CRUDEResponseLog
块。这可以通过以下方式完成:
let myLogger: CRUDEResponseLog = { response in
if let error = response.result.error {
print("CRUDE FAILURE: \(error.localizedDescription)")
} else
let method = response.request?.HTTPMethod ?? "UNKNOWN"
let urlString = response.request?.URLString ?? "unknown"
print("\(network.response!.statusCode) from \(method) \(urlString)")
}
}
CRUDE.configure(baseURL: "https://mysite.com/api", headers: kDefaultHeaders, responseLoggingBlock: myLogger)
…或者,通过在配置调用结束时提供块来完成
CRUDE.configure(baseURL: "https://mysite.com/api", headers: kDefaultHeaders) { response in
print("CRUDE response: \(response)")
}
您也可以在配置了CRUDE之后使用}CRUDE.setResponseLoggingBlock
函数设置响应日志块。您甚至可以使用}CRUDE.setRequestLoggingBlock
函数在请求之前设置一个记录器。例如
CRUDE.setRequestLoggingBlock() { method, path, params, headers in
print("CRUDE request \(method) \(path)")
params?.forEach { print("\($0)=\($1)") }
print("HTTP Headers:")
headers.forEach { print("\($0)=\($1)") }
}
如果您不提供日志块,可以通过将}
CRUDE.shouldUseDefaultLogger
设置为}true
来使用默认记录器。
尽管CRUDE旨在与结构体一起使用,但它也可以与类和甚至是管理对象(在一定程度上)一起使用。
您需要做的第一件事是导入}CRUDE_Futures
和}SwiftyJSON
。然后通过应用任何数量的协议来声明您打算如何使用您的模型。对于只读模型,您可能只需要使用}CRUDEReadable
,或者如果您希望一次检索多个项目,也许可以添加}CRUDEEnumeratable
。数据实体可以通过使用}CRUDECreatable
和}CRUDEDeletable
来创建和销毁。如果您想修改实体并要求服务器符合您创建的新现实,您可以使用}CRUDEUpdatable
。
所有这些不同的协议都符合}CRUDERequestable
,需要模型设置其}path
字符串,通知CRUDE这些模型通常在哪里可以找到。例如}static let path = "people"
将告诉CRUDE对“https://mysite.com/api/people”发送请求。模型还可以设置一个}objectKey
字符串,以在返回的JSON将所有珍贵的属性都封装在一个字典中时使用。如果您在模型中不设置此值,它将默认为}nil
。
为了将一些JSON轻松地转换为有用的模型,需要它是}JSONConvertable
的。这意味着可以通过传递一个}JSON
对象来初始化它。以下是一个Person模型对象的示例
struct Person: CRUDEReadable {
static let path: String = "person"
let id: Int
let firstName: String
let lastName: String
let favoriteColor: String?
init(_ json: JSON) {
id = json["id_Number"].intValue
firstName = json["first_name"].stringValue
lastName = json["last_name"].stringValue
favoriteColor = json["favorite_color"].string
}
}
是的,您确实需要执行一对一映射,但这可能会带来回报。比如说,您有一个}Household
实体,它拥有几个人员。它可以像这样映射其}people
属性
people = json["people"].array?.map { Person($0) }.sort { $0.firstName < $1.firstName} ?? []
看看这个!我们甚至在一行内按名字的顺序对它们进行了排序!如果您打算通过}Household
而不是}Person
来制作所有请求并进行映射,您可以让}Person
只遵循}JSONConvertable
。
如果您有一个将要执行所有操作的模型,您可以使用}CRUDEMappable
来替代列举所有五个。
虽然创建和枚举模型不需要}
id
属性,但它对于}CRUDEReadable
、}CRUDEUpdatable
和}CRUDEDeletable
来说是必需的。这样做是为了自动推断URL路径。例如,请求ID为}12345
的人员将发送到“https://mysite.com/api/people/12345”。您可以覆盖此路径(稍后解释),但}id
的要求仍然存在。
为了更新远程数据库中的实体,它需要是}JSONAttributable
的。这意味着它的属性具有逆映射。
var attributes: [String : AnyObject?] {
return [
"id_Number": id,
"first_name": firstName,
"last_name": lastName,
"favorite_color": favoriteColor
]
}
请注意,}attributes
包含可选对象。JSONAttributable
提供了一个名为}nullifiedAttributes
的computed属性,它将为任何nil属性提供一个值为}NSNull
的值,例如可能}favoriteColor
。它还提供了一个名为}valuedAttributes
的computed属性,它可以自动删除没有值的属性。
在}Household
模型示例中,实体会在计算}attributes
时包含}"people": people.map { $0.nullifiedAttributes }
。
CRUDE假设您的API只更新其接收到的参数的属性,因此对于已设置为nil的属性需要NSNull值。如果不是这样(没有新闻就是没有新闻),那么您可以使用
valuedAttributes
并在更新时指定该规定:thisPerson.updateOnServer(valuedAttributesOnly: true)
那么API调用看起来是什么样子的呢?某些协议提供静态请求,某些提供实例请求,还有一些两者都提供。例如,如果您想获取具有12345编号的新人
Person.readFromServerWithId(12345)
…或者如果您已经有这个人,只是想确保您有最新版本
self.person.readFromServer()
请注意,在发出这些请求时,CRUDE不会修改实体。它会在完成后提供一个新的实体。异步调用使用BrightFutures语法处理,因此检索最新的个人版本可能如下所示
self.person.readFromServer().onSuccess { person in
self.person = person
}.onFailure { error in
print(error)
}.onComplete { _ in
self.refreshControl?.endRefreshing()
}
请注意,虽然.onComplete
提供了一个原始的Result
,如果您只是想要在这个块中执行清理代码,可以将其丢弃。在这个例子中,我们根据加载是否成功更新视图的refreshControl。
可映射协议为您提供了方便的请求,您可以根据意图显式调用,但您仍然可以访问它们使用的底层请求。最基本的方法是request
,它将给您一个包含JSON对象的Future。
CRUDE.request(.GET, CRUDE.baseURL + "person/\(self.person.id)")
如果您想直接控制请求,但不想麻烦地将JSON转换为实体,可以使用requestObject
来获取单个实体或requestObjectsArray
来获取实体数组。只需确保将返回的Future转换为所需的类型。
let request = CRUDE.requestObjectsArray(.GET, CRUDE.baseURL + "person/\(self.person.id)", parameters: queryItems) as Future<[Person], NSError>
request.onSuccess { people in
self.household.people = people
}
Okay
是一个空对象,唯一目的是为了在.onSuccess
中返回一些东西。这用于任何是CRUDEDeletable
的模型,因为DELETE请求不应该返回任何可映射的JSON。
如果您想发出请求,但对服务器返回的内容不感兴趣,可以使用CRUDE.requestForSuccess
,它也会返回一个Okay
。
CRUDE假设了一个简单的API结构,其中与模型相关的请求都是这样进行的。如果您的baseURL是“https://mysite.com/api/”,那么针对Person
对象的请求应该如下所示
如前所述,所有这些都可以使用path
自动完成。但是,您的API可能并不那么简单。可能更新是“https://mysite.com/api/household/people/12345”,而检索特定的人来自“https://mysite.com/api/person/12345”。五个协议中的每一个都有针对该类型请求的特定路径,因此在这种情况下,您会设置updatePath
和readPath
的值,让path
处理其他三个情况。
您可以静态设置特定的路径
static let enumeratePath = CRUDE.baseURL + "/household/people"
…或者动态设置
static var enumeratePath: String {
return CRUDE.baseURL + "/households/\(householdID)/people"
}
始终设置
path
,如果有任何边缘情况,请提供特定的路径。
如果您想能够控制请求流量本身,请使用CRUDERequest
对象而不是CRUDE
静态方法。
初始化一个CRUDERequest
实例的方式与您使用请求函数的方式相同。必须提供urlString
,并且可以选择提供parameters
和/或headers
。要执行请求,您有三个选项,非常类似于三个基本的CRUDE
静态函数……
makeRequestForJSON
代替request
makeRequestForObject<T: JSONConvertable>
代替requestObject<T: JSONConvertable>
makeRequestForObjectsArray<T: JSONConvertable>
代替requestObjectsArray<T: JSONConvertable>
在请求进行中时,您可以使用pauseRequest()
来暂时中断。然后您可以稍后调用resumeRequest()
,或者放弃《code>cancelRequest。
您仍需要在您的AppDelegate中首先配置CRUDE。
如果您还想要自己完成更多的工作……那么您可能不应该使用这个Pod。额外的便捷性对您来说已经没有意义了。您也是穿上溜冰鞋去慢跑吗?您最喜欢的餐厅是The Melting Pot吗,在那里您租厨房用具来自己做饭?当然他们帮您买了一些杂货,但实际上您做了大部分的工作。
请使用Alamofire、SwiftyJSON和BrightFutures。这就是我用来组装一系列您可能不会使用到的工具的方式。
Jason Welch, [email protected]
CRUDE-Futures遵循MIT许可。有关更多信息,请参阅LICENSE文件。