http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridEntity.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridEntity.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridEntity.swift new file mode 100644 index 0000000..4b6fe8f --- /dev/null +++ b/sdks/swift/Samples/Push/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
http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridEnums.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridEnums.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridEnums.swift new file mode 100644 index 0000000..1cc0c9c --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridEnums.swift @@ -0,0 +1,415 @@ +// +// UsergridEnums.swift +// UsergridSDK +// +// Created by Robert Walsh on 10/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 + +/** +An enumeration that is used to determine what the `UsergridClient` will fallback to depending on certain authorization conditions. +*/ +@objc public enum UsergridAuthFallback : Int { + + // MARK: - Values - + + /** + If a non-expired user auth token exists in `UsergridClient.currentUser`, this token is used to authenticate all API calls. + + If the API call fails, the activity is treated as a failure with an appropriate HTTP status code. + + If a non-expired user auth token does not exist, all API calls will be made unauthenticated. + */ + case None + /** + If a non-expired user auth token exists in `UsergridClient.currentUser`, this token is used to authenticate all API calls. + + If the API call fails, the activity is treated as a failure with an appropriate HTTP status code (This behavior is identical to authFallback=.None). + + If a non-expired user auth does not exist, all API calls will be made using stored app auth. + */ + case App +} + +/** +`UsergridEntity` specific properties keys. Note that trying to mutate the values of these properties will not be allowed in most cases. +*/ +@objc public enum UsergridEntityProperties : Int { + + // MARK: - Values - + + /// Corresponds to the property 'type' + case EntityType + /// Corresponds to the property 'uuid' + case UUID + /// Corresponds to the property 'name' + case Name + /// Corresponds to the property 'created' + case Created + /// Corresponds to the property 'modified' + case Modified + /// Corresponds to the property 'location' + case Location + + // MARK: - Methods - + + /** + Gets the corresponding `UsergridEntityProperties` from a string if it's valid. + + - parameter stringValue: The string value to convert. + + - returns: The corresponding `UsergridEntityProperties` or nil. + */ + public static func fromString(stringValue: String) -> UsergridEntityProperties? { + switch stringValue.lowercaseString { + case ENTITY_TYPE: return .EntityType + case ENTITY_UUID: return .UUID + case ENTITY_NAME: return .Name + case ENTITY_CREATED: return .Created + case ENTITY_MODIFIED: return .Modified + case ENTITY_LOCATION: return .Location + default: return nil + } + } + + /// Returns the string value. + public var stringValue: String { + switch self { + case .EntityType: return ENTITY_TYPE + case .UUID: return ENTITY_UUID + case .Name: return ENTITY_NAME + case .Created: return ENTITY_CREATED + case .Modified: return ENTITY_MODIFIED + case .Location: return ENTITY_LOCATION + } + } + + /** + Determines if the `UsergridEntityProperties` is mutable for the given entity. + + - parameter entity: The entity to check. + + - returns: If the `UsergridEntityProperties` is mutable for the given entity + */ + public func isMutableForEntity(entity:UsergridEntity) -> Bool { + switch self { + case .EntityType,.UUID,.Created,.Modified: return false + case .Location: return true + case .Name: return entity.isUser + } + } +} + +/** +`UsergridDeviceProperties` specific properties keys. Note that trying to mutate the values of these properties will not be allowed in most cases. +*/ +@objc public enum UsergridDeviceProperties : Int { + + // MARK: - Values - + + /// Corresponds to the property 'deviceModel' + case Model + /// Corresponds to the property 'devicePlatform' + case Platform + /// Corresponds to the property 'deviceOSVersion' + case OSVersion + + // MARK: - Methods - + + /** + Gets the corresponding `UsergridDeviceProperties` from a string if it's valid. + + - parameter stringValue: The string value to convert. + + - returns: The corresponding `UsergridDeviceProperties` or nil. + */ + public static func fromString(stringValue: String) -> UsergridDeviceProperties? { + switch stringValue.lowercaseString { + case DEVICE_MODEL: return .Model + case DEVICE_PLATFORM: return .Platform + case DEVICE_OSVERSION: return .OSVersion + default: return nil + } + } + + /// Returns the string value. + public var stringValue: String { + switch self { + case .Model: return DEVICE_MODEL + case .Platform: return DEVICE_PLATFORM + case .OSVersion: return DEVICE_OSVERSION + } + } +} + +/** +`UsergridUser` specific properties keys. +*/ +@objc public enum UsergridUserProperties: Int { + + // MARK: - Values - + + /// Corresponds to the property 'name' + case Name + /// Corresponds to the property 'username' + case Username + /// Corresponds to the property 'password' + case Password + /// Corresponds to the property 'email' + case Email + /// Corresponds to the property 'age' + case Age + /// Corresponds to the property 'activated' + case Activated + /// Corresponds to the property 'disabled' + case Disabled + /// Corresponds to the property 'picture' + case Picture + + // MARK: - Methods - + + /** + Gets the corresponding `UsergridUserProperties` from a string if it's valid. + + - parameter stringValue: The string value to convert. + + - returns: The corresponding `UsergridUserProperties` or nil. + */ + public static func fromString(stringValue: String) -> UsergridUserProperties? { + switch stringValue.lowercaseString { + case ENTITY_NAME: return .Name + case USER_USERNAME: return .Username + case USER_PASSWORD: return .Password + case USER_EMAIL: return .Email + case USER_AGE: return .Age + case USER_ACTIVATED: return .Activated + case USER_DISABLED: return .Disabled + case USER_PICTURE: return .Picture + default: return nil + } + } + + /// Returns the string value. + public var stringValue: String { + switch self { + case .Name: return ENTITY_NAME + case .Username: return USER_USERNAME + case .Password: return USER_PASSWORD + case .Email: return USER_EMAIL + case .Age: return USER_AGE + case .Activated: return USER_ACTIVATED + case .Disabled: return USER_DISABLED + case .Picture: return USER_PICTURE + } + } +} + +/** +`UsergridQuery` specific operators. +*/ +@objc public enum UsergridQueryOperator: Int { + + // MARK: - Values - + + /// '=' + case Equal + /// '>' + case GreaterThan + /// '>=' + case GreaterThanEqualTo + /// '<' + case LessThan + /// '<=' + case LessThanEqualTo + + // MARK: - Methods - + + /** + Gets the corresponding `UsergridQueryOperator` from a string if it's valid. + + - parameter stringValue: The string value to convert. + + - returns: The corresponding `UsergridQueryOperator` or nil. + */ + public static func fromString(stringValue: String) -> UsergridQueryOperator? { + switch stringValue.lowercaseString { + case UsergridQuery.EQUAL: return .Equal + case UsergridQuery.GREATER_THAN: return .GreaterThan + case UsergridQuery.GREATER_THAN_EQUAL_TO: return .GreaterThanEqualTo + case UsergridQuery.LESS_THAN: return .LessThan + case UsergridQuery.LESS_THAN_EQUAL_TO: return .LessThanEqualTo + default: return nil + } + } + + /// Returns the string value. + public var stringValue: String { + switch self { + case .Equal: return UsergridQuery.EQUAL + case .GreaterThan: return UsergridQuery.GREATER_THAN + case .GreaterThanEqualTo: return UsergridQuery.GREATER_THAN_EQUAL_TO + case .LessThan: return UsergridQuery.LESS_THAN + case .LessThanEqualTo: return UsergridQuery.LESS_THAN_EQUAL_TO + } + } +} + +/** +`UsergridQuery` specific sort orders. +*/ +@objc public enum UsergridQuerySortOrder: Int { + + // MARK: - Values - + + /// Sort order is ascending. + case Asc + /// Sort order is descending. + case Desc + + // MARK: - Methods - + + /** + Gets the corresponding `UsergridQuerySortOrder` from a string if it's valid. + + - parameter stringValue: The string value to convert. + + - returns: The corresponding `UsergridQuerySortOrder` or nil. + */ + public static func fromString(stringValue: String) -> UsergridQuerySortOrder? { + switch stringValue.lowercaseString { + case UsergridQuery.ASC: return .Asc + case UsergridQuery.DESC: return .Desc + default: return nil + } + } + + /// Returns the string value. + public var stringValue: String { + switch self { + case .Asc: return UsergridQuery.ASC + case .Desc: return UsergridQuery.DESC + } + } +} + +/** +`UsergridAsset` image specific content types. +*/ +@objc public enum UsergridImageContentType : Int { + + // MARK: - Values - + + /// Content type: 'image/png' + case Png + /// Content type: 'image/jpeg' + case Jpeg + + // MARK: - Methods - + + /// Returns the string value. + public var stringValue: String { + switch self { + case .Png: return ASSET_IMAGE_PNG + case .Jpeg: return ASSET_IMAGE_JPEG + } + } +} + +/** + An enumeration that is used when getting connections to entity objects. Used to determine which the direction of the connection is wanted. + */ +@objc public enum UsergridDirection : Int { + + // MARK: - Values - + + /// To get the entities that have created a connection to an entity. aka `connecting` + case In + + /// To get the entities an entity has connected to. aka `connections` + case Out + + // MARK: - Methods - + + /// Returns the connection value. + public var connectionValue: String { + switch self { + case .In: return CONNECTION_TYPE_IN + case .Out: return CONNECTION_TYPE_OUT + } + } +} + +/** + An enumeration for defining the HTTP methods used by Usergrid. + */ +@objc public enum UsergridHttpMethod : Int { + + /// GET + case Get + + /// PUT + case Put + + /// POST + case Post + + /// DELETE + case Delete + + /// Returns the string value. + public var stringValue: String { + switch self { + case .Get: return "GET" + case .Put: return "PUT" + case .Post: return "POST" + case .Delete: return "DELETE" + } + } +} + +let ENTITY_TYPE = "type" +let ENTITY_UUID = "uuid" +let ENTITY_NAME = "name" +let ENTITY_CREATED = "created" +let ENTITY_MODIFIED = "modified" +let ENTITY_LOCATION = "location" +let ENTITY_LATITUDE = "latitude" +let ENTITY_LONGITUDE = "longitude" + +let USER_USERNAME = "username" +let USER_PASSWORD = "password" +let USER_EMAIL = "email" +let USER_AGE = "age" +let USER_ACTIVATED = "activated" +let USER_DISABLED = "disabled" +let USER_PICTURE = "picture" + +let DEVICE_MODEL = "deviceModel" +let DEVICE_PLATFORM = "devicePlatform" +let DEVICE_OSVERSION = "devicePlatform" + +let ASSET_IMAGE_PNG = "image/png" +let ASSET_IMAGE_JPEG = "image/jpeg" + +let CONNECTION_TYPE_IN = "connecting" +let CONNECTION_TYPE_OUT = "connections" http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridExtensions.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridExtensions.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridExtensions.swift new file mode 100644 index 0000000..050145c --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridExtensions.swift @@ -0,0 +1,42 @@ +// +// UsergridExtensions.swift +// UsergridSDK +// +// Created by Robert Walsh on 10/6/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 + +internal extension NSDate { + convenience init(utcTimeStamp: String) { + self.init(timeIntervalSince1970: (utcTimeStamp as NSString).doubleValue / 1000 ) + } + func utcTimeStamp() -> Int { + return Int(self.timeIntervalSince1970 * 1000) + } +} + +internal extension String { + func isUuid() -> Bool { + return (NSUUID(UUIDString: self) != nil) ? true : false + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridFileMetaData.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridFileMetaData.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridFileMetaData.swift new file mode 100644 index 0000000..c3e7f52 --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridFileMetaData.swift @@ -0,0 +1,114 @@ +// +// UsergridFileMetaData.swift +// UsergridSDK +// +// Created by Robert Walsh on 10/6/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 + +/** +`UsergridFileMetaData` is a helper class for dealing with reading `UsergridEntity` file meta data. +*/ +public class UsergridFileMetaData : NSObject,NSCoding { + + internal static let FILE_METADATA = "file-metadata" + + // MARK: - Instance Properties - + + /// The eTag. + public let eTag: String? + + /// The check sum. + public let checkSum: String? + + /// The content type associated with the file data. + public let contentType: String? + + /// The content length of the file data. + public let contentLength: Int + + /// The last modified time stamp. + public let lastModifiedTimeStamp: Int + + /// The `NSDate` object corresponding to the last modified time stamp. + public let lastModifiedDate: NSDate? + + // MARK: - Initialization - + + /** + Designated initializer for `UsergridFileMetaData` objects. + + - parameter fileMetaDataJSON: The file meta data JSON dictionary. + + - returns: A new instance of `UsergridFileMetaData`. + */ + public init(fileMetaDataJSON:[String:AnyObject]) { + self.eTag = fileMetaDataJSON["etag"] as? String + self.checkSum = fileMetaDataJSON["checksum"] as? String + self.contentType = fileMetaDataJSON["content-type"] as? String + self.contentLength = fileMetaDataJSON["content-length"] as? Int ?? 0 + self.lastModifiedTimeStamp = fileMetaDataJSON["last-modified"] as? Int ?? 0 + + if self.lastModifiedTimeStamp > 0 { + self.lastModifiedDate = NSDate(utcTimeStamp: self.lastModifiedTimeStamp.description) + } else { + self.lastModifiedDate = nil + } + } + + // MARK: - NSCoding - + + /** + NSCoding protocol initializer. + + - parameter aDecoder: The decoder. + + - returns: A decoded `UsergridUser` object. + */ + required public init?(coder aDecoder: NSCoder) { + self.eTag = aDecoder.decodeObjectForKey("etag") as? String + self.checkSum = aDecoder.decodeObjectForKey("checksum") as? String + self.contentType = aDecoder.decodeObjectForKey("content-type") as? String + self.contentLength = aDecoder.decodeIntegerForKey("content-length") ?? 0 + self.lastModifiedTimeStamp = aDecoder.decodeIntegerForKey("last-modified") ?? 0 + + if self.lastModifiedTimeStamp > 0 { + self.lastModifiedDate = NSDate(utcTimeStamp: self.lastModifiedTimeStamp.description) + } else { + self.lastModifiedDate = nil + } + } + + /** + NSCoding protocol encoder. + + - parameter aCoder: The encoder. + */ + public func encodeWithCoder(aCoder: NSCoder) { + aCoder.encodeObject(self.eTag, forKey: "etag") + aCoder.encodeObject(self.checkSum, forKey: "checksum") + aCoder.encodeObject(self.contentType, forKey: "content-type") + aCoder.encodeInteger(self.contentLength, forKey: "content-length") + aCoder.encodeInteger(self.lastModifiedTimeStamp, forKey: "last-modified") + } +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridKeychainHelpers.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridKeychainHelpers.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridKeychainHelpers.swift new file mode 100644 index 0000000..2d7dee6 --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridKeychainHelpers.swift @@ -0,0 +1,148 @@ +// +// UsergridKeychainHelpers.swift +// UsergridSDK +// +// Created by Robert Walsh on 12/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 + +#if os(iOS) || os(tvOS) || os(watchOS) +import UIKit +#endif + +private let USERGRID_KEYCHAIN_NAME = "Usergrid" +private let USERGRID_DEVICE_KEYCHAIN_SERVICE = "DeviceUUID" +private let USERGRID_CURRENT_USER_KEYCHAIN_SERVICE = "CurrentUser" + +private func usergridGenericKeychainItem() -> [String:AnyObject] { + var keychainItem: [String:AnyObject] = [:] + keychainItem[kSecClass as String] = kSecClassGenericPassword as String + keychainItem[kSecAttrAccessible as String] = kSecAttrAccessibleAlways as String + keychainItem[kSecAttrAccount as String] = USERGRID_KEYCHAIN_NAME + return keychainItem +} + +internal extension UsergridDevice { + + static func deviceKeychainItem() -> [String:AnyObject] { + var keychainItem = usergridGenericKeychainItem() + keychainItem[kSecAttrService as String] = USERGRID_DEVICE_KEYCHAIN_SERVICE + return keychainItem + } + + static func createNewUsergridKeychainUUID() -> String { + + #if os(watchOS) || os(OSX) + let usergridUUID = NSUUID().UUIDString + #elseif os(iOS) || os(tvOS) + let usergridUUID = UIDevice.currentDevice().identifierForVendor?.UUIDString ?? NSUUID().UUIDString + #endif + + var keychainItem = UsergridDevice.deviceKeychainItem() + keychainItem[kSecValueData as String] = (usergridUUID as NSString).dataUsingEncoding(NSUTF8StringEncoding) + SecItemAdd(keychainItem, nil) + return usergridUUID + } + + static func usergridDeviceUUID() -> String { + var queryAttributes = UsergridDevice.deviceKeychainItem() + queryAttributes[kSecReturnData as String] = kCFBooleanTrue as Bool + queryAttributes[kSecReturnAttributes as String] = kCFBooleanTrue as Bool + var result: AnyObject? + let status = withUnsafeMutablePointer(&result) { SecItemCopyMatching(queryAttributes, UnsafeMutablePointer($0)) } + if status == errSecSuccess { + if let resultDictionary = result as? NSDictionary { + if let resultData = resultDictionary[kSecValueData as String] as? NSData { + if let keychainUUID = String(data: resultData, encoding: NSUTF8StringEncoding) { + return keychainUUID + } + } + } + } + return UsergridDevice.createNewUsergridKeychainUUID() + } +} + +internal extension UsergridUser { + + static func userKeychainItem(client:UsergridClient) -> [String:AnyObject] { + var keychainItem = usergridGenericKeychainItem() + keychainItem[kSecAttrService as String] = USERGRID_CURRENT_USER_KEYCHAIN_SERVICE + "." + client.appId + "." + client.orgId + return keychainItem + } + + static func getCurrentUserFromKeychain(client:UsergridClient) -> UsergridUser? { + var queryAttributes = UsergridUser.userKeychainItem(client) + queryAttributes[kSecReturnData as String] = kCFBooleanTrue as Bool + queryAttributes[kSecReturnAttributes as String] = kCFBooleanTrue as Bool + + var result: AnyObject? + let status = withUnsafeMutablePointer(&result) { SecItemCopyMatching(queryAttributes, UnsafeMutablePointer($0)) } + if status == errSecSuccess { + if let resultDictionary = result as? NSDictionary { + if let resultData = resultDictionary[kSecValueData as String] as? NSData { + if let currentUser = NSKeyedUnarchiver.unarchiveObjectWithData(resultData) as? UsergridUser { + return currentUser + } + } + } + } + return nil + } + + static func saveCurrentUserKeychainItem(client:UsergridClient, currentUser:UsergridUser) { + var queryAttributes = UsergridUser.userKeychainItem(client) + queryAttributes[kSecReturnData as String] = kCFBooleanTrue as Bool + queryAttributes[kSecReturnAttributes as String] = kCFBooleanTrue as Bool + + if SecItemCopyMatching(queryAttributes,nil) == errSecSuccess // Do we need to update keychain item or add a new one. + { + let attributesToUpdate = [kSecValueData as String:NSKeyedArchiver.archivedDataWithRootObject(currentUser)] + let updateStatus = SecItemUpdate(UsergridUser.userKeychainItem(client), attributesToUpdate) + if updateStatus != errSecSuccess { + print("Error updating current user data to keychain!") + } + } + else + { + var keychainItem = UsergridUser.userKeychainItem(client) + keychainItem[kSecValueData as String] = NSKeyedArchiver.archivedDataWithRootObject(currentUser) + let status = SecItemAdd(keychainItem, nil) + if status != errSecSuccess { + print("Error adding current user data to keychain!") + } + } + } + + static func deleteCurrentUserKeychainItem(client:UsergridClient) { + var queryAttributes = UsergridUser.userKeychainItem(client) + queryAttributes[kSecReturnData as String] = kCFBooleanFalse as Bool + queryAttributes[kSecReturnAttributes as String] = kCFBooleanFalse as Bool + if SecItemCopyMatching(queryAttributes,nil) == errSecSuccess { + let deleteStatus = SecItemDelete(queryAttributes) + if deleteStatus != errSecSuccess { + print("Error deleting current user data to keychain!") + } + } + } +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridQuery.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridQuery.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridQuery.swift new file mode 100644 index 0000000..9dfd10a --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridQuery.swift @@ -0,0 +1,530 @@ +// +// UsergridQuery.swift +// UsergridSDK +// +// Created by Robert Walsh on 7/22/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 + +/** + `UsergridQuery` is builder class used to construct filtered requests to Usergrid. + + `UsergridQuery` objects are then passed to `UsergridClient` or `Usergrid` methods which support `UsergridQuery` as a parameter are .GET(), .PUT(), and .DELETE(). + */ +public class UsergridQuery : NSObject,NSCopying { + + // MARK: - Initialization - + + /** + Desingated initializer for `UsergridQuery` objects. + + - parameter collectionName: The collection name or `type` of entities you want to query. + + - returns: A new instance of `UsergridQuery`. + */ + public init(_ collectionName: String? = nil) { + self.collectionName = collectionName + } + + // MARK: - NSCopying - + + /** + See the NSCopying protocol. + + - parameter zone: Ignored + + - returns: Returns a new instance thatâs a copy of the receiver. + */ + public func copyWithZone(zone: NSZone) -> AnyObject { + let queryCopy = UsergridQuery(self.collectionName) + queryCopy.requirementStrings = NSArray(array:self.requirementStrings, copyItems: true) as! [String] + queryCopy.urlTerms = NSArray(array:self.urlTerms, copyItems: true) as! [String] + for (key,value) in self.orderClauses { + queryCopy.orderClauses[key] = value + } + queryCopy.limit = self.limit + queryCopy.cursor = self.cursor + return queryCopy + } + + // MARK: - Building - + + /** + Constructs the string that should be appeneded to the end of the URL as a query. + + - parameter autoURLEncode: Automatically encode the constructed string. + + - returns: The constructed URL query sting. + */ + public func build(autoURLEncode: Bool = true) -> String { + return self.constructURLAppend(autoURLEncode) + } + + // MARK: - Builder Methods - + + /** + Contains. Query: where term contains 'val%'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func containsString(term: String, value: String) -> Self { return self.containsWord(term, value: value) } + + /** + Contains. Query: where term contains 'val%'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func containsWord(term: String, value: String) -> Self { return self.addRequirement(term + UsergridQuery.SPACE + UsergridQuery.CONTAINS + UsergridQuery.SPACE + ((value.isUuid()) ? UsergridQuery.EMPTY_STRING : UsergridQuery.APOSTROPHE) + value + ((value.isUuid()) ? UsergridQuery.EMPTY_STRING : UsergridQuery.APOSTROPHE)) } + + /** + Sort ascending. Query:. order by term asc. + + - parameter term: The term. + + - returns: `Self` + */ + public func ascending(term: String) -> Self { return self.asc(term) } + + /** + Sort ascending. Query:. order by term asc. + + - parameter term: The term. + + - returns: `Self` + */ + public func asc(term: String) -> Self { return self.sort(term, sortOrder: UsergridQuerySortOrder.Asc) } + + /** + Sort descending. Query: order by term desc + + - parameter term: The term. + + - returns: `Self` + */ + public func descending(term: String) -> Self { return self.desc(term) } + + /** + Sort descending. Query: order by term desc + + - parameter term: The term. + + - returns: `Self` + */ + public func desc(term: String) -> Self { return self.sort(term, sortOrder: UsergridQuerySortOrder.Desc) } + + /** + Filter (or Equal-to). Query: where term = 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func filter(term: String, value: AnyObject) -> Self { return self.eq(term, value: value) } + + /** + Equal-to. Query: where term = 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func equals(term: String, value: AnyObject) -> Self { return self.eq(term, value: value) } + + /** + Equal-to. Query: where term = 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func eq(term: String, value: AnyObject) -> Self { return self.addOperationRequirement(term, operation:.Equal, value: value) } + + /** + Greater-than. Query: where term > 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func greaterThan(term: String, value: AnyObject) -> Self { return self.gt(term, value: value) } + + /** + Greater-than. Query: where term > 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func gt(term: String, value: AnyObject) -> Self { return self.addOperationRequirement(term, operation:.GreaterThan, value: value) } + + /** + Greater-than-or-equal-to. Query: where term >= 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func greaterThanOrEqual(term: String, value: AnyObject) -> Self { return self.gte(term, value: value) } + + /** + Greater-than-or-equal-to. Query: where term >= 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func gte(term: String, value: AnyObject) -> Self { return self.addOperationRequirement(term, operation:.GreaterThanEqualTo, value: value) } + + /** + Less-than. Query: where term < 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func lessThan(term: String, value: AnyObject) -> Self { return self.lt(term, value: value) } + + /** + Less-than. Query: where term < 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func lt(term: String, value: AnyObject) -> Self { return self.addOperationRequirement(term, operation:.LessThan, value: value) } + + /** + Less-than-or-equal-to. Query: where term <= 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func lessThanOrEqual(term: String, value: AnyObject) -> Self { return self.lte(term, value: value) } + + /** + Less-than-or-equal-to. Query: where term <= 'value'. + + - parameter term: The term. + - parameter value: The value. + + - returns: `Self` + */ + public func lte(term: String, value: AnyObject) -> Self { return self.addOperationRequirement(term, operation:.LessThanEqualTo, value: value) } + + /** + Contains. Query: location within val of lat, long. + + - parameter distance: The distance from the latitude and longitude. + - parameter latitude: The latitude. + - parameter longitude: The longitude. + + - returns: `Self` + */ + public func locationWithin(distance: Float, latitude: Float, longitude: Float) -> Self { + return self.addRequirement(UsergridQuery.LOCATION + UsergridQuery.SPACE + UsergridQuery.WITHIN + UsergridQuery.SPACE + distance.description + UsergridQuery.SPACE + UsergridQuery.OF + UsergridQuery.SPACE + latitude.description + UsergridQuery.COMMA + longitude.description ) + } + + /** + Joining operation to combine conditional queries. + + - returns: `Self` + */ + public func or() -> Self { + if !self.requirementStrings.first!.isEmpty { + self.requirementStrings.insert(UsergridQuery.OR, atIndex: 0) + self.requirementStrings.insert(UsergridQuery.EMPTY_STRING, atIndex: 0) + } + return self + } + + /** + Not operation for conditional queries. + + - returns: `Self` + */ + public func not() -> Self { + if !self.requirementStrings.first!.isEmpty { + self.requirementStrings.insert(UsergridQuery.NOT, atIndex: 0) + self.requirementStrings.insert(UsergridQuery.EMPTY_STRING, atIndex: 0) + } + return self + } + + /** + Sort. Query: order by term `sortOrder` + + - parameter term: The term. + - parameter sortOrder: The order. + + - returns: `Self` + */ + public func sort(term: String, sortOrder: UsergridQuerySortOrder) -> Self { + self.orderClauses[term] = sortOrder + return self + } + + /** + Sets the collection name. + + - parameter collectionName: The new collection name. + + - returns: `Self` + */ + public func collection(collectionName: String) -> Self { + self.collectionName = collectionName + return self + } + + /** + Sets the limit on the query. Default limit is 10. + + - parameter limit: The limit. + + - returns: `Self` + */ + public func limit(limit: Int) -> Self { + self.limit = limit + return self + } + + /** + Adds a preconstructed query string as a requirement onto the query. + + - parameter value: The query string. + + - returns: `Self` + */ + public func ql(value: String) -> Self { + return self.addRequirement(value) + } + + /** + Sets the cursor of the query used internally by Usergrid's APIs. + + - parameter value: The cursor. + + - returns: `Self` + */ + public func cursor(value: String?) -> Self { + self.cursor = value + return self + } + + /** + Adds a URL term that will be added next to the query string when constructing the URL append. + + - parameter term: The term. + - parameter equalsValue: The value. + + - returns: `Self` + */ + public func urlTerm(term: String, equalsValue: String) -> Self { + if (term as NSString).isEqualToString(UsergridQuery.QL) { + self.ql(equalsValue) + } else { + self.urlTerms.append(term + UsergridQueryOperator.Equal.stringValue + equalsValue) + } + return self + } + + /** + Adds a string requirement to the query. + + - parameter term: The term. + - parameter operation: The operation. + - parameter stringValue: The string value. + + - returns: `Self` + */ + public func addOperationRequirement(term: String, operation: UsergridQueryOperator, stringValue: String) -> Self { + return self.addOperationRequirement(term,operation:operation,value:stringValue) + } + + /** + Adds a integer requirement to the query. + + - parameter term: The term. + - parameter operation: The operation. + - parameter intValue: The integer value. + + - returns: `Self` + */ + public func addOperationRequirement(term: String, operation: UsergridQueryOperator, intValue: Int) -> Self { + return self.addOperationRequirement(term,operation:operation,value:intValue) + } + + private func addRequirement(requirement: String) -> Self { + var requirementString: String = self.requirementStrings.removeAtIndex(0) + if !requirementString.isEmpty { + requirementString += UsergridQuery.SPACE + UsergridQuery.AND + UsergridQuery.SPACE + } + requirementString += requirement + self.requirementStrings.insert(requirementString, atIndex: 0) + return self + } + + private func addOperationRequirement(term: String, operation: UsergridQueryOperator, value: AnyObject) -> Self { + if value is String { + return self.addRequirement(term + UsergridQuery.SPACE + operation.stringValue + UsergridQuery.SPACE + ((value.description.isUuid()) ? UsergridQuery.EMPTY_STRING : UsergridQuery.APOSTROPHE) + value.description + ((value.description.isUuid()) ? UsergridQuery.EMPTY_STRING : UsergridQuery.APOSTROPHE) ) + } else { + return self.addRequirement(term + UsergridQuery.SPACE + operation.stringValue + UsergridQuery.SPACE + value.description) + } + } + + private func constructOrderByString() -> String { + var orderByString = UsergridQuery.EMPTY_STRING + if !self.orderClauses.isEmpty { + var combinedClausesArray: [String] = [] + for (key,value) in self.orderClauses { + combinedClausesArray.append(key + UsergridQuery.SPACE + value.stringValue) + } + for index in 0..<combinedClausesArray.count { + if index > 0 { + orderByString += UsergridQuery.COMMA + } + orderByString += combinedClausesArray[index] + } + if !orderByString.isEmpty { + orderByString = UsergridQuery.SPACE + UsergridQuery.ORDER_BY + UsergridQuery.SPACE + orderByString + } + } + return orderByString + } + + private func constructURLTermsString() -> String { + return (self.urlTerms as NSArray).componentsJoinedByString(UsergridQuery.AMPERSAND) + } + + private func constructRequirementString() -> String { + var requirementsString = UsergridQuery.EMPTY_STRING + var requirementStrings = self.requirementStrings + + // If the first requirement is empty lets remove it. + if let firstRequirement = requirementStrings.first where firstRequirement.isEmpty { + requirementStrings.removeFirst() + } + + // If the first requirement now is a conditional separator then we should remove it so its not placed at the end of the constructed string. + if let firstRequirement = requirementStrings.first where firstRequirement == UsergridQuery.OR || firstRequirement == UsergridQuery.NOT { + requirementStrings.removeFirst() + } + + requirementsString = (requirementStrings.reverse() as NSArray).componentsJoinedByString(UsergridQuery.SPACE) + return requirementsString + } + + private func constructURLAppend(autoURLEncode: Bool = true) -> String { + var urlAppend = UsergridQuery.EMPTY_STRING + if self.limit != UsergridQuery.LIMIT_DEFAULT { + urlAppend += "\(UsergridQuery.LIMIT)=\(self.limit.description)" + } + let urlTermsString = self.constructURLTermsString() + if !urlTermsString.isEmpty { + if !urlAppend.isEmpty { + urlAppend += UsergridQuery.AMPERSAND + } + urlAppend += urlTermsString + } + if let cursorString = self.cursor where !cursorString.isEmpty { + if !urlAppend.isEmpty { + urlAppend += UsergridQuery.AMPERSAND + } + urlAppend += "\(UsergridQuery.CURSOR)=\(cursorString)" + } + + var requirementsString = self.constructRequirementString() + let orderByString = self.constructOrderByString() + if !orderByString.isEmpty { + requirementsString += orderByString + } + if !requirementsString.isEmpty { + if autoURLEncode { + if let encodedRequirementsString = requirementsString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) { + requirementsString = encodedRequirementsString + } + } + if !urlAppend.isEmpty { + urlAppend += UsergridQuery.AMPERSAND + } + urlAppend += "\(UsergridQuery.QL)=\(requirementsString)" + } + + if !urlAppend.isEmpty { + urlAppend = "\(UsergridQuery.QUESTION_MARK)\(urlAppend)" + } + return urlAppend + } + + private(set) var collectionName: String? = nil + private(set) var cursor: String? = nil + private(set) var limit: Int = UsergridQuery.LIMIT_DEFAULT + + private(set) var requirementStrings: [String] = [UsergridQuery.EMPTY_STRING] + private(set) var orderClauses: [String:UsergridQuerySortOrder] = [:] + private(set) var urlTerms: [String] = [] + + private static let LIMIT_DEFAULT = 10 + private static let AMPERSAND = "&" + private static let AND = "and" + private static let APOSTROPHE = "'" + private static let COMMA = "," + private static let CONTAINS = "contains" + private static let CURSOR = "cursor" + private static let EMPTY_STRING = "" + private static let IN = "in" + private static let LIMIT = "limit" + private static let LOCATION = "location"; + private static let NOT = "not" + private static let OF = "of" + private static let OR = "or" + private static let ORDER_BY = "order by" + private static let QL = "ql" + private static let QUESTION_MARK = "?" + private static let SPACE = " " + private static let WITHIN = "within" + + internal static let ASC = "asc" + internal static let DESC = "desc" + internal static let EQUAL = "=" + internal static let GREATER_THAN = ">" + internal static let GREATER_THAN_EQUAL_TO = ">=" + internal static let LESS_THAN = "<" + internal static let LESS_THAN_EQUAL_TO = "<=" +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridRequest.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridRequest.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridRequest.swift new file mode 100644 index 0000000..dd1f561 --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridRequest.swift @@ -0,0 +1,245 @@ +// +// UsergridRequest.swift +// UsergridSDK +// +// Created by Robert Walsh on 1/12/16. +// +/* + * + * 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 UsergridRequest class incapsulates the properties that all requests made by the SDK have in common. + + This class is also functions to create `NSURLRequest` objects based on the properties of the class. +*/ +public class UsergridRequest : NSObject { + + // MARK: - Instance Properties - + + /// The HTTP method. + public let method: UsergridHttpMethod + + /// The base URL. + public let baseUrl: String + + /// The paths to append to the base URL. + public let paths: [String]? + + /// The query to append to the URL. + public let query: UsergridQuery? + + /// The auth that will be used. + public let auth: UsergridAuth? + + /// The headers to add to the request. + public let headers: [String:String]? + + /// The JSON body that will be set on the request. Can be either a valid JSON object or NSData. + public let jsonBody: AnyObject? + + /// The query params that will be set on the request. + public let queryParams: [String:String]? + + // MARK: - Initialization - + + /** + The designated initializer for `UsergridRequest` objects. + + - parameter method: The HTTP method. + - parameter baseUrl: The base URL. + - parameter paths: The optional paths to append to the base URL. + - parameter query: The optional query to append to the URL. + - parameter auth: The optional `UsergridAuth` that will be used in the Authorization header. + - parameter headers: The optional headers. + - parameter jsonBody: The optional JSON body. Can be either a valid JSON object or NSData. + - parameter queryParams: The optional query params to be appended to the request url. + + - returns: A new instance of `UsergridRequest`. + */ + public init(method:UsergridHttpMethod, + baseUrl:String, + paths:[String]? = nil, + query:UsergridQuery? = nil, + auth:UsergridAuth? = nil, + headers:[String:String]? = nil, + jsonBody:AnyObject? = nil, + queryParams:[String:String]? = nil) { + self.method = method + self.baseUrl = baseUrl + self.paths = paths + self.auth = auth + self.headers = headers + self.query = query + self.queryParams = queryParams + if let body = jsonBody where (body is NSData || NSJSONSerialization.isValidJSONObject(body)) { + self.jsonBody = body + } else { + self.jsonBody = nil + } + } + + // MARK: - Instance Methods - + + /** + Constructs a `NSURLRequest` object with this objects instance properties. + + - returns: An initialized and configured `NSURLRequest` object. + */ + public func buildNSURLRequest() -> NSURLRequest { + let request = NSMutableURLRequest(URL: self.buildURL()) + request.HTTPMethod = self.method.stringValue + self.applyHeaders(request) + self.applyBody(request) + self.applyAuth(request) + return request + } + + private func buildURL() -> NSURL { + var constructedURLString = self.baseUrl + if let appendingPaths = self.paths { + for pathToAppend in appendingPaths { + if let encodedPath = pathToAppend.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet()) { + constructedURLString = "\(constructedURLString)\(UsergridRequest.FORWARD_SLASH)\(encodedPath)" + } + } + } + if let queryToAppend = self.query { + let appendFromQuery = queryToAppend.build() + if !appendFromQuery.isEmpty { + constructedURLString = "\(constructedURLString)\(UsergridRequest.FORWARD_SLASH)\(appendFromQuery)" + } + } + if let queryParams = self.queryParams { + if let components = NSURLComponents(string: constructedURLString) { + components.queryItems = components.queryItems ?? [] + for (key, value) in queryParams { + let q: NSURLQueryItem = NSURLQueryItem(name: key, value: value) + components.queryItems!.append(q) + } + constructedURLString = components.string! + } + } + return NSURL(string:constructedURLString)! + } + + private func applyHeaders(request:NSMutableURLRequest) { + if let httpHeaders = self.headers { + for (key,value) in httpHeaders { + request.setValue(value, forHTTPHeaderField: key) + } + } + } + + private func applyBody(request:NSMutableURLRequest) { + if let jsonBody = self.jsonBody, httpBody = UsergridRequest.jsonBodyToData(jsonBody) { + request.HTTPBody = httpBody + request.setValue(String(format: "%lu", httpBody.length), forHTTPHeaderField: UsergridRequest.CONTENT_LENGTH) + } + } + + private func applyAuth(request:NSMutableURLRequest) { + if let usergridAuth = self.auth { + if usergridAuth.isValid, let accessToken = usergridAuth.accessToken { + request.setValue("\(UsergridRequest.BEARER) \(accessToken)", forHTTPHeaderField: UsergridRequest.AUTHORIZATION) + } + } + } + + private static func jsonBodyToData(jsonBody:AnyObject) -> NSData? { + if let jsonBodyAsNSData = jsonBody as? NSData { + return jsonBodyAsNSData + } else { + var jsonBodyAsNSData: NSData? = nil + do { jsonBodyAsNSData = try NSJSONSerialization.dataWithJSONObject(jsonBody, options: NSJSONWritingOptions(rawValue: 0)) } + catch { print(error) } + return jsonBodyAsNSData + } + } + + private static let AUTHORIZATION = "Authorization" + private static let ACCESS_TOKEN = "access_token" + private static let APPLICATION_JSON = "application/json" + private static let BEARER = "Bearer" + private static let CONTENT_LENGTH = "Content-Length" + private static let CONTENT_TYPE = "Content-Type" + private static let FORWARD_SLASH = "/" + + static let JSON_CONTENT_TYPE_HEADER = [UsergridRequest.CONTENT_TYPE:UsergridRequest.APPLICATION_JSON] +} + +/** + The `UsergridRequest` sub class which is used for uploading assets. + */ +public class UsergridAssetUploadRequest: UsergridRequest { + + // MARK: - Instance Properties - + + /// The asset to use for uploading. + public let asset: UsergridAsset + + /// A constructed multipart http body for requests to upload. + public var multiPartHTTPBody: NSData { + let httpBodyString = UsergridAssetUploadRequest.MULTIPART_START + + "\(UsergridAssetUploadRequest.CONTENT_DISPOSITION):\(UsergridAssetUploadRequest.FORM_DATA); name=file; filename=\(self.asset.filename)\r\n" + + "\(UsergridRequest.CONTENT_TYPE): \(self.asset.contentType)\r\n\r\n" as NSString + + let httpBody = NSMutableData() + httpBody.appendData(httpBodyString.dataUsingEncoding(NSUTF8StringEncoding)!) + httpBody.appendData(self.asset.data) + httpBody.appendData(UsergridAssetUploadRequest.MULTIPART_END.dataUsingEncoding(NSUTF8StringEncoding)!) + + return httpBody + } + + // MARK: - Initialization - + + /** + The designated initializer for `UsergridAssetUploadRequest` objects. + + - parameter baseUrl: The base URL. + - parameter paths: The optional paths to append to the base URL. + - parameter auth: The optional `UsergridAuth` that will be used in the Authorization header. + - parameter asset: The asset to upload. + + - returns: A new instance of `UsergridRequest`. + */ + public init(baseUrl:String, + paths:[String]? = nil, + auth:UsergridAuth? = nil, + asset:UsergridAsset) { + self.asset = asset + super.init(method: .Put, baseUrl: baseUrl, paths: paths, auth: auth) + } + + private override func applyHeaders(request: NSMutableURLRequest) { + super.applyHeaders(request) + request.setValue(UsergridAssetUploadRequest.ASSET_UPLOAD_CONTENT_HEADER, forHTTPHeaderField: UsergridRequest.CONTENT_TYPE) + request.setValue(String(format: "%lu", self.multiPartHTTPBody.length), forHTTPHeaderField: UsergridRequest.CONTENT_LENGTH) + } + + private static let ASSET_UPLOAD_BOUNDARY = "usergrid-asset-upload-boundary" + private static let ASSET_UPLOAD_CONTENT_HEADER = "multipart/form-data; boundary=\(UsergridAssetUploadRequest.ASSET_UPLOAD_BOUNDARY)" + private static let CONTENT_DISPOSITION = "Content-Disposition" + private static let MULTIPART_START = "--\(UsergridAssetUploadRequest.ASSET_UPLOAD_BOUNDARY)\r\n" + private static let MULTIPART_END = "\r\n--\(UsergridAssetUploadRequest.ASSET_UPLOAD_BOUNDARY)--\r\n" as NSString + private static let FORM_DATA = "form-data" +}
