You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2016/02/16 14:15:35 UTC
[43/75] [partial] usergrid git commit: Initial commit of the Swift
SDK.
http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridClient.swift
----------------------------------------------------------------------
diff --git a/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridClient.swift b/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridClient.swift
new file mode 100644
index 0000000..cbb416f
--- /dev/null
+++ b/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridClient.swift
@@ -0,0 +1,875 @@
+//
+// 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)" }
+
+ /// The currently logged in `UsergridUser`.
+ internal(set) public var currentUser: UsergridUser? = nil {
+ didSet {
+ 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? {
+ set { config.appAuth = newValue }
+ get { return config.appAuth }
+ }
+
+ /// The `UsergridAuthFallback` value used to determine what type of token will be sent, if any.
+ public var authFallback: UsergridAuthFallback {
+ set { config.authFallback = newValue }
+ get { return config.authFallback }
+ }
+
+ // 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()
+ self.currentUser = UsergridUser.getCurrentUserFromKeychain(self) // Attempt to get the current user from the saved keychain data.
+ }
+
+ // 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 we didn't decode a current user, attempt to get the current user from the saved keychain data.
+ self.currentUser = UsergridUser.getCurrentUserFromKeychain(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)
+ PUT(UsergridDevice.DEVICE_ENTITY_TYPE, jsonBody: device.jsonObjectValue, 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 with an optional query.
+
+ - parameter type: The `UsergridEntity` type.
+ - parameter query: The optional query to use when gathering `UsergridEntity` objects.
+ - parameter completion: The optional completion block that will be called once the request has completed.
+ */
+ public func GET(type: String, query: UsergridQuery? = nil, completion: UsergridResponseCompletion? = nil) {
+ let request = UsergridRequest(method: .Get, baseUrl: self.clientAppURL, paths: [type], query: query, auth: self.authForRequests())
+ self.sendRequest(request, completion: completion)
+ }
+
+ // 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)
+ })
+ }
+}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridClientConfig.swift
----------------------------------------------------------------------
diff --git a/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridClientConfig.swift b/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridClientConfig.swift
new file mode 100644
index 0000000..c79b6b2
--- /dev/null
+++ b/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridClientConfig.swift
@@ -0,0 +1,142 @@
+//
+// UsergridClientConfig.swift
+// UsergridSDK
+//
+// Created by Robert Walsh on 10/5/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
+
+/**
+`UsergridClientConfig` is used when initializing `UsergridClient` objects.
+
+The `UsergridClientConfig` is meant for further customization of `UsergridClient` objects when needed.
+*/
+public class UsergridClientConfig : NSObject, NSCoding {
+
+ // MARK: - Instance Properties -
+
+ /// The organization identifier.
+ public var orgId : String
+
+ /// The application identifier.
+ public var appId : String
+
+ /// The base URL that all calls will be made with.
+ public var baseUrl: String = UsergridClient.DEFAULT_BASE_URL
+
+ /// The `UsergridAuthFallback` value used to determine what type of token will be sent, if any.
+ public var authFallback: UsergridAuthFallback = .App
+
+ /**
+ The application level `UsergridAppAuth` object.
+
+ Note that you still need to call the authentication methods within `UsergridClient` once it has been initialized.
+ */
+ public var appAuth: UsergridAppAuth?
+
+ // MARK: - Initialization -
+
+ /**
+ Designated initializer for `UsergridClientConfig` objects.
+
+ - parameter orgId: The organization identifier.
+ - parameter appId: The application identifier.
+
+ - returns: A new instance of `UsergridClientConfig`.
+ */
+ public init(orgId: String, appId: String) {
+ self.orgId = orgId
+ self.appId = appId
+ }
+
+ /**
+ Convenience initializer for `UsergridClientConfig`.
+
+ - parameter orgId: The organization identifier.
+ - parameter appId: The application identifier.
+ - parameter baseUrl: The base URL that all calls will be made with.
+
+ - returns: A new instance of `UsergridClientConfig`.
+ */
+ public convenience init(orgId: String, appId: String, baseUrl:String) {
+ self.init(orgId:orgId,appId:appId)
+ self.baseUrl = baseUrl
+ }
+
+ /**
+ Convenience initializer for `UsergridClientConfig`.
+
+ - parameter orgId: The organization identifier.
+ - parameter appId: The application identifier.
+ - parameter baseUrl: The base URL that all calls will be made with.
+ - parameter authFallback: The `UsergridAuthFallback` value used to determine what type of token will be sent, if any.
+ - parameter appAuth: The application level `UsergridAppAuth` object.
+
+ - returns: A new instance of `UsergridClientConfig`.
+ */
+ public convenience init(orgId: String, appId: String, baseUrl:String, authFallback:UsergridAuthFallback, appAuth:UsergridAppAuth? = nil) {
+ self.init(orgId:orgId,appId:appId,baseUrl:baseUrl)
+ self.authFallback = authFallback
+ self.appAuth = appAuth
+ }
+
+ // MARK: - NSCoding -
+
+ /**
+ NSCoding protocol initializer.
+
+ - parameter aDecoder: The decoder.
+
+ - returns: A decoded `UsergridUser` object.
+ */
+ public required init?(coder aDecoder: NSCoder) {
+ guard let appId = aDecoder.decodeObjectForKey("appId") as? String,
+ let orgId = aDecoder.decodeObjectForKey("orgId") as? String,
+ let baseUrl = aDecoder.decodeObjectForKey("baseUrl") as? String
+ else {
+ self.appId = ""
+ self.orgId = ""
+ super.init()
+ return nil
+ }
+ self.appId = appId
+ self.orgId = orgId
+ self.baseUrl = baseUrl
+ self.appAuth = aDecoder.decodeObjectForKey("appAuth") as? UsergridAppAuth
+ self.authFallback = UsergridAuthFallback(rawValue:aDecoder.decodeIntegerForKey("authFallback")) ?? .App
+ super.init()
+ }
+
+ /**
+ NSCoding protocol encoder.
+
+ - parameter aCoder: The encoder.
+ */
+ public func encodeWithCoder(aCoder: NSCoder) {
+ aCoder.encodeObject(self.appId, forKey: "appId")
+ aCoder.encodeObject(self.orgId, forKey: "orgId")
+ aCoder.encodeObject(self.baseUrl, forKey: "baseUrl")
+ aCoder.encodeObject(self.appAuth, forKey: "appAuth")
+ aCoder.encodeInteger(self.authFallback.rawValue, forKey: "authFallback")
+ }
+}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridDevice.swift
----------------------------------------------------------------------
diff --git a/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridDevice.swift b/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridDevice.swift
new file mode 100644
index 0000000..c08fcf6
--- /dev/null
+++ b/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridDevice.swift
@@ -0,0 +1,168 @@
+//
+// UsergridDevice.swift
+// UsergridSDK
+//
+// Created by Robert Walsh on 10/23/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
+
+#if !os(OSX)
+import UIKit
+#endif
+
+#if os(watchOS)
+import WatchKit
+#endif
+
+/**
+`UsergridDevice` is an `UsergridEntity` subclass that encapsulates information about the current device as well as stores information about push tokens and Usergrid notifiers.
+
+To apply push tokens for Usergrid notifiers use the `UsergridClient.applyPushToken` method.
+*/
+public class UsergridDevice : UsergridEntity {
+
+ /// The `UsergridDevice` type.
+ static let DEVICE_ENTITY_TYPE = "device"
+
+ // MARK: - Instance Properties -
+
+ /// Property helper method for the `UsergridDevice` objects `uuid`.
+ override public var uuid: String! { return super[UsergridEntityProperties.UUID.stringValue] as! String }
+
+ /// Property helper method for the `UsergridDevice` objects device model.
+ public var model: String { return super[UsergridDeviceProperties.Model.stringValue] as! String }
+
+ /// Property helper method for the `UsergridDevice` objects device platform.
+ public var platform: String { return super[UsergridDeviceProperties.Platform.stringValue] as! String }
+
+ /// Property helper method for the `UsergridDevice` objects device operating system version.
+ public var osVersion: String { return super[UsergridDeviceProperties.OSVersion.stringValue] as! String }
+
+ // MARK: - Initialization -
+
+ /// The shared instance of `UsergridDevice`.
+ public static var sharedDevice: UsergridDevice = UsergridDevice()
+
+ /**
+ Designated Initializer for `UsergridDevice` objects
+
+ Most likely you will never need to create seperate instances of `UsergridDevice`. Use of `UsergridDevice.sharedInstance` is recommended.
+
+ - returns: A new instance of `UsergridDevice`.
+ */
+ public init() {
+ var deviceEntityDict: [String:AnyObject] = [:]
+ deviceEntityDict[UsergridEntityProperties.EntityType.stringValue] = UsergridDevice.DEVICE_ENTITY_TYPE
+ deviceEntityDict[UsergridEntityProperties.UUID.stringValue] = UsergridDevice.usergridDeviceUUID()
+
+ #if os(watchOS)
+ deviceEntityDict[UsergridDeviceProperties.Model.stringValue] = WKInterfaceDevice.currentDevice().model
+ deviceEntityDict[UsergridDeviceProperties.Platform.stringValue] = WKInterfaceDevice.currentDevice().systemName
+ deviceEntityDict[UsergridDeviceProperties.OSVersion.stringValue] = WKInterfaceDevice.currentDevice().systemVersion
+ #elseif os(iOS) || os(tvOS)
+ deviceEntityDict[UsergridDeviceProperties.Model.stringValue] = UIDevice.currentDevice().model
+ deviceEntityDict[UsergridDeviceProperties.Platform.stringValue] = UIDevice.currentDevice().systemName
+ deviceEntityDict[UsergridDeviceProperties.OSVersion.stringValue] = UIDevice.currentDevice().systemVersion
+ #elseif os(OSX)
+ deviceEntityDict[UsergridDeviceProperties.Model.stringValue] = "Mac"
+ deviceEntityDict[UsergridDeviceProperties.Platform.stringValue] = "OSX"
+ deviceEntityDict[UsergridDeviceProperties.OSVersion.stringValue] = NSProcessInfo.processInfo().operatingSystemVersionString
+ #endif
+
+ super.init(type: UsergridDevice.DEVICE_ENTITY_TYPE, propertyDict: deviceEntityDict)
+ }
+
+ /**
+ The required public initializer for `UsergridEntity` subclasses.
+
+ - parameter type: The type associated with the `UsergridEntity` object.
+ - parameter name: The optional name associated with the `UsergridEntity` object.
+ - parameter propertyDict: The optional property dictionary that the `UsergridEntity` object will start out with.
+
+ - returns: A new `UsergridDevice` object.
+ */
+ required public init(type: String, name: String?, propertyDict: [String : AnyObject]?) {
+ super.init(type: type, name: name, propertyDict: propertyDict)
+ }
+
+ // MARK: - NSCoding -
+
+ /**
+ NSCoding protocol initializer.
+
+ - parameter aDecoder: The decoder.
+
+ - returns: A decoded `UsergridUser` object.
+ */
+ required public init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ }
+
+ /**
+ NSCoding protocol encoder.
+
+ - parameter aCoder: The encoder.
+ */
+ public override func encodeWithCoder(aCoder: NSCoder) {
+ super.encodeWithCoder(aCoder)
+ }
+
+ /**
+ Subscript for the `UsergridDevice` class. Note that all of the `UsergridDeviceProperties` are immutable.
+
+ - Warning: When setting a properties value must be a valid JSON object.
+
+ - Example usage:
+ ```
+ let uuid = usergridDevice["uuid"]
+ ```
+ */
+ override public subscript(propertyName: String) -> AnyObject? {
+ get {
+ return super[propertyName]
+ }
+ set(propertyValue) {
+ if UsergridDeviceProperties.fromString(propertyName) == nil {
+ super[propertyName] = propertyValue
+ }
+ }
+ }
+
+ // MARK: - Push Token Handling -
+
+ /**
+ Sets the push token for the given notifier ID.
+
+ This does not perform any API requests to update on Usergrid, rather it will just set the information in the `UsergridDevice` instance.
+
+ In order to set the push token and perform an API request, use `UsergridClient.applyPushToken`.
+
+ - parameter pushToken: The push token from Apple.
+ - parameter notifierID: The notifier ID.
+ */
+ internal func applyPushToken(pushToken: NSData, notifierID: String) {
+ self[notifierID + USERGRID_NOTIFIER_ID_SUFFIX] = pushToken.description.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>")).stringByReplacingOccurrencesOfString(" ", withString: "")
+ }
+}
+
+private let USERGRID_NOTIFIER_ID_SUFFIX = ".notifier.id"
http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridEntity.swift
----------------------------------------------------------------------
diff --git a/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridEntity.swift b/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridEntity.swift
new file mode 100644
index 0000000..4b6fe8f
--- /dev/null
+++ b/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridEntity.swift
@@ -0,0 +1,613 @@
+//
+// UsergridEntity.swift
+// UsergridSDK
+//
+// Created by Robert Walsh on 7/21/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
+import CoreLocation
+
+/**
+`UsergridEntity` is the base class that contains a single Usergrid entity.
+
+`UsergridEntity` maintains a set of accessor properties for standard Usergrid schema properties (e.g. name, uuid), and supports helper methods for accessing any custom properties that might exist.
+*/
+public class UsergridEntity: NSObject, NSCoding {
+
+ static private var subclassMappings: [String:UsergridEntity.Type] = [UsergridUser.USER_ENTITY_TYPE:UsergridUser.self,UsergridDevice.DEVICE_ENTITY_TYPE:UsergridDevice.self]
+
+ // MARK: - Instance Properties -
+
+ /// The property dictionary that stores the properties values of the `UsergridEntity` object.
+ private var properties: [String : AnyObject] {
+ didSet {
+ if let fileMetaData = properties.removeValueForKey(UsergridFileMetaData.FILE_METADATA) as? [String:AnyObject] {
+ self.fileMetaData = UsergridFileMetaData(fileMetaDataJSON: fileMetaData)
+ } else {
+ self.fileMetaData = nil
+ }
+ }
+ }
+
+ /// The `UsergridAsset` that contains the asset data.
+ public var asset: UsergridAsset?
+
+ /// The `UsergridFileMetaData` of this `UsergridEntity`.
+ private(set) public var fileMetaData : UsergridFileMetaData?
+
+ /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.EntityType`.
+ public var type: String { return self.getEntitySpecificProperty(.EntityType) as! String }
+
+ /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.UUID`.
+ public var uuid: String? { return self.getEntitySpecificProperty(.UUID) as? String }
+
+ /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.Name`.
+ public var name: String? { return self.getEntitySpecificProperty(.Name) as? String }
+
+ /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.Created`.
+ public var created: NSDate? { return self.getEntitySpecificProperty(.Created) as? NSDate }
+
+ /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.Modified`.
+ public var modified: NSDate? { return self.getEntitySpecificProperty(.Modified) as? NSDate }
+
+ /// Property helper method for the `UsergridEntity` objects `UsergridEntityProperties.Location`.
+ public var location: CLLocation? {
+ get { return self.getEntitySpecificProperty(.Location) as? CLLocation }
+ set { self[UsergridEntityProperties.Location.stringValue] = newValue }
+ }
+
+ /// Property helper method to get the UUID or name of the `UsergridEntity`.
+ public var uuidOrName: String? { return self.uuid ?? self.name }
+
+ /// Tells you if this `UsergridEntity` has a type of `user`.
+ public var isUser: Bool { return self is UsergridUser || self.type == UsergridUser.USER_ENTITY_TYPE }
+
+ /// Tells you if there is an asset associated with this entity.
+ public var hasAsset: Bool { return self.asset != nil || self.fileMetaData?.contentLength > 0 }
+
+ /// The JSON object value.
+ public var jsonObjectValue : [String:AnyObject] { return self.properties }
+
+ /// The string value.
+ public var stringValue : String { return NSString(data: try! NSJSONSerialization.dataWithJSONObject(self.jsonObjectValue, options: .PrettyPrinted), encoding: NSASCIIStringEncoding) as! String }
+
+ /// The description.
+ public override var description : String {
+ return "Properties of Entity: \(stringValue)."
+ }
+
+ /// The debug description.
+ public override var debugDescription : String {
+ return "Properties of Entity: \(stringValue)."
+ }
+
+ // MARK: - Initialization -
+
+ /**
+ Designated initializer for `UsergridEntity` objects
+
+ - parameter type: The type associated with the `UsergridEntity` object.
+ - parameter name: The optional name associated with the `UsergridEntity` object.
+ - parameter propertyDict: The optional property dictionary that the `UsergridEntity` object will start out with.
+
+ - returns: A new `UsergridEntity` object.
+ */
+ required public init(type:String, name:String? = nil, propertyDict:[String:AnyObject]? = nil) {
+ self.properties = propertyDict ?? [:]
+ super.init()
+ if self is UsergridUser {
+ self.properties[UsergridEntityProperties.EntityType.stringValue] = UsergridUser.USER_ENTITY_TYPE
+ } else if self is UsergridDevice {
+ self.properties[UsergridEntityProperties.EntityType.stringValue] = UsergridDevice.DEVICE_ENTITY_TYPE
+ } else {
+ self.properties[UsergridEntityProperties.EntityType.stringValue] = type
+ }
+ if let entityName = name {
+ self.properties[UsergridEntityProperties.Name.stringValue] = entityName
+ }
+ }
+
+ private func copyInternalsFromEntity(entity:UsergridEntity) {
+ self.properties = entity.properties
+ self.asset = entity.asset ?? self.asset
+ }
+
+
+ /**
+ Used for custom mapping subclasses to a given `Usergrid` type.
+
+ - parameter type: The type of the `Usergrid` object.
+ - parameter toSubclass: The subclass `UsergridEntity.Type` to map it to.
+ */
+ public static func mapCustomType(type:String,toSubclass:UsergridEntity.Type) {
+ UsergridEntity.subclassMappings[type] = toSubclass
+ }
+
+ /**
+ Class convenience constructor for creating `UsergridEntity` objects dynamically.
+
+ - parameter jsonDict: A valid JSON dictionary which must contain at the very least a value for the `type` key.
+
+ - returns: A `UsergridEntity` object provided that the `type` key within the dictionay exists. Otherwise nil.
+ */
+ public class func entity(jsonDict jsonDict: [String:AnyObject]) -> UsergridEntity? {
+ if let type = jsonDict[UsergridEntityProperties.EntityType.stringValue] as? String {
+ if let mapping = UsergridEntity.subclassMappings[type] {
+ return mapping.init(type: type,propertyDict:jsonDict)
+ } else {
+ return UsergridEntity(type:type, propertyDict:jsonDict)
+ }
+ } else {
+ return nil
+ }
+ }
+
+ /**
+ Class convenience constructor for creating multiple `UsergridEntity` objects dynamically.
+
+ - parameter entitiesJSONArray: An array which contains dictionaries that are used to create the `UsergridEntity` objects.
+
+ - returns: An array of `UsergridEntity`.
+ */
+ public class func entities(jsonArray entitiesJSONArray: [[String:AnyObject]]) -> [UsergridEntity] {
+ var entityArray : [UsergridEntity] = []
+ for entityJSONDict in entitiesJSONArray {
+ if let entity = UsergridEntity.entity(jsonDict:entityJSONDict) {
+ entityArray.append(entity)
+ }
+ }
+ return entityArray
+ }
+
+ // MARK: - NSCoding -
+
+ /**
+ NSCoding protocol initializer.
+
+ - parameter aDecoder: The decoder.
+
+ - returns: A decoded `UsergridUser` object.
+ */
+ required public init?(coder aDecoder: NSCoder) {
+ guard let properties = aDecoder.decodeObjectForKey("properties") as? [String:AnyObject]
+ else {
+ self.properties = [:]
+ super.init()
+ return nil
+ }
+ self.properties = properties
+ self.fileMetaData = aDecoder.decodeObjectForKey("fileMetaData") as? UsergridFileMetaData
+ self.asset = aDecoder.decodeObjectForKey("asset") as? UsergridAsset
+ super.init()
+ }
+
+ /**
+ NSCoding protocol encoder.
+
+ - parameter aCoder: The encoder.
+ */
+ public func encodeWithCoder(aCoder: NSCoder) {
+ aCoder.encodeObject(self.properties, forKey: "properties")
+ aCoder.encodeObject(self.fileMetaData, forKey: "fileMetaData")
+ aCoder.encodeObject(self.asset, forKey: "asset")
+ }
+
+ // MARK: - Property Manipulation -
+
+ /**
+ Subscript for the `UsergridEntity` class.
+
+ - Example usage:
+ ```
+ let propertyValue = usergridEntity["propertyName"]
+ usergridEntity["propertyName"] = propertyValue
+ ```
+ */
+ public subscript(propertyName: String) -> AnyObject? {
+ get {
+ if let entityProperty = UsergridEntityProperties.fromString(propertyName) {
+ return self.getEntitySpecificProperty(entityProperty)
+ } else {
+ let propertyValue = self.properties[propertyName]
+ if propertyValue === NSNull() { // Let's just return nil for properties that have been removed instead of NSNull
+ return nil
+ } else {
+ return propertyValue
+ }
+ }
+ }
+ set(propertyValue) {
+ if let value = propertyValue {
+ if let entityProperty = UsergridEntityProperties.fromString(propertyName) {
+ if entityProperty.isMutableForEntity(self) {
+ if entityProperty == .Location {
+ if let location = value as? CLLocation {
+ properties[propertyName] = [ENTITY_LATITUDE:location.coordinate.latitude,
+ ENTITY_LONGITUDE:location.coordinate.longitude]
+ } else if let location = value as? CLLocationCoordinate2D {
+ properties[propertyName] = [ENTITY_LATITUDE:location.latitude,
+ ENTITY_LONGITUDE:location.longitude]
+ } else if let location = value as? [String:Double] {
+ if let lat = location[ENTITY_LATITUDE], long = location[ENTITY_LONGITUDE] {
+ properties[propertyName] = [ENTITY_LATITUDE:lat,
+ ENTITY_LONGITUDE:long]
+ }
+ }
+ } else {
+ properties[propertyName] = value
+ }
+ }
+ } else {
+ properties[propertyName] = value
+ }
+ } else { // If the property value is nil we assume they wanted to remove the property.
+
+ // We set the value for this property to Null so that when a PUT is performed on the entity the property will actually be removed from the Entity on Usergrid
+ if let entityProperty = UsergridEntityProperties.fromString(propertyName){
+ if entityProperty.isMutableForEntity(self) {
+ properties[propertyName] = NSNull()
+ }
+ } else {
+ properties[propertyName] = NSNull()
+ }
+ }
+ }
+ }
+
+ /**
+ Updates a properties value for the given property name.
+
+ - parameter name: The name of the property.
+ - parameter value: The value to update to.
+ */
+ public func putProperty(name:String,value:AnyObject?) {
+ self[name] = value
+ }
+
+ /**
+ Updates a set of properties that are within the given properties dictionary.
+
+ - parameter properties: The property dictionary containing the properties names and values.
+ */
+ public func putProperties(properties:[String:AnyObject]) {
+ for (name,value) in properties {
+ self.putProperty(name, value: value)
+ }
+ }
+
+ /**
+ Removes the property for the given property name.
+
+ - parameter name: The name of the property.
+ */
+ public func removeProperty(name:String) {
+ self[name] = nil
+ }
+
+ /**
+ Removes the properties with the names within the propertyNames array
+
+ - parameter propertyNames: An array of property names.
+ */
+ public func removeProperties(propertyNames:[String]) {
+ for name in propertyNames {
+ self.removeProperty(name)
+ }
+ }
+
+ /**
+ Appends the given value to the end of the properties current value.
+
+ - parameter name: The name of the property.
+ - parameter value: The value or an array of values to append.
+ */
+ public func append(name:String, value:AnyObject) {
+ self.insertArray(name, values:value as? [AnyObject] ?? [value], index: Int.max)
+ }
+
+ /**
+ Inserts the given value at the given index within the properties current value.
+
+ - parameter name: The name of the property.
+ - parameter index: The index to insert at.
+ - parameter value: The value or an array of values to insert.
+ */
+ public func insert(name:String, value:AnyObject, index:Int = 0) {
+ self.insertArray(name, values:value as? [AnyObject] ?? [value], index: index)
+ }
+
+ /**
+ Inserts an array of property values at a given index within the properties current value.
+
+ - parameter name: The name of the property
+ - parameter index: The index to insert at.
+ - parameter values: The values to insert.
+ */
+ private func insertArray(name:String,values:[AnyObject], index:Int = 0) {
+ if let propertyValue = self[name] {
+ if let arrayValue = propertyValue as? [AnyObject] {
+ var arrayOfValues = arrayValue
+ if index > arrayValue.count {
+ arrayOfValues.appendContentsOf(values)
+ } else {
+ arrayOfValues.insertContentsOf(values, at: index)
+ }
+ self[name] = arrayOfValues
+ } else {
+ if index > 0 {
+ self[name] = [propertyValue] + values
+ } else {
+ self[name] = values + [propertyValue]
+ }
+ }
+ } else {
+ self[name] = values
+ }
+ }
+
+ /**
+ Removes the last value of the properties current value.
+
+ - parameter name: The name of the property.
+ */
+ public func pop(name:String) {
+ if let arrayValue = self[name] as? [AnyObject] where arrayValue.count > 0 {
+ var arrayOfValues = arrayValue
+ arrayOfValues.removeLast()
+ self[name] = arrayOfValues
+ }
+ }
+
+ /**
+ Removes the first value of the properties current value.
+
+ - parameter name: The name of the property.
+ */
+ public func shift(name:String) {
+ if let arrayValue = self[name] as? [AnyObject] where arrayValue.count > 0 {
+ var arrayOfValues = arrayValue
+ arrayOfValues.removeFirst()
+ self[name] = arrayOfValues
+ }
+ }
+
+ private func getEntitySpecificProperty(entityProperty: UsergridEntityProperties) -> AnyObject? {
+ var propertyValue: AnyObject? = nil
+ switch entityProperty {
+ case .UUID,.EntityType,.Name :
+ propertyValue = self.properties[entityProperty.stringValue]
+ case .Created,.Modified :
+ if let utcTimeStamp = self.properties[entityProperty.stringValue] as? Int {
+ propertyValue = NSDate(utcTimeStamp: utcTimeStamp.description)
+ }
+ case .Location :
+ if let locationDict = self.properties[entityProperty.stringValue] as? [String:Double], lat = locationDict[ENTITY_LATITUDE], long = locationDict[ENTITY_LONGITUDE] {
+ propertyValue = CLLocation(latitude: lat, longitude: long)
+ }
+ }
+ return propertyValue
+ }
+
+ // MARK: - CRUD Convenience Methods -
+
+ /**
+ Performs a GET on the `UsergridEntity` using the shared instance of `UsergridClient`.
+
+ - parameter completion: An optional completion block that, if successful, will contain the reloaded `UsergridEntity` object.
+ */
+ public func reload(completion: UsergridResponseCompletion? = nil) {
+ self.reload(Usergrid.sharedInstance, completion: completion)
+ }
+
+ /**
+ Performs a GET on the `UsergridEntity`.
+
+ - parameter client: The client to use when reloading.
+ - parameter completion: An optional completion block that, if successful, will contain the reloaded `UsergridEntity` object.
+ */
+ public func reload(client:UsergridClient, completion: UsergridResponseCompletion? = nil) {
+ if let uuidOrName = self.uuidOrName {
+ client.GET(self.type, uuidOrName: uuidOrName) { (response) -> Void in
+ if let responseEntity = response.entity {
+ self.copyInternalsFromEntity(responseEntity)
+ }
+ completion?(response: response)
+ }
+ } else {
+ completion?(response: UsergridResponse(client: client, errorName: "Entity cannot be reloaded.", errorDescription: "Entity has neither an UUID or specified."))
+ }
+ }
+
+ /**
+ Performs a PUT (or POST if no UUID is found) on the `UsergridEntity` using the shared instance of `UsergridClient`.
+
+ - parameter completion: An optional completion block that, if successful, will contain the updated/saved `UsergridEntity` object.
+ */
+ public func save(completion: UsergridResponseCompletion? = nil) {
+ self.save(Usergrid.sharedInstance, completion: completion)
+ }
+
+ /**
+ Performs a PUT (or POST if no UUID is found) on the `UsergridEntity`.
+
+ - parameter client: The client to use when saving.
+ - parameter completion: An optional completion block that, if successful, will contain the updated/saved `UsergridEntity` object.
+ */
+ public func save(client:UsergridClient, completion: UsergridResponseCompletion? = nil) {
+ if let _ = self.uuid { // If UUID exists we PUT otherwise POST
+ client.PUT(self, completion: { (response) -> Void in
+ if let responseEntity = response.entity {
+ self.copyInternalsFromEntity(responseEntity)
+ }
+ completion?(response: response)
+ })
+ } else {
+ client.POST(self, completion: { (response) -> Void in
+ if let responseEntity = response.entity {
+ self.copyInternalsFromEntity(responseEntity)
+ }
+ completion?(response: response)
+ })
+ }
+ }
+
+ /**
+ Performs a DELETE on the `UsergridEntity` using the shared instance of the `UsergridClient`.
+
+ - parameter completion: An optional completion block.
+ */
+ public func remove(completion: UsergridResponseCompletion? = nil) {
+ Usergrid.sharedInstance.DELETE(self, completion: completion)
+ }
+
+ /**
+ Performs a DELETE on the `UsergridEntity`.
+
+ - parameter client: The client to use when removing.
+ - parameter completion: An optional completion block.
+ */
+ public func remove(client:UsergridClient, completion: UsergridResponseCompletion? = nil) {
+ client.DELETE(self, completion: completion)
+ }
+
+ // MARK: - Asset Management -
+
+ /**
+ Uploads the given `UsergridAsset` and the data within it and creates an association between this `UsergridEntity` with the given `UsergridAsset` using the shared instance of `UsergridClient`.
+
+ - parameter asset: The `UsergridAsset` object to upload.
+ - parameter progress: An optional progress block to keep track of upload progress.
+ - parameter completion: An optional completion block.
+ */
+ public func uploadAsset(asset:UsergridAsset, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetUploadCompletion? = nil) {
+ Usergrid.sharedInstance.uploadAsset(self, asset: asset, progress:progress, completion:completion)
+ }
+
+ /**
+ Uploads the given `UsergridAsset` and the data within it and creates an association between this `UsergridEntity` with the given `UsergridAsset`.
+
+ - parameter client: The client to use when uploading.
+ - parameter asset: The `UsergridAsset` object to upload.
+ - parameter progress: An optional progress block to keep track of upload progress.
+ - parameter completion: An optional completion block.
+ */
+ public func uploadAsset(client:UsergridClient, asset:UsergridAsset, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetUploadCompletion? = nil) {
+ client.uploadAsset(self, asset: asset, progress:progress, completion:completion)
+ }
+
+ /**
+ Downloads the `UsergridAsset` that is associated with this `UsergridEntity` using the shared instance of `UsergridClient`.
+
+ - parameter contentType: The content type of the data to load.
+ - parameter progress: An optional progress block to keep track of download progress.
+ - parameter completion: An optional completion block.
+ */
+ public func downloadAsset(contentType:String, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetDownloadCompletion? = nil) {
+ Usergrid.sharedInstance.downloadAsset(self, contentType: contentType, progress:progress, completion: completion)
+ }
+
+ /**
+ Downloads the `UsergridAsset` that is associated with this `UsergridEntity`.
+
+ - parameter client: The client to use when uploading.
+ - parameter contentType: The content type of the data to load.
+ - parameter progress: An optional progress block to keep track of download progress.
+ - parameter completion: An optional completion block.
+ */
+ public func downloadAsset(client:UsergridClient, contentType:String, progress:UsergridAssetRequestProgress? = nil, completion:UsergridAssetDownloadCompletion? = nil) {
+ client.downloadAsset(self, contentType: contentType, progress:progress, completion: completion)
+ }
+
+ // MARK: - Connection Management -
+
+ /**
+ Creates a relationship between this `UsergridEntity` and the given entity using the shared instance of `UsergridClient`.
+
+ - parameter relationship: The relationship type.
+ - parameter toEntity: The entity to connect.
+ - parameter completion: An optional completion block.
+ */
+ public func connect(relationship:String, toEntity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
+ Usergrid.sharedInstance.connect(self, relationship: relationship, to: toEntity, completion: completion)
+ }
+
+ /**
+ Creates a relationship between this `UsergridEntity` and the given entity.
+
+ - parameter client: The client to use when connecting.
+ - parameter relationship: The relationship type.
+ - parameter toEntity: The entity to connect.
+ - parameter completion: An optional completion block.
+ */
+ public func connect(client:UsergridClient, relationship:String, toEntity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
+ client.connect(self, relationship: relationship, to: toEntity, completion: completion)
+ }
+
+ /**
+ Removes a relationship between this `UsergridEntity` and the given entity using the shared instance of `UsergridClient`.
+
+ - parameter relationship: The relationship type.
+ - parameter fromEntity: The entity to disconnect.
+ - parameter completion: An optional completion block.
+ */
+ public func disconnect(relationship:String, fromEntity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
+ Usergrid.sharedInstance.disconnect(self, relationship: relationship, from: fromEntity, completion: completion)
+ }
+
+ /**
+ Removes a relationship between this `UsergridEntity` and the given entity.
+
+ - parameter client: The client to use when disconnecting.
+ - parameter relationship: The relationship type.
+ - parameter fromEntity: The entity to disconnect.
+ - parameter completion: An optional completion block.
+ */
+ public func disconnect(client:UsergridClient, relationship:String, fromEntity:UsergridEntity, completion: UsergridResponseCompletion? = nil) {
+ client.disconnect(self, relationship: relationship, from: fromEntity, completion: completion)
+ }
+
+ /**
+ Gets the `UsergridEntity` objects, if any, which are connected via the relationship using the shared instance of `UsergridClient`.
+
+ - parameter direction: The direction of the connection.
+ - parameter relationship: The relationship type.
+ - parameter query: The optional query.
+ - parameter completion: An optional completion block.
+ */
+ public func getConnections(direction:UsergridDirection, relationship:String, query:UsergridQuery?, completion:UsergridResponseCompletion? = nil) {
+ Usergrid.sharedInstance.getConnections(direction, entity: self, relationship: relationship, query:query, completion: completion)
+ }
+
+ /**
+ Gets the `UsergridEntity` objects, if any, which are connected via the relationship.
+
+ - parameter client: The client to use when getting the connected `UsergridEntity` objects.
+ - parameter direction: The direction of the connection.
+ - parameter relationship: The relationship type.
+ - parameter query: The optional query.
+ - parameter completion: An optional completion block.
+ */
+ public func getConnections(client:UsergridClient, direction:UsergridDirection, relationship:String, query:UsergridQuery?, completion:UsergridResponseCompletion? = nil) {
+ client.getConnections(direction, entity: self, relationship: relationship, query:query, completion: completion)
+ }
+}
\ No newline at end of file