You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2016/02/18 16:52:44 UTC

[36/89] [partial] usergrid git commit: Initial commit of the Swift SDK.

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>