merged documentation updates from CoreData branch
This commit is contained in:
parent
692a8c6968
commit
eb4fcdd6b1
|
@ -35,6 +35,10 @@ let log = XCGLogger(identifier: "DDP")
|
|||
public typealias DDPMethodCallback = (result:AnyObject?, error:DDPError?) -> ()
|
||||
public typealias DDPCallback = () -> ()
|
||||
|
||||
/**
|
||||
DDPClient is the base class for communicating with a server using the DDP protocol
|
||||
*/
|
||||
|
||||
public class DDPClient: NSObject {
|
||||
|
||||
// included for storing login id and token
|
||||
|
|
|
@ -20,23 +20,103 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
DDPEvents is a struct holder for callback closures that execute in response to
|
||||
websocket and Meteor lifecyle events. New closures can be assigned to public
|
||||
closures to modify the clients behavior in response to the trigger event.
|
||||
*/
|
||||
|
||||
public struct DDPEvents {
|
||||
|
||||
public var onWebsocketClose: ((code:Int, reason:String, clean:Bool) -> ())?
|
||||
public var onWebsocketError: (error:ErrorType) -> () = {error in log.error("websocket error \(error)")}
|
||||
/**
|
||||
onWebsocketClose executes when the websocket connection has closed
|
||||
|
||||
- parameter code: An integer value that provides the reason code for closing the websocket connection
|
||||
- parameter reason: A string describing the reason that the websocket was closed
|
||||
- parameter clean: A boolean value indicating if the websocket connection was closed cleanly
|
||||
*/
|
||||
|
||||
internal var onWebsocketClose: ((code:Int, reason:String, clean:Bool) -> ())?
|
||||
|
||||
/**
|
||||
onWebsocketError executes when the websocket connection returns an error.
|
||||
|
||||
- parameter error: An ErrorType object describing the error
|
||||
*/
|
||||
|
||||
internal var onWebsocketError: (error:ErrorType) -> () = {error in log.error("websocket error \(error)")}
|
||||
|
||||
/**
|
||||
onConnected executes when the client makes a DDP connection
|
||||
|
||||
- parameter session: A string session id
|
||||
*/
|
||||
|
||||
public var onConnected: (session:String) -> () = {session in log.info("connected with session: \(session)")}
|
||||
|
||||
/**
|
||||
onDisconnected executes when the client is disconnected
|
||||
*/
|
||||
|
||||
public var onDisconnected: () -> () = {log.debug("disconnected")}
|
||||
|
||||
/**
|
||||
onFailed executes when an attempt to make a DDP connection fails
|
||||
*/
|
||||
|
||||
public var onFailed: () -> () = {log.error("failed")}
|
||||
|
||||
// Data messages
|
||||
|
||||
/**
|
||||
onAdded executes when a document has been added to a local collection
|
||||
|
||||
- parameter collection: the string name of the collection to which the document belongs
|
||||
- parameter id: the string unique id that identifies the document on the server
|
||||
- parameter fields: an optional NSDictionary with the documents properties
|
||||
*/
|
||||
|
||||
public var onAdded: ((collection:String, id:String, fields:NSDictionary?) -> ())?
|
||||
|
||||
/**
|
||||
onChanged executes when the server sends an instruction to modify a local document
|
||||
|
||||
|
||||
- parameter collection: the string name of the collection to which the document belongs
|
||||
- parameter id: the string unique id that identifies the document on the server
|
||||
- parameter fields: an optional NSDictionary with the documents properties
|
||||
- parameter cleared: an optional array of string property names to delete
|
||||
*/
|
||||
|
||||
public var onChanged: ((collection:String, id:String, fields:NSDictionary?, cleared:NSArray?) -> ())?
|
||||
|
||||
/**
|
||||
onRemoved executes when the server sends an instruction to remove a document from the local collection
|
||||
|
||||
- parameter collection: the string name of the collection to which the document belongs
|
||||
- parameter id: the string unique id that identifies the document on the server
|
||||
*/
|
||||
|
||||
public var onRemoved: ((collection:String, id:String) -> ())?
|
||||
|
||||
// RPC Messages
|
||||
// public var onResult: (json: NSDictionary?, callback:(result:AnyObject?, error:AnyObject?) -> ()) -> () = {json, callback in callback(result: json, error:nil) }
|
||||
|
||||
/**
|
||||
onUpdated executes when the server sends a notification that all the consequences of a method call have
|
||||
been communicated to the client
|
||||
|
||||
- parameter methods: An array of method id strings
|
||||
*/
|
||||
|
||||
public var onUpdated: ((methods: [String]) -> ())?
|
||||
|
||||
/**
|
||||
onError executes when the client receives a DDP error message
|
||||
|
||||
- parameter message: A DDPError message describing the error
|
||||
*/
|
||||
|
||||
public var onError: ((message:DDPError) -> ())?
|
||||
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ extension NSDictionary {
|
|||
}
|
||||
|
||||
/**
|
||||
Extensions that provide core Meteor functionality and a cleaner API
|
||||
Extensions that provide an api for interacting with basic Meteor server-side services
|
||||
*/
|
||||
extension DDPClient {
|
||||
|
||||
|
|
|
@ -71,10 +71,13 @@ A struct to parse, encapsulate and facilitate handling of DDP message strings
|
|||
public struct DDPMessage {
|
||||
|
||||
/**
|
||||
The message properties in an NSDictionary
|
||||
The message's properties, stored as an NSDictionary
|
||||
*/
|
||||
public var json:NSDictionary!
|
||||
|
||||
/**
|
||||
Initialize a message struct, with a Json string
|
||||
*/
|
||||
public init(message:String) {
|
||||
|
||||
if let JSON = message.dictionaryValue() { json = JSON }
|
||||
|
@ -84,6 +87,9 @@ public struct DDPMessage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize a message struct, with a dictionary of strings
|
||||
*/
|
||||
public init(message:[String:String]) {
|
||||
json = message as NSDictionary
|
||||
}
|
||||
|
@ -101,7 +107,9 @@ public struct DDPMessage {
|
|||
// Computed variables
|
||||
//
|
||||
|
||||
// Returns the type of DDP message, or unhandled if it is not a DDP message
|
||||
/**
|
||||
Returns the DDP message type, of type DDPMessageType enum
|
||||
*/
|
||||
public var type:DDPMessageType {
|
||||
if let msg = message,
|
||||
let type = DDPMessageType(rawValue: msg) {
|
||||
|
@ -110,6 +118,9 @@ public struct DDPMessage {
|
|||
return DDPMessageType(rawValue: "unhandled")!
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a boolean value indicating if the message is an error message or not
|
||||
*/
|
||||
public var isError:Bool {
|
||||
if (self.type == .Error) { return true } // if message is a top level error ("msg"="error")
|
||||
if let _ = self.error { return true } // if message contains an error object, as in method or nosub
|
||||
|
@ -117,7 +128,7 @@ public struct DDPMessage {
|
|||
}
|
||||
|
||||
// Returns the root-level keys of the JSON object
|
||||
public var keys:[String] {
|
||||
internal var keys:[String] {
|
||||
return json.allKeys as! [String]
|
||||
}
|
||||
|
||||
|
@ -128,91 +139,165 @@ public struct DDPMessage {
|
|||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP message
|
||||
*/
|
||||
public var message:String? {
|
||||
get { return json["msg"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP session string
|
||||
*/
|
||||
public var session:String? {
|
||||
get { return json["session"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP version string
|
||||
*/
|
||||
public var version:String? {
|
||||
get { return json["version"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP support string
|
||||
*/
|
||||
public var support:String? {
|
||||
get { return json["support"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP message id string
|
||||
*/
|
||||
public var id:String? {
|
||||
get { return json["id"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP name string
|
||||
*/
|
||||
public var name:String? {
|
||||
get { return json["name"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP param string
|
||||
*/
|
||||
public var params:String? {
|
||||
get { return json["params"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP error object
|
||||
*/
|
||||
public var error:DDPError? {
|
||||
get { if let e = json["error"] as? NSDictionary { return DDPError(json:e) } else { return nil }}
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP collection name string
|
||||
*/
|
||||
public var collection:String? {
|
||||
get { return json["collection"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP fields dictionary
|
||||
*/
|
||||
public var fields:NSDictionary? {
|
||||
get { return json["fields"] as? NSDictionary }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional DDP cleared array. Contains an array of fields that should be removed
|
||||
*/
|
||||
public var cleared:[String]? {
|
||||
get { return json["cleared"] as? [String] }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional method name
|
||||
*/
|
||||
public var method:String? {
|
||||
get { return json["method"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional random seed JSON value (an arbitrary client-determined seed for pseudo-random generators)
|
||||
*/
|
||||
public var randomSeed:String? {
|
||||
get { return json["randomSeed"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional result object, containing the result of a method call
|
||||
*/
|
||||
public var result:AnyObject? {
|
||||
get { return json["result"] }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional array of ids passed to 'method', all of whose writes have been reflected in data messages)
|
||||
*/
|
||||
public var methods:[String]? {
|
||||
get { return json["methods"] as? [String] }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional array of id strings passed to 'sub' which have sent their initial batch of data
|
||||
*/
|
||||
public var subs:[String]? {
|
||||
get { return json["subs"] as? [String] }
|
||||
}
|
||||
|
||||
// Communication error properties
|
||||
/**
|
||||
The optional reason given for an error returned from the server
|
||||
*/
|
||||
public var reason:String? {
|
||||
get { return json["reason"] as? String }
|
||||
}
|
||||
|
||||
/**
|
||||
The optional original error message
|
||||
*/
|
||||
public var offendingMessage:String? {
|
||||
get { return json["offendingMessage"] as? String }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public struct DDPError {
|
||||
/**
|
||||
A struct encapsulating a DDP error message
|
||||
*/
|
||||
public struct DDPError: ErrorType {
|
||||
|
||||
private var json:NSDictionary?
|
||||
|
||||
/**
|
||||
The string error code
|
||||
*/
|
||||
public var error:String? { return json?["error"] as? String } // Error code
|
||||
|
||||
/**
|
||||
The detailed message given for an error returned from the server
|
||||
*/
|
||||
public var reason:String? { return json?["reason"] as? String }
|
||||
|
||||
/**
|
||||
The string providing error details
|
||||
*/
|
||||
public var details:String? { return json?["details"] as? String }
|
||||
|
||||
/**
|
||||
If the original message parsed properly, it is included here
|
||||
*/
|
||||
public var offendingMessage:String? { return json?["offendingMessage"] as? String }
|
||||
|
||||
/**
|
||||
Helper variable that returns true if the struct has both an error code and a reason
|
||||
*/
|
||||
|
||||
var isValid:Bool {
|
||||
if let _ = error { return true }
|
||||
if let _ = reason { return true }
|
||||
|
|
|
@ -20,7 +20,18 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
Struct to encapsulate the result of a Meteor method call
|
||||
*/
|
||||
public struct Result {
|
||||
|
||||
/**
|
||||
The result of the method call
|
||||
*/
|
||||
public var result:AnyObject?
|
||||
|
||||
/**
|
||||
An error object describing the server-side error, or nil if the method completed successfully
|
||||
*/
|
||||
public var error:DDPError?
|
||||
}
|
|
@ -26,8 +26,18 @@ protocol MeteorCollectionType {
|
|||
func documentWasRemoved(collection:String, id:String)
|
||||
}
|
||||
|
||||
/**
|
||||
Meteor is a class to simplify communicating with and consuming MeteorJS server services
|
||||
*/
|
||||
|
||||
public class Meteor {
|
||||
|
||||
/**
|
||||
client is a singleton instance of DDPClient
|
||||
*/
|
||||
|
||||
public static let client = Meteor.Client() // Client is a singleton object
|
||||
|
||||
private static var collections = [String:Any]()
|
||||
|
||||
|
||||
|
@ -74,6 +84,13 @@ public class Meteor {
|
|||
|
||||
//public static func unsubscribe(
|
||||
|
||||
/**
|
||||
Call a single function to establish a DDP connection, and login with email and password
|
||||
|
||||
- parameter url: The url to connect to
|
||||
- parameter email: A string email address associated with a Meteor account
|
||||
- parameter password: A string password
|
||||
*/
|
||||
public static func connect(url:String, email:String, password:String) {
|
||||
client.connect(url) { session in
|
||||
client.loginWithPassword(email, password: password) { result, error in
|
||||
|
@ -87,6 +104,9 @@ public class Meteor {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Meteor.Client is a subclass of DDPClient that facilitates interaction with the MeteorCollection class
|
||||
*/
|
||||
public class Client: DDPClient {
|
||||
|
||||
typealias SubscriptionCallback = () -> ()
|
||||
|
@ -96,7 +116,15 @@ public class Meteor {
|
|||
self.init()
|
||||
}
|
||||
|
||||
// Posts a notification when a document is added
|
||||
/**
|
||||
Calls the documentWasAdded method in the MeteorCollection subclass instance associated with the document
|
||||
collection
|
||||
|
||||
- parameter collection: the string name of the collection to which the document belongs
|
||||
- parameter id: the string unique id that identifies the document on the server
|
||||
- parameter fields: an optional NSDictionary with the documents properties
|
||||
*/
|
||||
|
||||
public override func documentWasAdded(collection:String, id:String, fields:NSDictionary?) {
|
||||
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType {
|
||||
NSOperationQueue.mainQueue().addOperationWithBlock() {
|
||||
|
@ -105,18 +133,16 @@ public class Meteor {
|
|||
}
|
||||
}
|
||||
|
||||
// Posts a notification when a document is removed
|
||||
public override func documentWasRemoved(collection:String, id:String) {
|
||||
// let message = NSDictionary(dictionary:["collection":collection, "id":id])
|
||||
// let userInfo = ["message":message]
|
||||
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType {
|
||||
NSOperationQueue.mainQueue().addOperationWithBlock() {
|
||||
meteorCollection.documentWasRemoved(collection, id: id)
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
Calls the documentWasChanged method in the MeteorCollection subclass instance associated with the document
|
||||
collection
|
||||
|
||||
- parameter collection: the string name of the collection to which the document belongs
|
||||
- parameter id: the string unique id that identifies the document on the server
|
||||
- parameter fields: an optional NSDictionary with the documents properties
|
||||
- parameter cleared: an optional array of string property names to delete
|
||||
*/
|
||||
|
||||
// Posts a notification when a document is changed
|
||||
public override func documentWasChanged(collection:String, id:String, fields:NSDictionary?, cleared:[String]?) {
|
||||
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType {
|
||||
NSOperationQueue.mainQueue().addOperationWithBlock() {
|
||||
|
@ -124,20 +150,46 @@ public class Meteor {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Calls the documentWasRemoved method in the MeteorCollection subclass instance associated with the document
|
||||
collection
|
||||
|
||||
- parameter collection: the string name of the collection to which the document belongs
|
||||
- parameter id: the string unique id that identifies the document on the server
|
||||
*/
|
||||
|
||||
public override func documentWasRemoved(collection:String, id:String) {
|
||||
if let meteorCollection = Meteor.collections[collection] as? MeteorCollectionType {
|
||||
NSOperationQueue.mainQueue().addOperationWithBlock() {
|
||||
meteorCollection.documentWasRemoved(collection, id: id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
MeteorCollection is a class created to provide a base class and api for integrating SwiftDDP with persistence stores. MeteorCollection
|
||||
should generally be subclassed, with the methods documentWasAdded, documentWasChanged and documentWasRemoved facilitating communicating
|
||||
with the datastore.
|
||||
*/
|
||||
public class MeteorCollection: NSObject, MeteorCollectionType {
|
||||
|
||||
internal var name:String
|
||||
internal let client = Meteor.client
|
||||
|
||||
// Alternative API to subclassing
|
||||
// Can also set these closures to modify behavior on added, changed, removed
|
||||
public var onAdded:((collection:String, id:String, fields:NSDictionary?) -> ())?
|
||||
public var onChanged:((collection:String, id:String, fields:NSDictionary?, cleared:[String]?) -> ())?
|
||||
public var onRemoved:((collection:String, id:String) -> ())?
|
||||
// public var onAdded:((collection:String, id:String, fields:NSDictionary?) -> ())?
|
||||
// public var onChanged:((collection:String, id:String, fields:NSDictionary?, cleared:[String]?) -> ())?
|
||||
// public var onRemoved:((collection:String, id:String) -> ())?
|
||||
|
||||
// Must use the constructor function to create the collection
|
||||
/**
|
||||
Initializes a MeteorCollection object
|
||||
|
||||
- parameter name: The string name of the collection (must match the name of the collection on the server)
|
||||
*/
|
||||
public init(name:String) {
|
||||
self.name = name
|
||||
super.init()
|
||||
|
@ -148,17 +200,24 @@ public class MeteorCollection: NSObject, MeteorCollectionType {
|
|||
Meteor.collections[name] = nil
|
||||
}
|
||||
|
||||
// Override these methods to subclass Collection
|
||||
/**
|
||||
Called when a document has been sent from the server. Always executes on the main queue
|
||||
|
||||
- parameter collection: the string name of the collection to which the document belongs
|
||||
- parameter id: the string unique id that identifies the document on the server
|
||||
- parameter fields: an optional NSDictionary with the documents properties
|
||||
*/
|
||||
|
||||
public func documentWasAdded(collection:String, id:String, fields:NSDictionary?) {
|
||||
if let added = onAdded { added(collection: collection, id: id, fields:fields) }
|
||||
// if let added = onAdded { added(collection: collection, id: id, fields:fields) }
|
||||
}
|
||||
|
||||
public func documentWasChanged(collection:String, id:String, fields:NSDictionary?, cleared:[String]?) {
|
||||
if let changed = onChanged { changed(collection:collection, id:id, fields:fields, cleared:cleared) }
|
||||
// if let changed = onChanged { changed(collection:collection, id:id, fields:fields, cleared:cleared) }
|
||||
}
|
||||
|
||||
public func documentWasRemoved(collection:String, id:String) {
|
||||
if let removed = onRemoved { removed(collection:collection, id:id) }
|
||||
// if let removed = onRemoved { removed(collection:collection, id:id) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue