http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridRequestManager.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridRequestManager.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridRequestManager.swift new file mode 100644 index 0000000..ccd41e5 --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridRequestManager.swift @@ -0,0 +1,156 @@ +// +// UsergridRequestManager.swift +// UsergridSDK +// +// Created by Robert Walsh on 9/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 + +final class UsergridRequestManager { + + unowned let client: UsergridClient + + let session: NSURLSession + + var sessionDelegate : UsergridSessionDelegate { + return session.delegate as! UsergridSessionDelegate + } + + init(client:UsergridClient) { + self.client = client + + let config = NSURLSessionConfiguration.defaultSessionConfiguration() + + #if os(tvOS) + config.HTTPAdditionalHeaders = ["User-Agent": "usergrid-tvOS/v\(UsergridSDKVersion)"] + #elseif os(iOS) + config.HTTPAdditionalHeaders = ["User-Agent": "usergrid-ios/v\(UsergridSDKVersion)"] + #elseif os(watchOS) + config.HTTPAdditionalHeaders = ["User-Agent": "usergrid-watchOS/v\(UsergridSDKVersion)"] + #elseif os(OSX) + config.HTTPAdditionalHeaders = ["User-Agent": "usergrid-osx/v\(UsergridSDKVersion)"] + #endif + + self.session = NSURLSession(configuration: config, + delegate: UsergridSessionDelegate(), + delegateQueue: NSOperationQueue.mainQueue()) + } + + deinit { + session.invalidateAndCancel() + } + + func performRequest(request:UsergridRequest, completion:UsergridResponseCompletion?) { + session.dataTaskWithRequest(request.buildNSURLRequest()) { [weak self] (data, response, error) -> Void in + completion?(response: UsergridResponse(client:self?.client, data: data, response: response as? NSHTTPURLResponse, error: error)) + }.resume() + } +} + + +// MARK: - Authentication - +extension UsergridRequestManager { + + static func getTokenAndExpiryFromResponseJSON(jsonDict:[String:AnyObject]) -> (String?,NSDate?) { + var token: String? = nil + var expiry: NSDate? = nil + if let accessToken = jsonDict["access_token"] as? String { + token = accessToken + } + if let expiresIn = jsonDict["expires_in"] as? Int { + let expiresInAdjusted = expiresIn - 5000 + expiry = NSDate(timeIntervalSinceNow: Double(expiresInAdjusted)) + } + return (token,expiry) + } + + func performUserAuthRequest(userAuth:UsergridUserAuth, request:UsergridRequest, completion:UsergridUserAuthCompletionBlock?) { + session.dataTaskWithRequest(request.buildNSURLRequest()) { (data, response, error) -> Void in + let dataAsJSON = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) + if let jsonDict = dataAsJSON as? [String:AnyObject] { + let tokenAndExpiry = UsergridRequestManager.getTokenAndExpiryFromResponseJSON(jsonDict) + userAuth.accessToken = tokenAndExpiry.0 + userAuth.expiry = tokenAndExpiry.1 + + var user: UsergridUser? + if let userDict = jsonDict[UsergridUser.USER_ENTITY_TYPE] as? [String:AnyObject] { + if let createdUser = UsergridEntity.entity(jsonDict: userDict) as? UsergridUser { + createdUser.auth = userAuth + user = createdUser + } + } + if let createdUser = user { + completion?(auth: userAuth, user:createdUser, error: nil) + } else { + let error = UsergridResponseError(jsonDictionary: jsonDict) ?? UsergridResponseError(errorName: "Auth Failed.", errorDescription: "Error Description: \(error?.localizedDescription).") + completion?(auth: userAuth, user:nil, error:error) + } + } else { + let error = UsergridResponseError(errorName: "Auth Failed.", errorDescription: "Error Description: \(error?.localizedDescription).") + completion?(auth: userAuth, user:nil, error: error) + } + }.resume() + } + + func performAppAuthRequest(appAuth: UsergridAppAuth, request: UsergridRequest, completion: UsergridAppAuthCompletionBlock?) { + session.dataTaskWithRequest(request.buildNSURLRequest()) { (data, response, error) -> Void in + let dataAsJSON = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) + if let jsonDict = dataAsJSON as? [String:AnyObject] { + let tokenAndExpiry = UsergridRequestManager.getTokenAndExpiryFromResponseJSON(jsonDict) + appAuth.accessToken = tokenAndExpiry.0 + appAuth.expiry = tokenAndExpiry.1 + completion?(auth: appAuth, error: nil) + } else { + let error = UsergridResponseError(errorName: "Auth Failed.", errorDescription: "Error Description: \(error?.localizedDescription).") + completion?(auth: nil, error: error) + } + }.resume() + } +} + +// MARK: - Asset Management - +extension UsergridRequestManager { + + func performAssetDownload(contentType:String, usergridRequest:UsergridRequest, progress: UsergridAssetRequestProgress? = nil, completion:UsergridAssetDownloadCompletion? = nil) { + let downloadTask = session.downloadTaskWithRequest(usergridRequest.buildNSURLRequest()) + let requestWrapper = UsergridAssetRequestWrapper(session: self.session, sessionTask: downloadTask, progress: progress) { (request) -> Void in + if let assetData = request.responseData where assetData.length > 0 { + let asset = UsergridAsset(data: assetData, contentType: contentType) + completion?(asset: asset, error:nil) + } else { + completion?(asset: nil, error: "Downloading asset failed. No data was recieved.") + } + } + self.sessionDelegate.addRequestDelegate(requestWrapper.sessionTask, requestWrapper:requestWrapper) + requestWrapper.sessionTask.resume() + } + + func performAssetUpload(usergridRequest:UsergridAssetUploadRequest, progress:UsergridAssetRequestProgress? = nil, completion: UsergridAssetUploadCompletion? = nil) { + let uploadTask = session.uploadTaskWithRequest(usergridRequest.buildNSURLRequest(), fromData: usergridRequest.multiPartHTTPBody) + let requestWrapper = UsergridAssetRequestWrapper(session: self.session, sessionTask: uploadTask, progress: progress) { [weak self] (request) -> Void in + completion?(response: UsergridResponse(client: self?.client, data: request.responseData, response: request.response as? NSHTTPURLResponse, error: request.error),asset:usergridRequest.asset,error:nil) + } + self.sessionDelegate.addRequestDelegate(requestWrapper.sessionTask, requestWrapper:requestWrapper) + requestWrapper.sessionTask.resume() + } +} \ 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/UsergridResponse.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridResponse.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridResponse.swift new file mode 100644 index 0000000..012c82f --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridResponse.swift @@ -0,0 +1,203 @@ +// +// UsergridResponse.swift +// UsergridSDK +// +// Created by Robert Walsh on 9/2/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 completion block used in for most `UsergridClient` requests. +public typealias UsergridResponseCompletion = (response: UsergridResponse) -> Void + +/** +`UsergridResponse` is the core class that handles both successful and unsuccessful HTTP responses from Usergrid. + +If a request is successful, any entities returned in the response will be automatically parsed into `UsergridEntity` objects and pushed to the `entities` property. + +If a request fails, the `errorName` and `errorDescription` will contain information about the problem encountered. +*/ +public class UsergridResponse: NSObject { + + // MARK: - Instance Properties - + + /// The client that was responsible for the request. + public weak var client: UsergridClient? + + /// The raw response JSON. + internal(set) public var responseJSON: [String:AnyObject]? + + /// The query used on the request. + internal(set) public var query: UsergridQuery? + + /// The cursor from the response. + internal(set) public var cursor: String? + + /// The entities created from the response JSON. + internal(set) public var entities: [UsergridEntity]? + + /// The response headers. + internal(set) public var headers: [String:String]? + + /// The response status code. + internal(set) public var statusCode: Int? + + /// The error object containing error information if one occurred. + internal(set) public var error: UsergridResponseError? + + /// Returns true if the HTTP status code from the response is less than 400. + public var ok : Bool { + var isOk = false + if let statusCode = self.statusCode { + isOk = (statusCode < 400) + } + return isOk + } + + /// The count of `entities`. + public var count: Int { return self.entities?.count ?? 0 } + + /// The first entity in `entities`. + public var first: UsergridEntity? { return self.entities?.first } + + /// The last entity in `entities`. + public var last: UsergridEntity? { return self.entities?.last } + + /// The first entity in `entities`. + public var entity: UsergridEntity? { return self.first } + + /// The `UsergridUser` entity. + public var user: UsergridUser? { return self.entities?.first as? UsergridUser } + + /// An array of `UsergridUser` entities. + public var users: [UsergridUser]? { return self.entities as? [UsergridUser] } + + /// Does the response have a cursor. + public var hasNextPage: Bool { return self.cursor != nil } + + /// The string value. + public var stringValue : String? { + if let responseJSON = self.responseJSON { + return NSString(data: try! NSJSONSerialization.dataWithJSONObject(responseJSON, options: .PrettyPrinted), encoding: NSASCIIStringEncoding) as? String + } else { + return error?.description + } + } + + /// The description. + public override var description : String { + return "Response Description: \(stringValue)." + } + + /// The debug description. + public override var debugDescription : String { + return "Properties of Entity: \(stringValue)." + } + + // MARK: - Initialization - + + /** + Designated initializer for `UsergridResponse` objects that contain errors. + + These types of responses are usually created because request conditions are not met. + + - parameter client: The client responsible for the request. + - parameter errorName: The error name. + - parameter errorDescription: The error description. + + - returns: A new instance of `UsergridResponse`. + */ + public init(client: UsergridClient?, errorName: String, errorDescription: String) { + self.client = client + self.error = UsergridResponseError(errorName: errorName, errorDescription: errorDescription, exception: nil) + } + + /** + Designated initializer for `UsergridResponse` objects finished but still may contain errors. + + - parameter client: The client responsible for the request. + - parameter data: The response data. + - parameter response: The `NSHTTPURLResponse` object. + - parameter error: The `NSError` object. + - parameter query: The query when making the request. + + - returns: A new instance of `UsergridResponse`. + */ + public init(client:UsergridClient?, data:NSData?, response:NSHTTPURLResponse?, error:NSError?, query:UsergridQuery? = nil) { + self.client = client + self.statusCode = response?.statusCode + self.headers = response?.allHeaderFields as? [String:String] + + if let sessionError = error { + self.error = UsergridResponseError(errorName: sessionError.domain, errorDescription: sessionError.localizedDescription) + } + + if let responseQuery = query { + self.query = responseQuery.copy() as? UsergridQuery + } + + if let jsonData = data { + do { + let dataAsJSON = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers) + if let jsonDict = dataAsJSON as? [String:AnyObject] { + self.responseJSON = jsonDict + if let responseError = UsergridResponseError(jsonDictionary: jsonDict) { + self.error = responseError + } else { + if let entitiesJSONArray = jsonDict[UsergridResponse.ENTITIES] as? [[String:AnyObject]] where entitiesJSONArray.count > 0 { + self.entities = UsergridEntity.entities(jsonArray: entitiesJSONArray) + } + if let cursor = jsonDict[UsergridResponse.CURSOR] as? String where !cursor.isEmpty { + self.cursor = cursor + } + } + } + } catch { + print(error) + } + } + } + + // MARK: - Instance Methods - + + /** + Attempts to load the next page of `UsergridEntity` objects. + + This requires a `cursor` to be valid as well as a `path` key within the response JSON. + + - parameter completion: The completion block that is called once the request for the next page has finished. + */ + public func loadNextPage(completion: UsergridResponseCompletion) { + if self.hasNextPage, let type = (self.responseJSON?["path"] as? NSString)?.lastPathComponent { + if let query = self.query?.copy() as? UsergridQuery { + self.client?.GET(type, query: query.cursor(self.cursor), completion:completion) + } else { + self.client?.GET(type, query: UsergridQuery(type).cursor(self.cursor), completion:completion) + } + } else { + completion(response: UsergridResponse(client: self.client, errorName: "No next page.", errorDescription: "No next page was found.")) + } + } + + static let CURSOR = "cursor" + static let ENTITIES = "entities" +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridResponseError.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridResponseError.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridResponseError.swift new file mode 100644 index 0000000..eda8a30 --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridResponseError.swift @@ -0,0 +1,90 @@ +// +// UsergridResponseError.swift +// UsergridSDK +// +// Created by Robert Walsh on 1/8/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 + +/// A standard error object that contains details about a request failure. +public class UsergridResponseError: NSObject { + + // MARK: - Instance Properties - + + /// The error's name. + public let errorName : String + + /// The error's description. + public let errorDescription: String + + /// The exception. + public var exception: String? + + /// The description. + public override var description : String { + return "Error Name: \(errorName). Error Description: \(errorDescription). Exception: \(exception)." + } + + /// The debug description. + public override var debugDescription : String { + return "Error Name: \(errorName). Error Description: \(errorDescription). Exception: \(exception)." + } + + // MARK: - Initialization - + + /** + Designated initializer for `UsergridResponseError`. + + - parameter errorName: The error's name. + - parameter errorDescription: The error's description. + - parameter exception: The exception. + + - returns: A new instance of `UsergridResponseError` + */ + public init(errorName:String, errorDescription:String, exception:String? = nil) { + self.errorName = errorName + self.errorDescription = errorDescription + self.exception = exception + } + + /** + Convenience initializer for `UsergridResponseError` that determines if the given `jsonDictionary` contains an error. + + - parameter jsonDictionary: The JSON dictionary that may contain error information. + + - returns: A new instance of `UsergridResponseError` if the JSON dictionary did indeed contain error information. + */ + public convenience init?(jsonDictionary:[String:AnyObject]) { + if let errorName = jsonDictionary[USERGRID_ERROR] as? String, + errorDescription = jsonDictionary[USERGRID_ERROR_DESCRIPTION] as? String { + self.init(errorName:errorName,errorDescription:errorDescription,exception:jsonDictionary[USERGRID_EXCEPTION] as? String) + } else { + self.init(errorName:"",errorDescription:"") + return nil + } + } +} + +let USERGRID_ERROR = "error" +let USERGRID_ERROR_DESCRIPTION = "error_description" +let USERGRID_EXCEPTION = "exception" \ 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/UsergridSessionDelegate.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridSessionDelegate.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridSessionDelegate.swift new file mode 100644 index 0000000..cb36fb7 --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridSessionDelegate.swift @@ -0,0 +1,90 @@ +// +// UsergridSessionDelegate.swift +// UsergridSDK +// +// Created by Robert Walsh on 9/30/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 + +final class UsergridSessionDelegate: NSObject { + + private var requestDelegates: [Int:UsergridAssetRequestWrapper] = [:] + + func addRequestDelegate(task:NSURLSessionTask,requestWrapper:UsergridAssetRequestWrapper) { + requestDelegates[task.taskIdentifier] = requestWrapper + } + + func removeRequestDelegate(task:NSURLSessionTask) { + requestDelegates[task.taskIdentifier] = nil + } +} + +extension UsergridSessionDelegate : NSURLSessionTaskDelegate { + + func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { + if let progressBlock = requestDelegates[task.taskIdentifier]?.progress { + progressBlock(bytesFinished:totalBytesSent, bytesExpected: totalBytesExpectedToSend) + } + } + + func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { + if let requestWrapper = requestDelegates[task.taskIdentifier] { + requestWrapper.error = error + requestWrapper.completion(requestWrapper: requestWrapper) + } + self.removeRequestDelegate(task) + } +} + +extension UsergridSessionDelegate : NSURLSessionDataDelegate { + + func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { + if let requestWrapper = requestDelegates[dataTask.taskIdentifier] { + requestWrapper.response = response + } + completionHandler(NSURLSessionResponseDisposition.Allow) + } + + func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) { + if let requestWrapper = requestDelegates[dataTask.taskIdentifier] { + let mutableData = requestWrapper.responseData != nil ? NSMutableData(data: requestWrapper.responseData!) : NSMutableData() + mutableData.appendData(data) + requestWrapper.responseData = mutableData + } + } +} + +extension UsergridSessionDelegate : NSURLSessionDownloadDelegate { + + func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { + if let progressBlock = requestDelegates[downloadTask.taskIdentifier]?.progress { + progressBlock(bytesFinished:totalBytesWritten, bytesExpected: totalBytesExpectedToWrite) + } + } + + func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) { + if let requestWrapper = requestDelegates[downloadTask.taskIdentifier] { + requestWrapper.responseData = NSData(contentsOfURL: location)! + } + } +} \ 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/UsergridUser.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridUser.swift b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridUser.swift new file mode 100644 index 0000000..b1eedcc --- /dev/null +++ b/sdks/swift/Samples/Push/Pods/UsergridSDK/sdks/swift/Source/UsergridUser.swift @@ -0,0 +1,441 @@ +// +// User.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 + +/// The completion block used for checking email and/or username availablity for new `UsergridUser` objects. +public typealias UsergridUserAvailabilityCompletion = (error: UsergridResponseError?, available:Bool) -> Void + +/// The completion block used for changing the password of `UsergridUser` objects. +public typealias UsergridUserResetPasswordCompletion = (error: UsergridResponseError?, didSucceed:Bool) -> Void + +/** +`UsergridUser` is a special subclass of `UsergridEntity` that supports functions and properties unique to users. +*/ +public class UsergridUser : UsergridEntity { + + static let USER_ENTITY_TYPE = "user" + + // MARK: - Instance Properties - + + /// The `UsergridUserAuth` object if this user was authenticated. + public var auth: UsergridUserAuth? + + /** + Property helper method for the `UsergridUser` objects `UsergridUserProperties.Name`. + + Unlike `UsergridEntity` objects, `UsergridUser`'s can change their name property which is why we provide a getter here. + */ + override public var name: String? { + set(name) { self[UsergridUserProperties.Name.stringValue] = name } + get{ return super.name } + } + + /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Username`. + public var username: String? { + set(username) { self[UsergridUserProperties.Username.stringValue] = username } + get { return self.getUserSpecificProperty(.Username) as? String } + } + + /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Password`. + public var password: String? { + set(password) { self[UsergridUserProperties.Password.stringValue] = password } + get { return self.getUserSpecificProperty(.Password) as? String } + } + + /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Email`. + public var email: String? { + set(email) { self[UsergridUserProperties.Email.stringValue] = email } + get { return self.getUserSpecificProperty(.Email) as? String } + } + + /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Age`. + public var age: NSNumber? { + set(age) { self[UsergridUserProperties.Age.stringValue] = age } + get { return self.getUserSpecificProperty(.Age) as? NSNumber } + } + + /// Property helper method to get the username or email of the `UsergridUser`. + public var usernameOrEmail: String? { return self.username ?? self.email } + + /** + Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Activated`. + + Indicates whether the user account has been activated or not. + */ + public var activated: Bool { + set(activated) { self[UsergridUserProperties.Activated.stringValue] = activated } + get { return self.getUserSpecificProperty(.Activated) as? Bool ?? false } + } + + /// Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Disabled`. + public var disabled: Bool { + set(disabled) { self[UsergridUserProperties.Disabled.stringValue] = disabled } + get { return self.getUserSpecificProperty(.Disabled) as? Bool ?? false } + } + + /** + Property getter and setter helpers for the `UsergridUser` objects `UsergridUserProperties.Picture`. + + URL path to userâs profile picture. Defaults to Gravatar for email address. + */ + public var picture: String? { + set(picture) { self[UsergridUserProperties.Picture.stringValue] = picture } + get { return self.getUserSpecificProperty(.Picture) as? String } + } + + /// The UUID or username property value if found. + public var uuidOrUsername: String? { return self.uuid ?? self.username } + + // MARK: - Initialization - + + /** + Designated initializer for `UsergridUser` objects. + + - parameter name: The name of the user. Note this is different from the `username` property. + + - returns: A new instance of `UsergridUser`. + */ + public init(name:String? = nil) { + super.init(type: UsergridUser.USER_ENTITY_TYPE, name:name, propertyDict:nil) + } + + /** + 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 `UsergridUser` object. + */ + required public init(type: String, name: String?, propertyDict: [String : AnyObject]?) { + super.init(type: type, name: name, propertyDict: propertyDict) + } + + /** + Designated initializer for `UsergridUser` objects. + + - parameter name: The name of the user. Note this is different from the `username` property. + - parameter propertyDict: The optional property dictionary that the `UsergridEntity` object will start out with. + + - returns: A new instance of `UsergridUser`. + */ + public init(name:String,propertyDict:[String:AnyObject]? = nil) { + super.init(type: UsergridUser.USER_ENTITY_TYPE, name:name, propertyDict:propertyDict) + } + + /** + Convenience initializer for `UsergridUser` objects. + + - parameter name: The name of the user. Note this is different from the `username` property. + - parameter email: The user's email. + - parameter password: The optional user's password. + + - returns: A new instance of `UsergridUser`. + */ + public convenience init(name:String, email:String, password:String? = nil) { + self.init(name:name,email:email,username:nil,password:password) + } + + /** + Convenience initializer for `UsergridUser` objects. + + - parameter email: The user's email. + - parameter password: The optional user's password. + + - returns: A new instance of `UsergridUser`. + */ + public convenience init(email:String, password:String? = nil) { + self.init(name:nil,email:email,username:nil,password:password) + } + + /** + Convenience initializer for `UsergridUser` objects. + + - parameter name: The name of the user. Note this is different from the `username` property. + - parameter username: The username of the user. + - parameter password: The optional user's password. + + - returns: A new instance of `UsergridUser`. + */ + public convenience init(name:String, username:String, password:String? = nil) { + self.init(name:name,email:nil,username:username,password:password) + } + + /** + Convenience initializer for `UsergridUser` objects. + + - parameter username: The username of the user. + - parameter password: The optional user's password. + + - returns: A new instance of `UsergridUser`. + */ + public convenience init(username:String, password:String? = nil) { + self.init(name:nil,email:nil,username:username,password:password) + } + + /** + Convenience initializer for `UsergridUser` objects. + + - parameter name: The optional name of the user. Note this is different from the `username` property. + - parameter email: The optional user's email. + - parameter username: The optional username of the user. + - parameter password: The optional user's password. + + - returns: A new instance of `UsergridUser`. + */ + public convenience init(name:String?, email:String?, username:String?, password:String? = nil) { + self.init(name:name) + self.email = email + self.username = username + self.password = password + } + + // MARK: - NSCoding - + + /** + NSCoding protocol initializer. + + - parameter aDecoder: The decoder. + + - returns: A decoded `UsergridUser` object. + */ + required public init?(coder aDecoder: NSCoder) { + self.auth = aDecoder.decodeObjectForKey("auth") as? UsergridUserAuth + super.init(coder: aDecoder) + } + + /** + NSCoding protocol encoder. + + - parameter aCoder: The encoder. + */ + public override func encodeWithCoder(aCoder: NSCoder) { + aCoder.encodeObject(self.auth, forKey: "auth") + super.encodeWithCoder(aCoder) + } + + // MARK: - Class Methods - + + /** + Checks the given email and/or username availablity for new `UsergridUser` objects using the shared instance of `UsergridClient`. + + - parameter email: The optional email address. + - parameter username: The optional username. + - parameter completion: The completion block. + */ + public static func checkAvailable(email:String?, username:String?, completion:UsergridUserAvailabilityCompletion) { + self.checkAvailable(Usergrid.sharedInstance, email: email, username: username, completion: completion) + } + + /** + Checks the given email and/or username availablity for new `UsergridUser` objects using with the given `UsergridClient`. + + - parameter client: The client to use for checking availability. + - parameter email: The optional email address. + - parameter username: The optional username. + - parameter completion: The completion block. + */ + public static func checkAvailable(client: UsergridClient, email:String?, username:String?, completion:UsergridUserAvailabilityCompletion) { + let query = UsergridQuery(USER_ENTITY_TYPE) + if let emailValue = email { + query.eq(UsergridUserProperties.Email.stringValue, value: emailValue) + } + if let usernameValue = username { + query.or().eq(UsergridUserProperties.Username.stringValue, value: usernameValue) + } + client.GET(USER_ENTITY_TYPE, query: query) { (response) -> Void in + completion(error: response.error, available: response.entity == nil) + } + } + + // MARK: - Instance Methods - + + /** + Creates the user object in Usergrid if the user does not already exist with the shared instance of `UsergridClient`. + + - parameter completion: The optional completion block. + */ + public func create(completion: UsergridResponseCompletion? = nil) { + self.create(Usergrid.sharedInstance, completion: completion) + } + + /** + Creates the user object in Usergrid if the user does not already exist with the given `UsergridClient`. + + - parameter client: The client to use for creation. + - parameter completion: The optional completion block. + */ + public func create(client: UsergridClient, completion: UsergridResponseCompletion? = nil) { + client.POST(self,completion:completion) + } + + /** + Authenticates the specified user using the provided username and password with the shared instance of `UsergridClient`. + + While functionally similar to `UsergridClient.authenticateUser(auth)`, this method does not automatically assign this user to `UsergridClient.currentUser`: + + - parameter username: The username. + - parameter password: The password. + - parameter completion: The optional completion block. + */ + public func login(username:String, password:String, completion: UsergridUserAuthCompletionBlock? = nil) { + self.login(Usergrid.sharedInstance, username: username, password: password, completion: completion) + } + + /** + Authenticates the specified user using the provided username and password. + + While functionally similar to `UsergridClient.authenticateUser(auth)`, this method does not automatically assign this user to `UsergridClient.currentUser`: + + - parameter client: The client to use for login. + - parameter username: The username. + - parameter password: The password. + - parameter completion: The optional completion block. + */ + public func login(client: UsergridClient, username:String, password:String, completion: UsergridUserAuthCompletionBlock? = nil) { + let userAuth = UsergridUserAuth(username: username, password: password) + client.authenticateUser(userAuth,setAsCurrentUser:false) { [weak self] (auth, user, error) -> Void in + self?.auth = userAuth + completion?(auth: userAuth, user: user, error: error) + } + } + + /** + Changes the User's current password with the shared instance of `UsergridClient`. + + - parameter old: The old password. + - parameter new: The new password. + - parameter completion: The optional completion block. + */ + public func resetPassword(old:String, new:String, completion:UsergridUserResetPasswordCompletion? = nil) { + self.resetPassword(Usergrid.sharedInstance, old: old, new: new, completion: completion) + } + + /** + Changes the User's current password with the shared instance of `UsergridClient`. + + - parameter client: The client to use for resetting the password. + - parameter old: The old password. + - parameter new: The new password. + - parameter completion: The optional completion block + */ + public func resetPassword(client: UsergridClient, old:String, new:String, completion:UsergridUserResetPasswordCompletion? = nil) { + client.resetPassword(self, old: old, new: new, completion: completion) + } + + /** + Attmepts to reauthenticate using the user's `UsergridUserAuth` instance property with the shared instance of `UsergridClient`. + + - parameter completion: The optional completion block. + */ + public func reauthenticate(completion: UsergridUserAuthCompletionBlock? = nil) { + self.reauthenticate(Usergrid.sharedInstance, completion: completion) + } + + /** + Attmepts to reauthenticate using the user's `UsergridUserAuth` instance property. + + - parameter client: The client to use for reauthentication. + - parameter completion: The optional completion block. + */ + public func reauthenticate(client: UsergridClient, completion: UsergridUserAuthCompletionBlock? = nil) { + if let userAuth = self.auth { + client.authenticateUser(userAuth, completion: completion) + } else { + let error = UsergridResponseError(errorName: "Invalid UsergridUserAuth.", errorDescription: "No UsergridUserAuth found on the UsergridUser.") + completion?(auth: nil, user: self, error: error) + } + } + + /** + Invalidates the user token locally and remotely. + + - parameter completion: The optional completion block. + */ + public func logout(completion:UsergridResponseCompletion? = nil) { + self.logout(Usergrid.sharedInstance,completion:completion) + } + + /** + Invalidates the user token locally and remotely. + + - parameter client: The client to use for logout. + - parameter completion: The optional completion block. + */ + public func logout(client: UsergridClient, completion:UsergridResponseCompletion? = nil) { + if self === client.currentUser { + client.logoutCurrentUser(completion) + } else if let uuidOrUsername = self.uuidOrUsername, accessToken = self.auth?.accessToken { + client.logoutUser(uuidOrUsername, token: accessToken) { (response) in + self.auth = nil + completion?(response: response) + } + } else { + completion?(response: UsergridResponse(client:client, errorName:"Logout Failed.", errorDescription:"UUID or Access Token not found on UsergridUser object.")) + } + } + + private func getUserSpecificProperty(userProperty: UsergridUserProperties) -> AnyObject? { + var propertyValue: AnyObject? = super[userProperty.stringValue] + NSJSONReadingOptions.AllowFragments + switch userProperty { + case .Activated,.Disabled : + propertyValue = propertyValue?.boolValue + case .Age : + propertyValue = propertyValue?.integerValue + case .Name,.Username,.Password,.Email,.Picture : + break + } + return propertyValue + } + + /** + Subscript for the `UsergridUser` class. + + - Warning: When setting a properties value must be a valid JSON object. + + - Example usage: + ``` + let someName = usergridUser["name"] + + usergridUser["name"] = someName + ``` + */ + override public subscript(propertyName: String) -> AnyObject? { + get { + if let userProperty = UsergridUserProperties.fromString(propertyName) { + return self.getUserSpecificProperty(userProperty) + } else { + return super[propertyName] + } + } + set(propertyValue) { + super[propertyName] = propertyValue + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Push.xcodeproj/project.pbxproj ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Push.xcodeproj/project.pbxproj b/sdks/swift/Samples/Push/Push.xcodeproj/project.pbxproj new file mode 100644 index 0000000..cbd1e3e --- /dev/null +++ b/sdks/swift/Samples/Push/Push.xcodeproj/project.pbxproj @@ -0,0 +1,386 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 637A720E1C5BF8160056545A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637A72061C5BF8160056545A /* AppDelegate.swift */; }; + 637A720F1C5BF8160056545A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 637A72071C5BF8160056545A /* Assets.xcassets */; }; + 637A72101C5BF8160056545A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 637A72081C5BF8160056545A /* LaunchScreen.storyboard */; }; + 637A72111C5BF8160056545A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 637A720A1C5BF8160056545A /* Main.storyboard */; }; + 637A72131C5BF8160056545A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637A720D1C5BF8160056545A /* ViewController.swift */; }; + 637A72161C5C06270056545A /* UsergridManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637A72151C5C06270056545A /* UsergridManager.swift */; }; + 93F1FDA07B9F97BFB25A2B6A /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73F3E0733C90D8FB3A70AF1A /* Pods.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 40784BA539B3C7FC7074887B /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; }; + 637A71F01C5BF7B10056545A /* Push.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Push.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 637A72061C5BF8160056545A /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; + 637A72071C5BF8160056545A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; + 637A72091C5BF8160056545A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; + 637A720B1C5BF8160056545A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; + 637A720C1C5BF8160056545A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + 637A720D1C5BF8160056545A /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; }; + 637A72151C5C06270056545A /* UsergridManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UsergridManager.swift; sourceTree = "<group>"; }; + 73F3E0733C90D8FB3A70AF1A /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9BB4D667087D6CF002BECEB1 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 637A71ED1C5BF7B10056545A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 93F1FDA07B9F97BFB25A2B6A /* Pods.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 11B1DE4765D09F54EEAA5FB4 /* Pods */ = { + isa = PBXGroup; + children = ( + 40784BA539B3C7FC7074887B /* Pods.debug.xcconfig */, + 9BB4D667087D6CF002BECEB1 /* Pods.release.xcconfig */, + ); + name = Pods; + sourceTree = "<group>"; + }; + 40B8DB4D5F8684F52D86AD13 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 73F3E0733C90D8FB3A70AF1A /* Pods.framework */, + ); + name = Frameworks; + sourceTree = "<group>"; + }; + 637A71E71C5BF7B10056545A = { + isa = PBXGroup; + children = ( + 637A72051C5BF8160056545A /* Source */, + 637A71F11C5BF7B10056545A /* Products */, + 11B1DE4765D09F54EEAA5FB4 /* Pods */, + 40B8DB4D5F8684F52D86AD13 /* Frameworks */, + ); + sourceTree = "<group>"; + }; + 637A71F11C5BF7B10056545A /* Products */ = { + isa = PBXGroup; + children = ( + 637A71F01C5BF7B10056545A /* Push.app */, + ); + name = Products; + sourceTree = "<group>"; + }; + 637A72051C5BF8160056545A /* Source */ = { + isa = PBXGroup; + children = ( + 637A72061C5BF8160056545A /* AppDelegate.swift */, + 637A720D1C5BF8160056545A /* ViewController.swift */, + 637A72151C5C06270056545A /* UsergridManager.swift */, + 637A720A1C5BF8160056545A /* Main.storyboard */, + 637A72081C5BF8160056545A /* LaunchScreen.storyboard */, + 637A72141C5BF8220056545A /* Supporting Files */, + ); + path = Source; + sourceTree = "<group>"; + }; + 637A72141C5BF8220056545A /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 637A72071C5BF8160056545A /* Assets.xcassets */, + 637A720C1C5BF8160056545A /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 637A71EF1C5BF7B10056545A /* Push */ = { + isa = PBXNativeTarget; + buildConfigurationList = 637A72021C5BF7B10056545A /* Build configuration list for PBXNativeTarget "Push" */; + buildPhases = ( + 07DB92FBF16075B01449F26B /* Check Pods Manifest.lock */, + 637A71EC1C5BF7B10056545A /* Sources */, + 637A71ED1C5BF7B10056545A /* Frameworks */, + 637A71EE1C5BF7B10056545A /* Resources */, + 9A01B8F77A9D4469391D8826 /* Embed Pods Frameworks */, + EA12798F3DFFB01F69B53C53 /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Push; + productName = Push; + productReference = 637A71F01C5BF7B10056545A /* Push.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 637A71E81C5BF7B10056545A /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = "Apigee Inc."; + TargetAttributes = { + 637A71EF1C5BF7B10056545A = { + CreatedOnToolsVersion = 7.2; + }; + }; + }; + buildConfigurationList = 637A71EB1C5BF7B10056545A /* Build configuration list for PBXProject "Push" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 637A71E71C5BF7B10056545A; + productRefGroup = 637A71F11C5BF7B10056545A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 637A71EF1C5BF7B10056545A /* Push */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 637A71EE1C5BF7B10056545A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 637A72111C5BF8160056545A /* Main.storyboard in Resources */, + 637A720F1C5BF8160056545A /* Assets.xcassets in Resources */, + 637A72101C5BF8160056545A /* LaunchScreen.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 07DB92FBF16075B01449F26B /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 9A01B8F77A9D4469391D8826 /* Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + EA12798F3DFFB01F69B53C53 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 637A71EC1C5BF7B10056545A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 637A72161C5C06270056545A /* UsergridManager.swift in Sources */, + 637A72131C5BF8160056545A /* ViewController.swift in Sources */, + 637A720E1C5BF8160056545A /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 637A72081C5BF8160056545A /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 637A72091C5BF8160056545A /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = "<group>"; + }; + 637A720A1C5BF8160056545A /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 637A720B1C5BF8160056545A /* Base */, + ); + name = Main.storyboard; + sourceTree = "<group>"; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 637A72001C5BF7B10056545A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 637A72011C5BF7B10056545A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 637A72031C5BF7B10056545A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 40784BA539B3C7FC7074887B /* Pods.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + INFOPLIST_FILE = Source/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.usergrid.usergridpushsample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + }; + name = Debug; + }; + 637A72041C5BF7B10056545A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9BB4D667087D6CF002BECEB1 /* Pods.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + INFOPLIST_FILE = Source/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.usergrid.usergridpushsample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 637A71EB1C5BF7B10056545A /* Build configuration list for PBXProject "Push" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 637A72001C5BF7B10056545A /* Debug */, + 637A72011C5BF7B10056545A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 637A72021C5BF7B10056545A /* Build configuration list for PBXNativeTarget "Push" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 637A72031C5BF7B10056545A /* Debug */, + 637A72041C5BF7B10056545A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 637A71E81C5BF7B10056545A /* Project object */; +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Push.xcodeproj/project.xcworkspace/contents.xcworkspacedata ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Push.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/sdks/swift/Samples/Push/Push.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..5ff4e01 --- /dev/null +++ b/sdks/swift/Samples/Push/Push.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "self:Push.xcodeproj"> + </FileRef> +</Workspace> http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Push.xcworkspace/contents.xcworkspacedata ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Push.xcworkspace/contents.xcworkspacedata b/sdks/swift/Samples/Push/Push.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..d4ed8a6 --- /dev/null +++ b/sdks/swift/Samples/Push/Push.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Workspace + version = "1.0"> + <FileRef + location = "group:Push.xcodeproj"> + </FileRef> + <FileRef + location = "group:Pods/Pods.xcodeproj"> + </FileRef> +</Workspace> http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Push.xcworkspace/xcshareddata/Push.xcscmblueprint ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Push.xcworkspace/xcshareddata/Push.xcscmblueprint b/sdks/swift/Samples/Push/Push.xcworkspace/xcshareddata/Push.xcscmblueprint new file mode 100644 index 0000000..bec49ab --- /dev/null +++ b/sdks/swift/Samples/Push/Push.xcworkspace/xcshareddata/Push.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "E28DB29D4B8B9FB468FB340D2257B16682332D89", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "E28DB29D4B8B9FB468FB340D2257B16682332D89" : 0, + "AD57BFF635DD66DF5DF78257082332592EB51D31" : 0 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "ADB99685-1C5E-4D1B-99F9-59253396C726", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "E28DB29D4B8B9FB468FB340D2257B16682332D89" : "swift\/", + "AD57BFF635DD66DF5DF78257082332592EB51D31" : ".." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "Push", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Samples\/Push\/Push.xcworkspace", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:RobertWalsh\/usergrid.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "AD57BFF635DD66DF5DF78257082332592EB51D31" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:RobertWalsh\/UsergridSDK.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "E28DB29D4B8B9FB468FB340D2257B16682332D89" + } + ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/AppDelegate.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/AppDelegate.swift b/sdks/swift/Samples/Push/Source/AppDelegate.swift new file mode 100644 index 0000000..0ce64dd --- /dev/null +++ b/sdks/swift/Samples/Push/Source/AppDelegate.swift @@ -0,0 +1,53 @@ +// +// AppDelegate.swift +// Push +// +// Created by Robert Walsh on 1/29/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 UIKit +import UsergridSDK + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + + UsergridManager.initializeSharedInstance() + + application.registerUserNotificationSettings(UIUserNotificationSettings( forTypes: [.Alert, .Badge, .Sound], categories: nil)) + application.registerForRemoteNotifications() + + return true + } + + func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { + UsergridManager.applyPushToken(deviceToken) + } + + func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) { + print("Application failed to register for remote notifications") + } +} + http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/Assets.xcassets/AppIcon.appiconset/Contents.json ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/Assets.xcassets/AppIcon.appiconset/Contents.json b/sdks/swift/Samples/Push/Source/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..118c98f --- /dev/null +++ b/sdks/swift/Samples/Push/Source/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/Assets.xcassets/Contents.json ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/Assets.xcassets/Contents.json b/sdks/swift/Samples/Push/Source/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/sdks/swift/Samples/Push/Source/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/Assets.xcassets/UsergridGuy.imageset/Contents.json ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/Assets.xcassets/UsergridGuy.imageset/Contents.json b/sdks/swift/Samples/Push/Source/Assets.xcassets/UsergridGuy.imageset/Contents.json new file mode 100644 index 0000000..c19ad83 --- /dev/null +++ b/sdks/swift/Samples/Push/Source/Assets.xcassets/UsergridGuy.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "UsergridGuy.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/Assets.xcassets/UsergridGuy.imageset/UsergridGuy.png ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/Assets.xcassets/UsergridGuy.imageset/UsergridGuy.png b/sdks/swift/Samples/Push/Source/Assets.xcassets/UsergridGuy.imageset/UsergridGuy.png new file mode 100644 index 0000000..b8a6844 Binary files /dev/null and b/sdks/swift/Samples/Push/Source/Assets.xcassets/UsergridGuy.imageset/UsergridGuy.png differ http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/Base.lproj/LaunchScreen.storyboard ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/Base.lproj/LaunchScreen.storyboard b/sdks/swift/Samples/Push/Source/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..8326657 --- /dev/null +++ b/sdks/swift/Samples/Push/Source/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM"> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/> + </dependencies> + <scenes> + <!--View Controller--> + <scene sceneID="EHf-IW-A2E"> + <objects> + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/> + <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> + </view> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="53" y="375"/> + </scene> + </scenes> +</document> http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/Base.lproj/Main.storyboard ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/Base.lproj/Main.storyboard b/sdks/swift/Samples/Push/Source/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f1d2558 --- /dev/null +++ b/sdks/swift/Samples/Push/Source/Base.lproj/Main.storyboard @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r"> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/> + <capability name="Constraints to layout margins" minToolsVersion="6.0"/> + </dependencies> + <scenes> + <!--View Controller--> + <scene sceneID="tne-QT-ifu"> + <objects> + <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="Push" customModuleProvider="target" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/> + <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> + <rect key="frame" x="0.0" y="0.0" width="414" height="736"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="UsergridGuy" translatesAutoresizingMaskIntoConstraints="NO" id="SlS-IJ-WvF"> + <rect key="frame" x="102" y="263" width="210" height="210"/> + </imageView> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WKX-zU-FkH"> + <rect key="frame" x="102" y="45" width="210" height="210"/> + <color key="backgroundColor" red="1" green="1" blue="1" alpha="0.59999999999999998" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="210" id="Lip-pm-tI5"/> + </constraints> + <state key="normal" title="push to this device"> + <color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="pushToThisDevice:" destination="BYZ-38-t0r" eventType="touchUpInside" id="PyU-Dy-zGg"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="HVf-R4-fSL"> + <rect key="frame" x="102" y="481" width="210" height="210"/> + <color key="backgroundColor" red="1" green="1" blue="1" alpha="0.59999999999999998" colorSpace="calibratedRGB"/> + <state key="normal" title="push to all devices"> + <color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> + <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="pushToAllDevices:" destination="BYZ-38-t0r" eventType="touchUpInside" id="j7d-n8-KeM"/> + </connections> + </button> + </subviews> + <color key="backgroundColor" red="0.10196078431372549" green="0.42745098039215684" blue="0.59215686274509804" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstItem="WKX-zU-FkH" firstAttribute="trailing" secondItem="SlS-IJ-WvF" secondAttribute="trailing" id="143-qW-0PZ"/> + <constraint firstItem="HVf-R4-fSL" firstAttribute="leading" secondItem="SlS-IJ-WvF" secondAttribute="leading" id="3qa-G1-lcp"/> + <constraint firstItem="SlS-IJ-WvF" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="6oN-Cy-5xc"/> + <constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="HVf-R4-fSL" secondAttribute="bottom" constant="45" id="7Oq-1b-BlW"/> + <constraint firstItem="SlS-IJ-WvF" firstAttribute="top" secondItem="WKX-zU-FkH" secondAttribute="bottom" constant="8" symbolic="YES" id="B0h-XG-3pm"/> + <constraint firstItem="SlS-IJ-WvF" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="Hbg-BY-chR"/> + <constraint firstItem="SlS-IJ-WvF" firstAttribute="trailing" secondItem="HVf-R4-fSL" secondAttribute="trailing" id="KLV-Bs-7HU"/> + <constraint firstItem="WKX-zU-FkH" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="82" id="UDK-2x-rwK"/> + <constraint firstItem="HVf-R4-fSL" firstAttribute="top" secondItem="SlS-IJ-WvF" secondAttribute="bottom" constant="8" symbolic="YES" id="bBV-SP-lGh"/> + <constraint firstItem="WKX-zU-FkH" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="25" id="eh3-3a-qhv"/> + <constraint firstItem="WKX-zU-FkH" firstAttribute="leading" secondItem="SlS-IJ-WvF" secondAttribute="leading" id="gZr-gE-TxI"/> + </constraints> + </view> + <simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina55"/> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="335" y="350"/> + </scene> + </scenes> + <resources> + <image name="UsergridGuy" width="162" height="161"/> + </resources> +</document> http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/Info.plist ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/Info.plist b/sdks/swift/Samples/Push/Source/Info.plist new file mode 100644 index 0000000..6c48029 --- /dev/null +++ b/sdks/swift/Samples/Push/Source/Info.plist @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + <key>UIMainStoryboardFile</key> + <string>Main</string> + <key>UIRequiredDeviceCapabilities</key> + <array> + <string>armv7</string> + </array> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + </array> +</dict> +</plist> http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/UsergridManager.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/UsergridManager.swift b/sdks/swift/Samples/Push/Source/UsergridManager.swift new file mode 100644 index 0000000..a916b75 --- /dev/null +++ b/sdks/swift/Samples/Push/Source/UsergridManager.swift @@ -0,0 +1,72 @@ +// +// UsergridManager.swift +// Push +// +// Created by Robert Walsh on 1/19/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 +import UsergridSDK + +/// This class handles the primary communications to the UsergridSDK. +public class UsergridManager { + + static let ORG_ID = "rwalsh" + static let APP_ID = "sandbox" + static let NOTIFIER_ID = "usergridpushsample" + static let BASE_URL = "https://api.usergrid.com" + + static func initializeSharedInstance() { + Usergrid.initSharedInstance(configuration: UsergridClientConfig(orgId: UsergridManager.ORG_ID, appId: UsergridManager.APP_ID, baseUrl: UsergridManager.BASE_URL)) + } + + static func applyPushToken(deviceToken:NSData) { + Usergrid.applyPushToken(deviceToken, notifierID: UsergridManager.NOTIFIER_ID, completion: { (response) -> Void in + print("Apply token completed successfully : \(response.ok)") + if !response.ok, let errorDescription = response.error?.errorDescription { + print("Error Description : \(errorDescription)") + } + }) + } + + static func sendPush(deviceId deviceId:String,message:String) { + let pushRequest = UsergridRequest(method: .Post, + baseUrl: Usergrid.clientAppURL, + paths: ["devices",deviceId,"notifications"], + auth: Usergrid.authForRequests(), + jsonBody: ["payloads":[UsergridManager.NOTIFIER_ID:message]]) + Usergrid.sendRequest(pushRequest, completion: { (response) -> Void in + print("Push request completed successfully : \(response.ok)") + if !response.ok, let errorDescription = response.error?.errorDescription { + print("Error Description : \(errorDescription)") + } + }) + } + + static func pushToThisDevice() { + UsergridManager.sendPush(deviceId: UsergridDevice.sharedDevice.uuid, message: "Push to this device message.") + } + + static func pushToAllDevices() { + UsergridManager.sendPush(deviceId: "*", message: "Push to all devices message.") + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Push/Source/ViewController.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Push/Source/ViewController.swift b/sdks/swift/Samples/Push/Source/ViewController.swift new file mode 100644 index 0000000..d1e3247 --- /dev/null +++ b/sdks/swift/Samples/Push/Source/ViewController.swift @@ -0,0 +1,39 @@ +// +// ViewController.swift +// Push +// +// Created by Robert Walsh on 1/29/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 UIKit + +class ViewController: UIViewController { + + @IBAction func pushToThisDevice(sender: AnyObject) { + UsergridManager.pushToThisDevice() + } + + @IBAction func pushToAllDevices(sender: AnyObject) { + UsergridManager.pushToAllDevices() + } +} + http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/Readme.md ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/Readme.md b/sdks/swift/Samples/Readme.md new file mode 100644 index 0000000..4c5601f --- /dev/null +++ b/sdks/swift/Samples/Readme.md @@ -0,0 +1,25 @@ +#UsergridSDK Sample Apps + +The sample apps in this directory are intended to show basic usage of some of the major features of the UsergridSDK. + +Each sample application utilizes `Cocoapods` to interact with the UsergridSDK. + +##Samples Apps + +* **ActivityFeed** - An app that demonstrates a wide variety of operations within the SDK. This app also contains a companion WatchOS application. + +* **Push** - An app that registers for and sends push notifications. + +##Configuring the Sample Apps + +Before running the sample applications you will need to configure each sample application. + +Each sample application should include a source file named `UsergridManager.swift`. This source file is used to contain interaction with the UsergridSDK within a single source file. In doing so, the interactions within the sample apps can be easily seen and examined. + +Within the `UsergridManager.swift` source there will be at least two different static vars named `ORG_ID` and `APP_ID`. You will need to configure those values in order to run the applications in your environment. + +Applications which utilize push notifications will require a valid provisioning profile and device for the push services to work correctly. + +## Running the Sample Apps + +To run the sample apps, simply open the <SAMPLE APP NAME>.xcworkspace file in Xcode, then run the app. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Source/Info.plist ---------------------------------------------------------------------- diff --git a/sdks/swift/Source/Info.plist b/sdks/swift/Source/Info.plist new file mode 100644 index 0000000..d3de8ee --- /dev/null +++ b/sdks/swift/Source/Info.plist @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>$(EXECUTABLE_NAME)</string> + <key>CFBundleIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>$(PRODUCT_NAME)</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>$(CURRENT_PROJECT_VERSION)</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist>
