测试已测试 | ✓ |
语言语言 | SwiftSwift |
许可 | MIT |
发布上次发布 | 2016年12月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✗ |
由 Peter Siegesmund 维护。
依赖关系 | |
CryptoSwift | ~> 0.6.6 |
SwiftWebSocket | ~> 2.6.5 |
XCGLogger | >= 0 |
MIT
使用 CocoaPods。将以下行添加到您的 Podfile 中
pod "SwiftDDP", "~> 0.4.0"
import SwiftDDP
Meteor.client.allowSelfSignedSSL = true // Connect to a server that uses a self signed ssl certificate
Meteor.client.logLevel = .Info // Options are: .Verbose, .Debug, .Info, .Warning, .Error, .Severe, .None
// Meteor.connect will automatically connect and will sign in using
// a stored login token if the client was previously signed in.
Meteor.connect("wss://todos.meteor.com/websocket") {
// do something after the client connects
}
使用电子邮件和密码登录。
Meteor.loginWithPassword("[email protected]", password: "********") { result, error in
// do something after login
}
使用用户名和密码登录。
Meteor.loginWithUsername("swiftddp", password: "********") { result, error in
// do something after login
}
登出。
Meteor.logout() { result, error in
// do something after logout
}
客户端还会在用户登录和断开连接时,以及连接失败事件期间发布通知。
// Notification name (a string global variable)
DDP_USER_DID_LOGIN
DDP_USER_DID_LOGOUT
//Websocket/DDP connection failure events
DDP_WEBSOCKET_CLOSE
DDP_WEBSOCKET_ERROR
DDP_DISCONNECTED
DDP_FAILED
// Example
NSNotificationCenter.defaultCenter().addObserver(self, selector: "userDidLogin", name: DDP_USER_DID_LOGIN, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "userDidLogout", name: DDP_USER_DID_LOGOUT, object: nil)
func userDidLogin() {
print("The user just signed in!")
}
func userDidLogout() {
print("The user just signed out!")
}
Meteor.subscribe("todos")
Meteor.subscribe("todos") {
// Do something when the todos subscription is ready
}
Meteor.subscribe("todos", [1,2,3,4]) {
// Do something when the todos subscription is ready
}
// Suppose you want to subscribe to a list of all cities and towns near a specific major city
// Subscribe to cities near Boston
let id1 = Meteor.subscribe("cities", ["lat": 42.358056 ,"lon": -71.063611]) {
// You are now subscribed to cities associated with the coordinates 42.358056, -71.063611
// id1 contains a key that allows you to cancel the subscription associated with
// the parameters ["lat": 42.358056 ,"lon": -71.063611]
}
// Subscribe to cities near Paris
let id2 = Meteor.subscribe("cities", ["lat": 48.8567, "lon": 2.3508]){
// You are now subscribed to cities associated with the coordinates 48.8567, 2.3508
// id2 contains a key that allows you to cancel the subscription associated with
// the parameters ["lat": 48.8567 ,"lon": 2.3508]
}
// Subscribe to cities near New York
let id3 = Meteor.subscribe("cities", ["lat": 40.7127, "lon": -74.0059]){
// You are now subscribed to cities associated with the coordinates 40.7127, -74.0059
// id3 contains a key that allows you to cancel the subscription associated with
// the parameters ["lat": 40.7127 ,"lon": -74.0059]
}
// When these subscriptions have completed, the collection associated with "cities" will now contain all
// documents returned from the three subscriptions
Meteor.unsubscribe(withId: id2)
// Your collection will now contain cities near Boston and New York, but not Paris
Meteor.unsubscribe("cities")
// You are now unsubscribed to all subscriptions associated with the publication "cities"
Meteor.call("foo", [1, 2, 3, 4]) { result, error in
// Do something with the method result
}
当向服务器方法传递参数时,参数对象必须使用NSJSONSerialization进行序列化
SwiftDDP 包含一个名为 MeteorCollection 的类,它提供了一个简单的、短暂的基于字典的持久化。MeteorCollection 存储从 MeteorDocument 继承的对象。创建一个集合就像
class List: MeteorDocument {
var collection:String = "lists"
var name:String?
var userId:String?
}
let lists = MeteorCollection<List>(name: "lists") // As with Meteorjs, the name is the name of the server-side collection
Meteor.subscribe("lists")
对于客户端的插入、更新和删除操作
let list = List(id: Meteor.client.getId(), fields: ["name": "foo"])
// Insert the object on both the client and server.
lists.insert(list)
// Update the object on both the client and server
list.name = "bar"
lists.update(list)
// Remove the object on both the client and server
lists.remove(list)
对于每个操作,如果服务器返回错误,则将在客户端执行操作,并回滚。
以下模式可用于创建由任何数据存储支持的自定义集合
在这个例子中,我们将创建一个简单的集合来存储联系人列表。我们首先会创建一个表示联系人的对象。该对象有四个属性和一个名为 update 的方法,该方法将 fields NSDictionary 映射到结构体属性。创建对象和执行更新时都会调用 update 方法。Meteor 总是传输一个 id 来标识应添加、更新或删除的对象,因此表示 Meteor 文档的对象必须始终具有一个id字段。在这里,我们坚持使用 MongoDB 的命名约定,将我们的id 命名为 _id。
struct Contact {
var _id:String?
var name:String?
var phone:String?
var email:String?
init(id:String, fields:NSDictionary?) {
self._id = id
update(fields)
}
mutating func update(fields:NSDictionary?) {
if let name = fields?.valueForKey("name") as? String {
self.name = name
}
if let phone = fields?.valueForKey("phone") as? String {
self.phone = phone
}
if let email = fields?.valueForKey("email") as? String {
self.email = email
}
}
}
接下来,我们将创建用于存储联系人并提供响应服务器端文档和订阅集更改的逻辑的集合类。SwiftDDP 包含一个名为 AbstractCollection 的抽象类,可以用于构建自定义集合。从 AbstractCollection 继承允许你覆盖在服务器事件上调用时调用的三个方法:documentWasAdded、documentWasChanged 和 documentWasRemoved。
class UserCollection: AbstractCollection {
var contacts = [Contact]()
// Include any logic that needs to occur when a document is added to the collection on the server
override public func documentWasAdded(collection:String, id:String, fields:NSDictionary?) {
let user = User(id, fields)
users.append(user)
}
// Include any logic that needs to occur when a document is changed on the server
override public func documentWasChanged(collection:String, id:String, fields:NSDictionary?, cleared:[String]?) {
if let index = contacts.indexOf({ contact in return contact._id == id }) {
contact = contacts[index]
contact.update(fields)
contacts[index] = contact
}
}
// Include any logic that needs to occur when a document is removed on the server
override public func documentWasRemoved(collection:String, id:String) {
if let index = contacts.indexOf({ contact in return contact._id == id }) {
contacts[index] = nil
}
}
}
到目前为止,我们能够处理在服务器上添加、更改或删除的文档。但 UserCollection 类仍然缺少更改本地数据存储和服务器上的能力。我们将进行更改。在 UserCollection 类中,创建一个名为 insert 的方法。
class UserCollection: AbstractCollection {
/*
override public func documentWasAdded ...
override public func documentWasChanged ...
override public func documentWasRemoved ...
*/
public func insert(contact: Contact) {
// (1) save the document to the contacts array
contacts[contacts._id] = contact
// (2) now try to insert the document on the server
client.insert(self.name, document: [contacts.fields()]) { result, error in
// (3) However, if the server returns an error, reverse the action on the client by
// removing the document from the contacts collection
if error != nil {
self.contacts[contact._id] = nil
log.error("\(error!)")
}
}
}
}
该方法的几个关键部分是
创建更新和删除方法的操作同样简单,并且遵循与 insert 相同的模式。有关此处所示模式的更广泛示例,请参阅 MeteorCollection.swift。MeteorCollection 是一个适用于简单应用程序的内存集合实现。
版本 0.3.0 包含破坏性更改
unsubscribe(name:String)
了。现在它将返回您已退订的订阅的ID数组。欢迎拉取请求、功能请求和反馈。如果您在生产应用中使用SwiftDDP,请告诉我们。