blob: 9cb6aa7173cab6187da2532a4a7801e2b7921f53 [file] [log] [blame]
//
// UsergridClient.swift
// UsergridSDK
//
// Created by Robert Walsh on 9/3/15.
//
/*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*
*/
import Foundation
/**
The `UsergridClient` class is the base handler for making client connections to and managing relationships with Usergrid's API.
*/
public class UsergridClient: NSObject, NSCoding {
static let DEFAULT_BASE_URL = "https://api.usergrid.com"
// MARK: - Instance Properties -
lazy private var _requestManager: UsergridRequestManager = UsergridRequestManager(client: self)
/// The configuration object used by the client.
public let config: UsergridClientConfig
/// The application identifier.
public var appId : String { return config.appId }
/// The organization identifier.
public var orgId : String { return config.orgId }
/// The base URL that all calls will be made with.
public var baseUrl : String { return config.baseUrl }
/// The constructed URL string based on the `UsergridClient`'s `baseUrl`, `orgId`, and `appId`.
internal var clientAppURL : String { return "\(baseUrl)/\(orgId)/\(appId)" }
/// Whether or not the current user will be saved and restored from the keychain.
public var persistCurrentUserInKeychain: Bool {
get { return config.persistCurrentUserInKeychain }
set(persist) { config.persistCurrentUserInKeychain = persist }
}
/// The currently logged in `UsergridUser`.
internal(set) public var currentUser: UsergridUser? = nil {
didSet {
if persistCurrentUserInKeychain {
if let newUser = self.currentUser {
UsergridUser.saveCurrentUserKeychainItem(self,currentUser:newUser)
} else if oldValue != nil {
UsergridUser.deleteCurrentUserKeychainItem(self)
}
}
}
}
/// The `UsergridUserAuth` which consists of the token information from the `currentUser` property.
public var userAuth: UsergridUserAuth? { return currentUser?.auth }
/// The temporary `UsergridAuth` object that is set when calling the `UsergridClient.usingAuth()` method.
private var tempAuth: UsergridAuth? = nil
/// The application level `UsergridAppAuth` object. Can be set manually but must call `authenticateApp` to retrive token.
public var appAuth: UsergridAppAuth? {
get { return config.appAuth }
set(auth) { config.appAuth = auth }
}
/// The `UsergridAuthFallback` value used to determine what type of token will be sent, if any.
public var authFallback: UsergridAuthFallback {
get { return config.authFallback }
set(fallback) { config.authFallback = fallback }
}
// MARK: - Initialization -
/**
Initializes instances of `UsergridClient`.
- parameter orgId: The organization identifier.
- parameter appId: The application identifier.
- returns: The new instance of `UsergridClient`.
*/
public convenience init(orgId: String, appId:String) {
self.init(configuration:UsergridClientConfig(orgId: orgId, appId: appId))
}
/**
Initializes instances of `UsergridClient`.
- parameter orgId: The organization identifier.
- parameter appId: The application identifier.
- parameter baseUrl: The base URL that all calls will be made with.
- returns: The new instance of `UsergridClient`.
*/
public convenience init(orgId: String, appId:String, baseUrl:String) {
self.init(configuration:UsergridClientConfig(orgId: orgId, appId: appId, baseUrl:baseUrl))
}
/**
Initializes instances of `UsergridClient`.
- parameter configuration: The configuration for the client to be set up with.
- returns: The new instance of `UsergridClient`.
*/
public init(configuration:UsergridClientConfig) {
self.config = configuration
super.init()
if persistCurrentUserInKeychain {
self.currentUser = UsergridUser.getCurrentUserFromKeychain(self) // Attempt to get the current user from the saved keychain data.
}
UsergridDevice.sharedDevice.save(self)
}
// MARK: - NSCoding -
/**
NSCoding protocol initializer.
- parameter aDecoder: The decoder.
- returns: A decoded `UsergridClient` object.
*/
public required init?(coder aDecoder: NSCoder) {
guard let config = aDecoder.decodeObjectForKey("config") as? UsergridClientConfig
else {
self.config = UsergridClientConfig(orgId: "", appId: "")
super.init()
return nil
}
self.config = config
super.init()
if let currentUser = aDecoder.decodeObjectForKey("currentUser") as? UsergridUser {
self.currentUser = currentUser
} else {
if persistCurrentUserInKeychain {
self.currentUser = UsergridUser.getCurrentUserFromKeychain(self)
}
}
UsergridDevice.sharedDevice.save(self)
}
/**
NSCoding protocol encoder.
- parameter aCoder: The encoder.
*/
public func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.config, forKey: "config")
aCoder.encodeObject(self.currentUser, forKey: "currentUser")
}
// MARK: - Device Registration/Push Notifications -
/**
Sets the push token for the given notifier ID and performs a PUT request to update the shared `UsergridDevice` instance.
- parameter pushToken: The push token from Apple.
- parameter notifierID: The Usergrid notifier ID.
- parameter completion: The completion block.
*/
public func applyPushToken(pushToken: NSData, notifierID: String, completion: UsergridResponseCompletion? = nil) {
self.applyPushToken(UsergridDevice.sharedDevice, pushToken: pushToken, notifierID: notifierID, completion: completion)
}
/**
Sets the push token for the given notifier ID and performs a PUT request to update the given `UsergridDevice` instance.
- parameter device: The `UsergridDevice` object.
- parameter pushToken: The push token from Apple.
- parameter notifierID: The Usergrid notifier ID.
- parameter completion: The completion block.
*/
public func applyPushToken(device: UsergridDevice, pushToken: NSData, notifierID: String, completion: UsergridResponseCompletion? = nil) {
device.applyPushToken(pushToken, notifierID: notifierID)
device.save(self, completion: completion)
}
// MARK: - Authorization and User Management -
/**
Determines the `UsergridAuth` object that will be used for all outgoing requests made.
If there is a valid temporary `UsergridAuth` set by the functions `usingAuth` or `usingToken` it will return that.
If there is a `UsergridUser` logged in and the token of that user is valid then it will return that.
Otherwise, if the `authFallback` is `.App`, and the `UsergridAppAuth` of the client is set and the token is valid it will return that.
- returns: The `UsergridAuth` if one is found or nil if not.
*/
internal func authForRequests() -> UsergridAuth? {
var usergridAuth: UsergridAuth?
if let tempAuth = self.tempAuth where tempAuth.isValid {
usergridAuth = tempAuth
self.tempAuth = nil
} else if let userAuth = self.userAuth where userAuth.isValid {
usergridAuth = userAuth
} else if self.authFallback == .App, let appAuth = self.appAuth where appAuth.isValid {
usergridAuth = appAuth
}
return usergridAuth
}
/**
Sets the client's `tempAuth` property using the passed in `UsergridAuth`.
This will cause the next CRUD method performed by the client to use the `tempAuth` property once and will then reset.
- parameter auth: The `UsergridAuth` object to temporarily use for authentication.
- returns: `Self`
*/
public func usingAuth(auth:UsergridAuth) -> Self {
self.tempAuth = auth
return self
}
/**
Sets the client's `tempAuth` property using the passed in token.
This will cause the next CRUD method performed by the client to use the `tempAuth` property once and will then reset.
- parameter auth: The access token to temporarily use for authentication.
- returns: `Self`
*/
public func usingToken(token:String) -> Self {
self.tempAuth = UsergridAuth(accessToken: token)
return self
}
/**
Authenticates with the `UsergridAppAuth` that is contained this instance of `UsergridCient`.
- parameter completion: The completion block that will be called after authentication has completed.
*/
public func authenticateApp(completion: UsergridAppAuthCompletionBlock? = nil) {
guard let appAuth = self.appAuth
else {
let error = UsergridResponseError(errorName: "Invalid UsergridAppAuth.", errorDescription: "UsergridClient's appAuth is nil.")
completion?(auth: nil, error: error)
return
}
self.authenticateApp(appAuth, completion: completion)
}
/**
Authenticates with the `UsergridAppAuth` that is passed in.
- parameter auth: The `UsergridAppAuth` that will be authenticated.
- parameter completion: The completion block that will be called after authentication has completed.
*/
public func authenticateApp(appAuth: UsergridAppAuth, completion: UsergridAppAuthCompletionBlock? = nil) {
let request = UsergridRequest(method: .Post,
baseUrl: self.clientAppURL,
paths: ["token"],
auth: self.authForRequests(),
jsonBody: appAuth.credentialsJSONDict)
_requestManager.performAppAuthRequest(appAuth, request: request) { [weak self] (auth,error) in
self?.appAuth = auth
completion?(auth: auth, error: error)
}
}
/**
Authenticates with the `UsergridUserAuth` that is passed in.
- parameter auth: The `UsergridUserAuth` that will be authenticated.
- parameter completion: The completion block that will be called after authentication has completed.
*/
public func authenticateUser(userAuth: UsergridUserAuth, completion: UsergridUserAuthCompletionBlock? = nil) {
self.authenticateUser(userAuth, setAsCurrentUser:true, completion:completion)
}
/**
Authenticates with the `UsergridUserAuth` that is passed in.
- parameter auth: The `UsergridUserAuth` that will be authenticated.
- parameter setAsCurrentUser: If the authenticated user should be set as the `UsergridClient.currentUser`.
- parameter completion: The completion block that will be called after authentication has completed.
*/
public func authenticateUser(userAuth: UsergridUserAuth, setAsCurrentUser: Bool, completion: UsergridUserAuthCompletionBlock? = nil) {
let request = UsergridRequest(method: .Post,
baseUrl: self.clientAppURL,
paths: ["token"],
auth: self.authForRequests(),
jsonBody: userAuth.credentialsJSONDict)
_requestManager.performUserAuthRequest(userAuth, request: request) { [weak self] (auth,user,error) in
if setAsCurrentUser {
self?.currentUser = user
}
completion?(auth: auth, user: user, error: error)
}
}
/**
Changes the give `UsergridUser`'s current password with the shared instance of `UsergridClient`.
- parameter user: The user.
- parameter old: The old password.
- parameter new: The new password.
- parameter completion: The optional completion block.
*/
public func resetPassword(user: UsergridUser, old:String, new:String, completion:UsergridUserResetPasswordCompletion? = nil) {
guard let usernameOrEmail = user.usernameOrEmail
else {
completion?(error: UsergridResponseError(errorName: "Error resetting password.", errorDescription: "The UsergridUser object must contain a valid username or email to reset the password."), didSucceed: false)
return
}
let request = UsergridRequest(method: .Put,
baseUrl: self.clientAppURL,
paths: ["users",usernameOrEmail,"password"],
auth: self.authForRequests(),
jsonBody:["oldpassword":old,"newpassword":new])
_requestManager.performRequest(request, completion: { (response) -> Void in
completion?(error: response.error, didSucceed: response.statusCode == 200)
})
}
/**
Logs out the current user locally and remotely.
- parameter completion: The completion block that will be called after logout has completed.
*/
public func logoutCurrentUser(completion:UsergridResponseCompletion? = nil) {
guard let uuidOrUsername = self.currentUser?.uuidOrUsername,
let token = self.currentUser?.auth?.accessToken
else {
completion?(response:UsergridResponse(client: self, errorName: "Logout Failed.", errorDescription: "UsergridClient's currentUser is not valid."))
return
}
self.logoutUser(uuidOrUsername, token: token) { (response) -> Void in
if response.ok || response.error?.errorName == "auth_bad_access_token" {
self.currentUser?.auth = nil
self.currentUser = nil
}
completion?(response: response)
}
}
/**
Logs out the user remotely with the given tokens.
- parameter completion: The completion block that will be called after logout has completed.
*/
public func logoutUserAllTokens(uuidOrUsername:String, completion:UsergridResponseCompletion? = nil) {
self.logoutUser(uuidOrUsername, token: nil, completion: completion)
}
/**
Logs out a user with the give UUID or username using the shared instance of `UsergridCient`.
Passing in a token will log out the user for just that token. Passing in nil for the token will logout the user for all tokens.
- parameter completion: The completion block that will be called after logout has completed.
*/
public func logoutUser(uuidOrUsername:String, token:String?, completion:UsergridResponseCompletion? = nil) {
var paths = ["users",uuidOrUsername]
var queryParams: [String: String]?
if let accessToken = token {
paths.append("revoketoken")
queryParams = ["token": accessToken]
} else {
paths.append("revoketokens")
}
let request = UsergridRequest(method: .Put,
baseUrl: self.clientAppURL,
paths: paths,
auth: self.authForRequests(),
queryParams: queryParams)
self.sendRequest(request, completion: completion)
}
// MARK: - Generic Request Methods -
/**
Starts the `UsergridRequest` sending process.
- Note: This method should only be used when you construct your own `UsergridRequest` objects.
- parameter request: The `UsergridRequest` object to send.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func sendRequest(request:UsergridRequest, completion:UsergridResponseCompletion? = nil) {
_requestManager.performRequest(request, completion: completion)
}
// MARK: - GET -
/**
Gets a single `UsergridEntity` of a given type with a specific UUID/name.
- parameter type: The `UsergridEntity` type.
- parameter uuidOrName: The UUID or name of the `UsergridEntity`.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func GET(type: String, uuidOrName: String, completion: UsergridResponseCompletion? = nil) {
let request = UsergridRequest(method: .Get, baseUrl: self.clientAppURL, paths: [type,uuidOrName], auth:self.authForRequests())
self.sendRequest(request, completion: completion)
}
/**
Gets a group of `UsergridEntity` objects of a given type.
- parameter type: The `UsergridEntity` type.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func GET(type: String, completion: UsergridResponseCompletion? = nil) {
let request = UsergridRequest(method: .Get, baseUrl: self.clientAppURL, paths: [type], query: nil, auth: self.authForRequests())
self.sendRequest(request, completion: completion)
}
/**
Gets a group of `UsergridEntity` objects using a given query.
- parameter query: The query to use when gathering `UsergridEntity` objects.
- parameter queryCompletion: The optional completion block that will be called once the request has completed.
*/
public func GET(query: UsergridQuery, queryCompletion: UsergridResponseCompletion? = nil) {
guard let type = query.collectionName
else {
queryCompletion?(response: UsergridResponse(client:self, errorName: "Query collection name missing.", errorDescription: "Query collection name is missing."))
return
}
let request = UsergridRequest(method: .Get, baseUrl: self.clientAppURL, paths: [type], query: query, auth: self.authForRequests())
self.sendRequest(request, completion: queryCompletion)
}
// MARK: - PUT -
/**
Updates an `UsergridEntity` with the given type and UUID/name specified using the passed in jsonBody.
- parameter type: The `UsergridEntity` type.
- parameter uuidOrName: The UUID or name of the `UsergridEntity`.
- parameter jsonBody: The valid JSON body dictionary to update the `UsergridEntity` with.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func PUT(type: String, uuidOrName: String, jsonBody:[String:AnyObject], completion: UsergridResponseCompletion? = nil) {
let request = UsergridRequest(method: .Put,
baseUrl: self.clientAppURL,
paths: [type,uuidOrName],
auth: self.authForRequests(),
headers: UsergridRequest.JSON_CONTENT_TYPE_HEADER,
jsonBody: jsonBody)
self.sendRequest(request, completion: completion)
}
/**
Updates the passed in `UsergridEntity`.
- parameter entity: The `UsergridEntity` to update.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func PUT(entity: UsergridEntity, completion: UsergridResponseCompletion? = nil) {
PUT(entity.type, jsonBody: entity.jsonObjectValue, completion: completion)
}
/**
Updates an `UsergridEntity` with the given type using the jsonBody where the UUID/name is specified inside of the jsonBody.
- Note: The `jsonBody` must contain a valid value for either `uuid` or `name` keys.
- parameter type: The `UsergridEntity` type.
- parameter jsonBody: The valid JSON body dictionary to update the `UsergridEntity` with.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func PUT(type: String, jsonBody:[String:AnyObject], completion: UsergridResponseCompletion? = nil) {
guard let uuidOrName = (jsonBody[UsergridEntityProperties.UUID.stringValue] ?? jsonBody[UsergridEntityProperties.Name.stringValue]) as? String
else {
completion?(response: UsergridResponse(client:self, errorName: "jsonBody not valid.", errorDescription: "The `jsonBody` must contain a valid value for either `uuid` or `name`."))
return
}
let request = UsergridRequest(method: .Put,
baseUrl: self.clientAppURL,
paths: [type,uuidOrName],
auth: self.authForRequests(),
headers: UsergridRequest.JSON_CONTENT_TYPE_HEADER,
jsonBody: jsonBody)
self.sendRequest(request, completion: completion)
}
/**
Updates the entities that fit the given query using the passed in jsonBody.
- Note: The query parameter must have a valid `collectionName` before calling this method.
- parameter query: The query to use when filtering what entities to update.
- parameter jsonBody: The valid JSON body dictionary to update with.
- parameter queryCompletion: The optional completion block that will be called once the request has completed.
*/
public func PUT(query: UsergridQuery, jsonBody:[String:AnyObject], queryCompletion: UsergridResponseCompletion? = nil) {
guard let type = query.collectionName
else {
queryCompletion?(response: UsergridResponse(client:self, errorName: "Query collection name invalid.", errorDescription: "Query is missing a collection name."))
return
}
let request = UsergridRequest(method: .Put,
baseUrl: self.clientAppURL,
paths: [type],
query: query,
auth: self.authForRequests(),
headers: UsergridRequest.JSON_CONTENT_TYPE_HEADER,
jsonBody: jsonBody)
self.sendRequest(request, completion: queryCompletion)
}
// MARK: - POST -
/**
Creates and posts creates an `UsergridEntity`.
- parameter entity: The `UsergridEntity` to create.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func POST(entity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
let request = UsergridRequest(method: .Post,
baseUrl: self.clientAppURL,
paths: [entity.type],
auth: self.authForRequests(),
headers: UsergridRequest.JSON_CONTENT_TYPE_HEADER,
jsonBody: entity.jsonObjectValue)
self.sendRequest(request, completion: completion)
}
/**
Creates and posts an array of `UsergridEntity` objects.
- Note: Each `UsergridEntity` in the array much already have a type assigned and must be the same.
- parameter entities: The `UsergridEntity` objects to create.
- parameter entitiesCompletion: The optional completion block that will be called once the request has completed.
*/
public func POST(entities:[UsergridEntity], entitiesCompletion: UsergridResponseCompletion? = nil) {
guard let type = entities.first?.type
else {
entitiesCompletion?(response: UsergridResponse(client:self, errorName: "No type found.", errorDescription: "The first entity in the array had no type found."))
return
}
POST(type, jsonBodies: entities.map { return ($0).jsonObjectValue }, completion: entitiesCompletion)
}
/**
Creates and posts an `UsergridEntity` of the given type with the given jsonBody.
- parameter type: The `UsergridEntity` type.
- parameter jsonBody: The valid JSON body dictionary to use when creating the `UsergridEntity`.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func POST(type: String, jsonBody:[String:AnyObject], completion: UsergridResponseCompletion? = nil) {
let request = UsergridRequest(method: .Post,
baseUrl: self.clientAppURL,
paths: [type],
auth: self.authForRequests(),
headers: UsergridRequest.JSON_CONTENT_TYPE_HEADER,
jsonBody: jsonBody)
self.sendRequest(request, completion: completion)
}
/**
Creates and posts an array of `Entity` objects while assigning the given type to them.
- parameter type: The `UsergridEntity` type.
- parameter jsonBody: The valid JSON body dictionaries to use when creating the `UsergridEntity` objects.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func POST(type: String, jsonBodies:[[String:AnyObject]], completion: UsergridResponseCompletion? = nil) {
let request = UsergridRequest(method: .Post,
baseUrl: self.clientAppURL,
paths: [type],
auth: self.authForRequests(),
headers: UsergridRequest.JSON_CONTENT_TYPE_HEADER,
jsonBody: jsonBodies)
self.sendRequest(request, completion: completion)
}
/**
Creates and posts an `UsergridEntity` of the given type with a given name and the given jsonBody.
- parameter type: The `UsergridEntity` type.
- parameter name: The name of the `UsergridEntity`.
- parameter jsonBody: The valid JSON body dictionary to use when creating the `UsergridEntity`.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func POST(type: String, name: String, jsonBody:[String:AnyObject], completion: UsergridResponseCompletion? = nil) {
var jsonBodyWithName = jsonBody
jsonBodyWithName[UsergridEntityProperties.Name.stringValue] = name
let request = UsergridRequest(method: .Post,
baseUrl: self.clientAppURL,
paths: [type],
auth: self.authForRequests(),
headers: UsergridRequest.JSON_CONTENT_TYPE_HEADER,
jsonBody: jsonBodyWithName)
self.sendRequest(request, completion: completion)
}
// MARK: - DELETE -
/**
Destroys the passed `UsergridEntity`.
- Note: The entity object must have a `uuid` or `name` assigned.
- parameter entity: The `UsergridEntity` to delete.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func DELETE(entity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
guard let uuidOrName = entity.uuidOrName
else {
completion?(response: UsergridResponse(client:self, errorName: "No UUID or name found.", errorDescription: "The entity object must have a `uuid` or `name` assigned."))
return
}
DELETE(entity.type, uuidOrName: uuidOrName, completion: completion)
}
/**
Destroys the `UsergridEntity` objects that fit the given `UsergridQuery`.
- Note: The query parameter must have a valid `collectionName` before calling this method.
- parameter query: The query to use when filtering what entities to delete.
- parameter queryCompletion: The optional completion block that will be called once the request has completed.
*/
public func DELETE(query:UsergridQuery, queryCompletion: UsergridResponseCompletion? = nil) {
guard let type = query.collectionName
else {
queryCompletion?(response: UsergridResponse(client:self, errorName: "Query collection name invalid.", errorDescription: "Query is missing a collection name."))
return
}
let request = UsergridRequest(method: .Delete,
baseUrl: self.clientAppURL,
paths: [type],
query: query,
auth: self.authForRequests(),
headers: UsergridRequest.JSON_CONTENT_TYPE_HEADER)
self.sendRequest(request, completion: queryCompletion)
}
/**
Destroys the `UsergridEntity` of a given type with a specific UUID/name.
- parameter type: The `UsergridEntity` type.
- parameter uuidOrName: The UUID or name of the `UsergridEntity`.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func DELETE(type:String, uuidOrName: String, completion: UsergridResponseCompletion? = nil) {
let request = UsergridRequest(method: .Delete,
baseUrl: self.clientAppURL,
paths: [type,uuidOrName],
auth: self.authForRequests(),
headers: UsergridRequest.JSON_CONTENT_TYPE_HEADER)
self.sendRequest(request, completion: completion)
}
// MARK: - Connection Management -
/**
Connects the `UsergridEntity` objects via the relationship.
- parameter entity: The `UsergridEntity` that will contain the connection.
- parameter relationship: The relationship of the connection.
- parameter to: The `UsergridEntity` which is connected.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func connect(entity:UsergridEntity, relationship:String, to:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
guard let entityID = entity.uuidOrName,
let toID = to.uuidOrName
else {
completion?(response: UsergridResponse(client: self, errorName: "Invalid Entity Connection Attempt.", errorDescription: "One or both entities that are attempting to be connected do not contain a valid UUID or Name property."))
return
}
self.connect(entity.type, entityID: entityID, relationship: relationship, toType: to.type, toID: toID, completion: completion)
}
/**
Connects the entity objects via the relationship.
- parameter entityType: The entity type.
- parameter entityID: The entity UUID or name.
- parameter relationship: The relationship of the connection.
- parameter toType: The type of the entity you are connecting to.
- parameter toName: The name of the entity you are connecting to.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func connect(entityType:String, entityID:String, relationship:String, toType:String, toName: String, completion: UsergridResponseCompletion? = nil) {
self.connect(entityType, entityID: entityID, relationship: relationship, toType: toType, toID: toName, completion: completion)
}
/**
Connects the entity objects via the relationship.
- parameter entityType: The entity type.
- parameter entityID: The entity UUID or name.
- parameter relationship: The relationship of the connection.
- parameter toType: The optional type of the entity you are connecting to.
- parameter toID: The UUID of the entity you are connecting to.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func connect(entityType:String, entityID:String, relationship:String, toType:String?, toID: String, completion: UsergridResponseCompletion? = nil) {
var paths = [entityType,entityID,relationship]
if let toType = toType {
paths.append(toType)
}
paths.append(toID)
let request = UsergridRequest(method: .Post,
baseUrl: self.clientAppURL,
paths: paths,
auth: self.authForRequests())
self.sendRequest(request, completion: completion)
}
/**
Disconnects the `UsergridEntity` objects via the relationship.
- parameter entity: The `UsergridEntity` that contains the connection.
- parameter relationship: The relationship of the connection.
- parameter from: The `UsergridEntity` which is connected.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func disconnect(entity:UsergridEntity, relationship:String, from:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
guard let entityID = entity.uuidOrName,
let fromID = from.uuidOrName
else {
completion?(response: UsergridResponse(client: self, errorName: "Invalid Entity Disconnect Attempt.", errorDescription: "The connecting and connected entities must have a `uuid` or `name` assigned."))
return
}
self.disconnect(entity.type, entityID: entityID, relationship: relationship, fromType: from.type, fromID: fromID, completion: completion)
}
/**
Disconnects the entity objects via the relationship.
- parameter entityType: The entity type.
- parameter entityID: The entity UUID or name.
- parameter relationship: The relationship of the connection.
- parameter fromType: The type of the entity you are disconnecting from.
- parameter fromName: The name of the entity you are disconnecting from.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func disconnect(entityType:String, entityID:String, relationship:String, fromType:String, fromName: String, completion: UsergridResponseCompletion? = nil) {
self.disconnect(entityType, entityID: entityID, relationship: relationship, fromType: fromType, fromID: fromName, completion: completion)
}
/**
Disconnects the entity objects via the relationship.
- parameter entityType: The entity type.
- parameter entityID: The entity UUID or name.
- parameter relationship: The relationship of the connection.
- parameter fromType: The optional type of the entity you are disconnecting from.
- parameter toID: The UUID of the entity you are disconnecting from.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func disconnect(entityType:String, entityID:String, relationship:String, fromType:String?, fromID: String, completion: UsergridResponseCompletion? = nil) {
var paths = [entityType,entityID,relationship]
if let fromType = fromType {
paths.append(fromType)
}
paths.append(fromID)
let request = UsergridRequest(method: .Delete,
baseUrl: self.clientAppURL,
paths: paths,
auth: self.authForRequests())
self.sendRequest(request, completion: completion)
}
/**
Gets the connected entities for the given relationship.
- parameter entity: The entity that contains the connection.
- parameter relationship: The relationship of the connection.
- parameter query: The optional query.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func getConnections(direction:UsergridDirection, entity:UsergridEntity, relationship:String, query:UsergridQuery?, completion:UsergridResponseCompletion? = nil) {
guard let uuidOrName = entity.uuidOrName
else {
completion?(response: UsergridResponse(client: self, errorName: "Invalid Entity Get Connections Attempt.", errorDescription: "The entity must have a `uuid` or `name` assigned."))
return
}
self.getConnections(direction, type: entity.type, uuidOrName: uuidOrName, relationship: relationship, query:query, completion: completion)
}
/**
Gets the connected entities for the given relationship.
- parameter direction: The direction of the connection.
- parameter type: The entity type.
- parameter uuidOrName: The entity UUID or name.
- parameter relationship: The relationship of the connection.
- parameter query: The optional query.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func getConnections(direction:UsergridDirection, type:String, uuidOrName:String, relationship:String, query:UsergridQuery?, completion:UsergridResponseCompletion? = nil) {
let request = UsergridRequest(method: .Get,
baseUrl: self.clientAppURL,
paths: [type, uuidOrName, direction.connectionValue, relationship],
query: query,
auth: self.authForRequests())
self.sendRequest(request, completion: completion)
}
/**
Gets the connected entities for the given relationship.
- parameter direction: The direction of the connection.
- parameter uuid: The entity UUID.
- parameter relationship: The relationship of the connection.
- parameter query: The optional query.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func getConnections(direction:UsergridDirection, uuid:String, relationship:String, query:UsergridQuery?, completion:UsergridResponseCompletion? = nil) {
let request = UsergridRequest(method: .Get,
baseUrl: self.clientAppURL,
paths: [uuid, direction.connectionValue, relationship],
query: query,
auth: self.authForRequests())
self.sendRequest(request, completion: completion)
}
// MARK: - Asset Management -
/**
Uploads the asset and connects the data to the given `UsergridEntity`.
- parameter entity: The `UsergridEntity` to connect the asset to.
- parameter asset: The `UsergridAsset` to upload.
- parameter progress: The optional progress block that will be called to update the progress of the upload.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func uploadAsset(entity:UsergridEntity, asset:UsergridAsset, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetUploadCompletion? = nil) {
let assetRequest = UsergridAssetUploadRequest(baseUrl: self.clientAppURL,
paths: [entity.type,entity.uuidOrName!],
auth: self.authForRequests(),
asset: asset)
_requestManager.performAssetUpload(assetRequest, progress: progress) { [weak entity] (response, asset, error) -> Void in
entity?.asset = asset
completion?(response: response, asset: asset, error: error)
}
}
/**
Downloads the asset from the given `UsergridEntity`.
- parameter entity: The `UsergridEntity` to which the asset to.
- parameter contentType: The content type of the asset's data.
- parameter progress: The optional progress block that will be called to update the progress of the download.
- parameter completion: The optional completion block that will be called once the request has completed.
*/
public func downloadAsset(entity:UsergridEntity, contentType:String, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetDownloadCompletion? = nil) {
guard entity.hasAsset
else {
completion?(asset: nil, error: "Entity does not have an asset attached.")
return
}
let downloadAssetRequest = UsergridRequest(method: .Get,
baseUrl: self.clientAppURL,
paths: [entity.type,entity.uuidOrName!],
auth: self.authForRequests(),
headers: ["Accept":contentType])
_requestManager.performAssetDownload(contentType, usergridRequest: downloadAssetRequest, progress: progress, completion: { (asset, error) -> Void in
entity.asset = asset
completion?(asset: asset, error: error)
})
}
}