http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridUser.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridUser.swift b/sdks/swift/Samples/ActivityFeed/Pods/UsergridSDK/sdks/swift/Source/UsergridUser.swift new file mode 100644 index 0000000..b1eedcc --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/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/ActivityFeed/Source/ActivityEntity.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/ActivityEntity.swift b/sdks/swift/Samples/ActivityFeed/Source/ActivityEntity.swift new file mode 100644 index 0000000..5ddcf12 --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/Source/ActivityEntity.swift @@ -0,0 +1,60 @@ +// +// ActivityEntity.swift +// ActivityFeed +// +// Created by Robert Walsh on 1/20/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 + +public class ActivityEntity: UsergridEntity { + + public var actor: [String:AnyObject]? { return self["actor"] as? [String:AnyObject] } + + public var content: String? { return self["content"] as? String } + + public var displayName: String? { return self.actor?["displayName"] as? String } + + public var email: String? { return self.actor?["email"] as? String } + + public var imageInfo: [String:AnyObject]? { return self.actor?["image"] as? [String:AnyObject] } + + public var imageURL: String? { return self.imageInfo?["url"] as? String } + + static func registerSubclass() { + UsergridEntity.mapCustomType("activity", toSubclass: ActivityEntity.self) + } + + required public init(type: String, name: String?, propertyDict: [String : AnyObject]?) { + super.init(type: type, name: name, propertyDict: propertyDict) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + public override func encodeWithCoder(aCoder: NSCoder) { + super.encodeWithCoder(aCoder) + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Source/AppDelegate.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/AppDelegate.swift b/sdks/swift/Samples/ActivityFeed/Source/AppDelegate.swift new file mode 100644 index 0000000..cca5c41 --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/Source/AppDelegate.swift @@ -0,0 +1,65 @@ +// +// AppDelegate.swift +// ActivityFeed +// +// Created by Robert Walsh on 11/19/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 UIKit +import UsergridSDK + +// TODO: Change the values to correspond to your organization, application, and notifier identifiers. + +@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + + UINavigationBar.appearance().tintColor = UIColor.whiteColor() + application.registerUserNotificationSettings(UIUserNotificationSettings( forTypes: [.Alert, .Badge, .Sound], categories: nil)) + application.registerForRemoteNotifications() + + // Initialize the Usergrid shared instance. + UsergridManager.initializeSharedInstance() + + // If there is a current user already logged in from the keychain we will skip the login page and go right to the chat screen + + if Usergrid.currentUser != nil { + let rootViewController = self.window!.rootViewController as! UINavigationController + let loginViewController = rootViewController.viewControllers.first! + loginViewController.performSegueWithIdentifier("loginSuccessNonAnimatedSegue", sender: loginViewController) + } + + return true + } + + func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { + Usergrid.applyPushToken(deviceToken, notifierID: UsergridManager.NOTIFIER_ID, completion: nil) + } + + 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/ActivityFeed/Source/Assets.xcassets/AppIcon.appiconset/Contents.json ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/Assets.xcassets/AppIcon.appiconset/Contents.json b/sdks/swift/Samples/ActivityFeed/Source/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..118c98f --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/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/ActivityFeed/Source/Assets.xcassets/Contents.json ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/Assets.xcassets/Contents.json b/sdks/swift/Samples/ActivityFeed/Source/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/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/ActivityFeed/Source/Assets.xcassets/UsergridGuy.imageset/Contents.json ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/Assets.xcassets/UsergridGuy.imageset/Contents.json b/sdks/swift/Samples/ActivityFeed/Source/Assets.xcassets/UsergridGuy.imageset/Contents.json new file mode 100644 index 0000000..c19ad83 --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/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/ActivityFeed/Source/Assets.xcassets/UsergridGuy.imageset/UsergridGuy.png ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/Assets.xcassets/UsergridGuy.imageset/UsergridGuy.png b/sdks/swift/Samples/ActivityFeed/Source/Assets.xcassets/UsergridGuy.imageset/UsergridGuy.png new file mode 100644 index 0000000..b8a6844 Binary files /dev/null and b/sdks/swift/Samples/ActivityFeed/Source/Assets.xcassets/UsergridGuy.imageset/UsergridGuy.png differ http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Source/Base.lproj/LaunchScreen.storyboard ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/Base.lproj/LaunchScreen.storyboard b/sdks/swift/Samples/ActivityFeed/Source/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..78686cd --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/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="15C50" 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/ActivityFeed/Source/Base.lproj/Main.storyboard ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/Base.lproj/Main.storyboard b/sdks/swift/Samples/ActivityFeed/Source/Base.lproj/Main.storyboard new file mode 100644 index 0000000..5f38e98 --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/Source/Base.lproj/Main.storyboard @@ -0,0 +1,371 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="0Ca-En-eac"> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/> + <capability name="Constraints to layout margins" minToolsVersion="6.0"/> + </dependencies> + <scenes> + <!--Navigation Controller--> + <scene sceneID="b6o-SG-nHZ"> + <objects> + <navigationController id="0Ca-En-eac" sceneMemberID="viewController"> + <simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina55"/> + <navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="kgZ-6Y-2Hs"> + <rect key="frame" x="0.0" y="0.0" width="320" height="44"/> + <autoresizingMask key="autoresizingMask"/> + <color key="barTintColor" red="0.10196078431372549" green="0.41176470588235292" blue="0.56862745098039214" alpha="1" colorSpace="calibratedRGB"/> + <textAttributes key="titleTextAttributes"> + <color key="textColor" red="0.97647058823529409" green="0.97647058823529409" blue="0.97647058823529409" alpha="1" colorSpace="calibratedRGB"/> + </textAttributes> + </navigationBar> + <connections> + <segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="JkM-3e-aQt"/> + </connections> + </navigationController> + <placeholder placeholderIdentifier="IBFirstResponder" id="KGr-0J-SBp" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="-191" y="350"/> + </scene> + <!--Chit-Chat--> + <scene sceneID="tne-QT-ifu"> + <objects> + <viewController title="Chit-Chat" id="BYZ-38-t0r" customClass="LoginViewController" customModule="SDKSample" 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="64" width="414" height="672"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Password" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="AUv-4K-02z" userLabel="Password Text Field" customClass="FormTextField" customModule="SDKSample" customModuleProvider="target"> + <rect key="frame" x="55" y="221" width="305" height="30"/> + <color key="backgroundColor" red="0.98039215686274506" green="0.98039215686274506" blue="0.98039215686274506" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="30" id="ttP-ff-vrA"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> + <textInputTraits key="textInputTraits" returnKeyType="done" secureTextEntry="YES"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="inset"> + <real key="value" value="10"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + <connections> + <outlet property="nextResponderField" destination="Pj4-c5-WOw" id="ndL-qj-xzY"/> + </connections> + </textField> + <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Username" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Z6O-sS-NMx" customClass="FormTextField" customModule="SDKSample" customModuleProvider="target"> + <rect key="frame" x="54" y="183" width="305" height="30"/> + <color key="backgroundColor" red="0.98431372549019602" green="0.98431372549019602" blue="0.98431372549019602" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="30" id="Dcr-HX-coh"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> + <textInputTraits key="textInputTraits" returnKeyType="next"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="inset"> + <real key="value" value="10"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + <connections> + <outlet property="nextResponderField" destination="AUv-4K-02z" id="NLo-pL-jk4"/> + </connections> + </textField> + <button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Pj4-c5-WOw" userLabel="Sign In "> + <rect key="frame" x="54" y="287" width="305" height="45"/> + <color key="backgroundColor" red="0.10196078431372549" green="0.41568627450980394" blue="0.58039215686274515" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="45" id="iPw-MQ-dMe"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/> + <state key="normal" title="Sign In"> + <color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> + </state> + <connections> + <action selector="loginButtonTouched:" destination="BYZ-38-t0r" eventType="touchUpInside" id="I2Z-mw-as5"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JLH-ZA-uPM"> + <rect key="frame" x="128" y="360" width="157" height="30"/> + <constraints> + <constraint firstAttribute="width" constant="157" id="Wo1-xd-zeb"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/> + <state key="normal" title="Create Account"> + <color key="titleColor" red="0.090196078431372548" green="0.33725490196078434" blue="0.50588235294117645" alpha="1" colorSpace="calibratedRGB"/> + </state> + <connections> + <segue destination="bnr-oZ-e0h" kind="show" identifier="signUpSegue" id="NXY-Nd-h56"/> + </connections> + </button> + <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="UsergridGuy" translatesAutoresizingMaskIntoConstraints="NO" id="t6Y-SG-C6M"> + <rect key="frame" x="128" y="41" width="169" height="105"/> + </imageView> + </subviews> + <color key="backgroundColor" red="0.92941176470588238" green="0.94509803921568625" blue="0.94509803921568625" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstItem="Pj4-c5-WOw" firstAttribute="top" secondItem="AUv-4K-02z" secondAttribute="bottom" constant="36" id="0Go-pE-u4p"/> + <constraint firstItem="AUv-4K-02z" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="35" id="2Xa-2C-BzP"/> + <constraint firstAttribute="trailingMargin" secondItem="t6Y-SG-C6M" secondAttribute="trailing" constant="97" id="BQF-rx-fX4"/> + <constraint firstItem="Z6O-sS-NMx" firstAttribute="trailing" secondItem="Pj4-c5-WOw" secondAttribute="trailing" id="CLi-7t-9Bm"/> + <constraint firstItem="Z6O-sS-NMx" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="34" id="H8h-Dc-gGd"/> + <constraint firstItem="AUv-4K-02z" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="ML2-oF-zNc"/> + <constraint firstItem="AUv-4K-02z" firstAttribute="top" secondItem="Z6O-sS-NMx" secondAttribute="bottom" constant="8" symbolic="YES" id="T1u-Ae-7qT"/> + <constraint firstItem="t6Y-SG-C6M" firstAttribute="leading" secondItem="JLH-ZA-uPM" secondAttribute="leading" id="UkI-we-10P"/> + <constraint firstItem="Pj4-c5-WOw" firstAttribute="top" secondItem="8bC-Xf-vdC" secondAttribute="top" constant="287" id="WHX-b2-vXU"/> + <constraint firstItem="JLH-ZA-uPM" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="adR-S0-Zw5"/> + <constraint firstItem="Z6O-sS-NMx" firstAttribute="top" secondItem="t6Y-SG-C6M" secondAttribute="bottom" constant="37" id="cDN-ea-Z7L"/> + <constraint firstItem="t6Y-SG-C6M" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="41" id="ciX-r9-UzJ"/> + <constraint firstItem="JLH-ZA-uPM" firstAttribute="top" secondItem="Pj4-c5-WOw" secondAttribute="bottom" constant="28" id="h7B-Kf-fPS"/> + <constraint firstItem="Z6O-sS-NMx" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="183" id="lIk-q4-Kkm"/> + <constraint firstItem="Z6O-sS-NMx" firstAttribute="leading" secondItem="Pj4-c5-WOw" secondAttribute="leading" id="wi1-xU-x6C"/> + <constraint firstItem="JLH-ZA-uPM" firstAttribute="centerX" secondItem="Pj4-c5-WOw" secondAttribute="centerX" id="xPz-Hj-Iv4"/> + </constraints> + </view> + <navigationItem key="navigationItem" id="9X6-oC-0Ku"> + <barButtonItem key="backBarButtonItem" title=" " id="saf-1i-WZ7"/> + </navigationItem> + <simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina55"/> + <connections> + <outlet property="passwordTextField" destination="AUv-4K-02z" id="ck2-dw-K3H"/> + <outlet property="usernameTextField" destination="Z6O-sS-NMx" id="jz7-0z-YRA"/> + <segue destination="e2L-gy-keG" kind="show" identifier="loginSuccessSegue" id="yFG-ee-xdi"/> + <segue destination="e2L-gy-keG" kind="show" identifier="loginSuccessNonAnimatedSegue" animates="NO" id="jbi-vT-etg"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="414" y="362"/> + </scene> + <!--Chat--> + <scene sceneID="xKw-pF-1VK"> + <objects> + <viewController storyboardIdentifier="Chat" id="e2L-gy-keG" customClass="MessageViewController" customModule="SDKSample" customModuleProvider="target" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="l0J-tj-N8R"/> + <viewControllerLayoutGuide type="bottom" id="aRQ-i9-bBv"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="gFB-Jy-DrN"> + <rect key="frame" x="0.0" y="64" width="414" height="672"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" red="0.90980392156862744" green="0.93333333333333335" blue="0.92941176470588238" alpha="1" colorSpace="calibratedRGB"/> + </view> + <extendedEdge key="edgesForExtendedLayout" bottom="YES"/> + <navigationItem key="navigationItem" title="Chat" id="A1Z-Fm-fb7" userLabel="Chat"> + <barButtonItem key="backBarButtonItem" title=" " id="lTa-eA-MlI"/> + <barButtonItem key="rightBarButtonItem" title="Follow" id="oWz-oN-r0q"> + <connections> + <segue destination="dZf-Pa-FEf" kind="show" id="4hi-xR-y7a"/> + </connections> + </barButtonItem> + </navigationItem> + <simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina55"/> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="KDg-MX-rlV" userLabel="First Responder" sceneMemberID="firstResponder"/> + <exit id="Vtr-ga-m5m" userLabel="Exit" sceneMemberID="exit"/> + </objects> + <point key="canvasLocation" x="873" y="692"/> + </scene> + <!--Follow--> + <scene sceneID="L1J-vW-kjp"> + <objects> + <viewController id="dZf-Pa-FEf" customClass="FollowViewController" customModule="SDKSample" customModuleProvider="target" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="bqC-DA-7jl"/> + <viewControllerLayoutGuide type="bottom" id="WfX-kG-aQR"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="qAg-Dl-t9F"> + <rect key="frame" x="0.0" y="64" width="414" height="672"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dSM-Kh-jtM" userLabel="Sign In "> + <rect key="frame" x="55" y="304" width="305" height="45"/> + <color key="backgroundColor" red="0.090196078431372548" green="0.33333333333333331" blue="0.49411764705882355" alpha="1" colorSpace="calibratedRGB"/> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/> + <state key="normal" title="Add Follower"> + <color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> + </state> + <connections> + <action selector="addFollowerButtonTouched:" destination="dZf-Pa-FEf" eventType="touchUpInside" id="yuv-da-ArK"/> + </connections> + </button> + <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Username" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="30w-Hq-z3n" customClass="FormTextField" customModule="SDKSample" customModuleProvider="target"> + <rect key="frame" x="55" y="229" width="305" height="30"/> + <color key="backgroundColor" red="0.98431372549999996" green="0.98431372549999996" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="30" id="VgQ-oU-xSh"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> + <textInputTraits key="textInputTraits" returnKeyType="next"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="inset"> + <real key="value" value="10"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + <connections> + <outlet property="nextResponderField" destination="dSM-Kh-jtM" id="JKY-WD-0wK"/> + </connections> + </textField> + </subviews> + <color key="backgroundColor" red="0.90980392156862744" green="0.93333333333333335" blue="0.92941176470588238" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstItem="30w-Hq-z3n" firstAttribute="leading" secondItem="qAg-Dl-t9F" secondAttribute="leadingMargin" constant="35" id="ETC-Hj-qu0"/> + <constraint firstItem="dSM-Kh-jtM" firstAttribute="leading" secondItem="30w-Hq-z3n" secondAttribute="leading" id="MrI-EB-S4Q"/> + <constraint firstItem="dSM-Kh-jtM" firstAttribute="centerX" secondItem="qAg-Dl-t9F" secondAttribute="centerX" id="XGA-b6-Kbm"/> + <constraint firstItem="dSM-Kh-jtM" firstAttribute="top" secondItem="30w-Hq-z3n" secondAttribute="bottom" constant="45" id="hYz-y9-k2e"/> + <constraint firstItem="30w-Hq-z3n" firstAttribute="trailing" secondItem="dSM-Kh-jtM" secondAttribute="trailing" id="jBo-UK-A49"/> + <constraint firstItem="WfX-kG-aQR" firstAttribute="top" secondItem="dSM-Kh-jtM" secondAttribute="bottom" constant="323" id="l8c-Ap-E9b"/> + <constraint firstItem="30w-Hq-z3n" firstAttribute="top" secondItem="bqC-DA-7jl" secondAttribute="bottom" constant="229" id="p7k-Gp-8pf"/> + </constraints> + </view> + <navigationItem key="navigationItem" title="Follow" id="j5X-9C-znz"> + <barButtonItem key="backBarButtonItem" id="HXY-KA-xWY"/> + </navigationItem> + <simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina55"/> + <connections> + <outlet property="usernameTextField" destination="30w-Hq-z3n" id="QcA-z0-XWe"/> + <segue destination="Vtr-ga-m5m" kind="unwind" identifier="unwindToChatSegue" unwindAction="unwindToChat:" id="uwe-tT-3Yl"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="P87-dE-iQW" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="1334" y="692"/> + </scene> + <!--Create Account--> + <scene sceneID="KTq-tk-yrN"> + <objects> + <viewController title="Create Account" id="bnr-oZ-e0h" customClass="RegisterViewController" customModule="SDKSample" customModuleProvider="target" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="54e-JK-PBR"/> + <viewControllerLayoutGuide type="bottom" id="JWP-YK-0Zj"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="8bt-vM-LeI"> + <rect key="frame" x="0.0" y="64" width="414" height="672"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Name" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="X55-Ni-6OO" customClass="FormTextField" customModule="SDKSample" customModuleProvider="target"> + <rect key="frame" x="55" y="112" width="305" height="30"/> + <color key="backgroundColor" red="0.98431372549999996" green="0.98431372549999996" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="30" id="e0c-yJ-CZz"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> + <textInputTraits key="textInputTraits" returnKeyType="next"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="inset"> + <real key="value" value="10"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + <connections> + <outlet property="nextResponderField" destination="T7U-9G-AS6" id="HUF-el-scZ"/> + </connections> + </textField> + <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Username" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="T7U-9G-AS6" userLabel="Username Text Field" customClass="FormTextField" customModule="SDKSample" customModuleProvider="target"> + <rect key="frame" x="55" y="150" width="305" height="30"/> + <color key="backgroundColor" red="0.98431372549999996" green="0.98431372549999996" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="30" id="AdR-w9-g8s"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> + <textInputTraits key="textInputTraits" returnKeyType="next"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="inset"> + <real key="value" value="10"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + <connections> + <outlet property="nextResponderField" destination="Fbi-gF-0jQ" id="sjv-Dm-5GL"/> + </connections> + </textField> + <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Email" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Fbi-gF-0jQ" customClass="FormTextField" customModule="SDKSample" customModuleProvider="target"> + <rect key="frame" x="55" y="188" width="305" height="30"/> + <color key="backgroundColor" red="0.98431372549999996" green="0.98431372549999996" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="30" id="BEM-zO-uYG"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> + <textInputTraits key="textInputTraits" keyboardType="emailAddress" returnKeyType="next"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="inset"> + <real key="value" value="10"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + <connections> + <outlet property="nextResponderField" destination="3wi-7s-j5P" id="eE7-9Y-L0t"/> + </connections> + </textField> + <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Password" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="3wi-7s-j5P" userLabel="Password Text Field" customClass="FormTextField" customModule="SDKSample" customModuleProvider="target"> + <rect key="frame" x="55" y="226" width="305" height="30"/> + <color key="backgroundColor" red="0.98431372549999996" green="0.98431372549999996" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstAttribute="height" constant="30" id="N5y-wK-RFi"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/> + <textInputTraits key="textInputTraits" returnKeyType="done" secureTextEntry="YES"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="inset"> + <real key="value" value="10"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + <connections> + <outlet property="nextResponderField" destination="1LM-SB-xON" id="igH-69-KP4"/> + </connections> + </textField> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1LM-SB-xON" userLabel="Create Account Button"> + <rect key="frame" x="129" y="311" width="157" height="30"/> + <constraints> + <constraint firstAttribute="width" constant="157" id="FnB-G6-Riq"/> + <constraint firstAttribute="height" constant="30" id="q9P-Oj-aoj"/> + </constraints> + <fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/> + <state key="normal" title="Create Account"> + <color key="titleColor" red="0.090196078431372548" green="0.33333333333333331" blue="0.49019607843137253" alpha="1" colorSpace="calibratedRGB"/> + </state> + <connections> + <action selector="registerButtonTouched:" destination="bnr-oZ-e0h" eventType="touchUpInside" id="GSH-40-K9q"/> + </connections> + </button> + </subviews> + <color key="backgroundColor" red="0.90980392156862744" green="0.93333333333333335" blue="0.92941176470588238" alpha="1" colorSpace="calibratedRGB"/> + <constraints> + <constraint firstItem="Fbi-gF-0jQ" firstAttribute="top" secondItem="T7U-9G-AS6" secondAttribute="bottom" constant="8" symbolic="YES" id="47R-E5-Snv"/> + <constraint firstItem="X55-Ni-6OO" firstAttribute="leading" secondItem="8bt-vM-LeI" secondAttribute="leadingMargin" constant="35" id="4AX-MS-GG7"/> + <constraint firstItem="3wi-7s-j5P" firstAttribute="centerX" secondItem="1LM-SB-xON" secondAttribute="centerX" id="6sW-Fh-Rab"/> + <constraint firstItem="X55-Ni-6OO" firstAttribute="top" secondItem="54e-JK-PBR" secondAttribute="bottom" constant="112" id="8Po-i9-42g"/> + <constraint firstItem="Fbi-gF-0jQ" firstAttribute="leading" secondItem="3wi-7s-j5P" secondAttribute="leading" id="Aun-rI-OR3"/> + <constraint firstItem="T7U-9G-AS6" firstAttribute="leading" secondItem="X55-Ni-6OO" secondAttribute="leading" id="BdL-Nz-LD6"/> + <constraint firstItem="Fbi-gF-0jQ" firstAttribute="trailing" secondItem="3wi-7s-j5P" secondAttribute="trailing" id="KdZ-Tm-Bwx"/> + <constraint firstItem="T7U-9G-AS6" firstAttribute="trailing" secondItem="X55-Ni-6OO" secondAttribute="trailing" id="RYI-tz-VCv"/> + <constraint firstItem="Fbi-gF-0jQ" firstAttribute="trailing" secondItem="T7U-9G-AS6" secondAttribute="trailing" id="fw6-6b-cmI"/> + <constraint firstItem="3wi-7s-j5P" firstAttribute="top" secondItem="Fbi-gF-0jQ" secondAttribute="bottom" constant="8" symbolic="YES" id="geo-x8-ZFP"/> + <constraint firstItem="Fbi-gF-0jQ" firstAttribute="leading" secondItem="T7U-9G-AS6" secondAttribute="leading" id="jQL-Ia-0fq"/> + <constraint firstItem="1LM-SB-xON" firstAttribute="top" secondItem="3wi-7s-j5P" secondAttribute="bottom" constant="55" id="p5i-2x-Yya"/> + <constraint firstItem="X55-Ni-6OO" firstAttribute="centerX" secondItem="8bt-vM-LeI" secondAttribute="centerX" id="qHj-O7-Oze"/> + <constraint firstItem="T7U-9G-AS6" firstAttribute="top" secondItem="X55-Ni-6OO" secondAttribute="bottom" constant="8" symbolic="YES" id="wCb-xG-olD"/> + </constraints> + </view> + <navigationItem key="navigationItem" title="Create Account" id="fQg-sg-1cB"/> + <simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina55"/> + <connections> + <outlet property="emailTextField" destination="Fbi-gF-0jQ" id="6Uc-Fs-euO"/> + <outlet property="nameTextField" destination="X55-Ni-6OO" id="6dQ-5q-zzP"/> + <outlet property="passwordTextField" destination="3wi-7s-j5P" id="978-dQ-Xd1"/> + <outlet property="usernameTextField" destination="T7U-9G-AS6" id="K2o-PS-UxH"/> + <segue destination="Zoo-Jg-Iad" kind="unwind" identifier="unwindSegue" unwindAction="unwind:" id="gdP-wh-1Zx"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="VBd-vg-SN9" userLabel="First Responder" sceneMemberID="firstResponder"/> + <exit id="Zoo-Jg-Iad" userLabel="Exit" sceneMemberID="exit"/> + </objects> + <point key="canvasLocation" x="873" y="-128"/> + </scene> + </scenes> + <resources> + <image name="UsergridGuy" width="162" height="161"/> + </resources> + <inferredMetricsTieBreakers> + <segue reference="yFG-ee-xdi"/> + </inferredMetricsTieBreakers> +</document> http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Source/FollowViewController.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/FollowViewController.swift b/sdks/swift/Samples/ActivityFeed/Source/FollowViewController.swift new file mode 100644 index 0000000..1f33fb5 --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/Source/FollowViewController.swift @@ -0,0 +1,49 @@ +// +// FollowViewController.swift +// ActivityFeed +// +// Created by Robert Walsh on 1/21/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 + +class FollowViewController : UIViewController { + + @IBOutlet weak var usernameTextField: UITextField! + + @IBAction func addFollowerButtonTouched(sender:AnyObject?) { + guard let username = usernameTextField.text where !username.isEmpty + else { + self.showAlert(title: "Follow failed.", message: "Please enter a valid username.") + return + } + + UsergridManager.followUser(username) { (response) -> Void in + if response.ok { + self.performSegueWithIdentifier("unwindToChatSegue", sender: self) + } else { + self.showAlert(title: "Follow failed.", message: "No user with the username \"\(username)\" found.") + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Source/FormTextField.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/FormTextField.swift b/sdks/swift/Samples/ActivityFeed/Source/FormTextField.swift new file mode 100644 index 0000000..9a79022 --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/Source/FormTextField.swift @@ -0,0 +1,71 @@ +// +// FormTextField.swift +// ActivityFeed +// +// Created by Robert Walsh on 1/21/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 UIKit + +@IBDesignable class FormTextField: UITextField { + + @IBInspectable var inset: CGFloat = 0 + @IBOutlet weak var nextResponderField: UIResponder? + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setUp() + } + + override init(frame: CGRect) { + super.init(frame: frame) + setUp() + } + + func setUp() { + addTarget(self, action: "actionKeyboardButtonTapped:", forControlEvents: .EditingDidEndOnExit) + } + + func actionKeyboardButtonTapped(sender: UITextField) { + switch nextResponderField { + case let button as UIButton: + if button.enabled { + button.sendActionsForControlEvents(.TouchUpInside) + } else { + resignFirstResponder() + } + case .Some(let responder): + responder.becomeFirstResponder() + default: + resignFirstResponder() + } + } + + override func textRectForBounds(bounds: CGRect) -> CGRect { + return CGRectInset(bounds, inset, 0) + } + + override func editingRectForBounds(bounds: CGRect) -> CGRect { + return textRectForBounds(bounds) + } +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Source/Info.plist ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/Info.plist b/sdks/swift/Samples/ActivityFeed/Source/Info.plist new file mode 100644 index 0000000..2ea3512 --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/Source/Info.plist @@ -0,0 +1,43 @@ +<?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>NSAppTransportSecurity</key> + <dict> + <key>NSAllowsArbitraryLoads</key> + <true/> + </dict> + <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/ActivityFeed/Source/LoginViewController.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/LoginViewController.swift b/sdks/swift/Samples/ActivityFeed/Source/LoginViewController.swift new file mode 100644 index 0000000..76f8d8b --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/Source/LoginViewController.swift @@ -0,0 +1,76 @@ +// +// LoginViewController.swift +// ActivityFeed +// +// Created by Robert Walsh on 1/21/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 + +class LoginViewController: UIViewController { + + @IBOutlet weak var usernameTextField: UITextField! + @IBOutlet weak var passwordTextField: UITextField! + + override func viewWillAppear(animated: Bool) { + super.viewWillAppear(animated) + self.passwordTextField.text = nil + } + + override func viewDidAppear(animated: Bool) { + Usergrid.logoutCurrentUser() + super.viewDidAppear(animated) + } + + override func viewWillDisappear(animated: Bool) { + super.viewWillDisappear(animated) + self.view.endEditing(true) + } + + @IBAction func loginButtonTouched(sender: AnyObject) { + guard let username = usernameTextField.text where !username.isEmpty, + let password = passwordTextField.text where !password.isEmpty + else { + self.showAlert(title: "Error Authenticating User", message: "Username and password must not be empty.") + return; + } + + self.loginUser(username, password: password) + } + + func loginUser(username:String, password:String) { + UsergridManager.loginUser(username,password: password) { (auth, user, error) -> Void in + if let authErrorDescription = error { + self.showAlert(title: "Error Authenticating User", message: authErrorDescription.errorDescription) + } else if let authenticatedUser = user { + self.showAlert(title: "Authenticated User Successful", message: "User description: \n \(authenticatedUser.stringValue)") { (action) -> Void in + self.performSegueWithIdentifier("loginSuccessSegue", sender: self) + } + } + } + } + + @IBAction func unwind(segue: UIStoryboardSegue) { + // Used for unwind segues back to this view controller. + } +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Source/MessageTableViewCell.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/MessageTableViewCell.swift b/sdks/swift/Samples/ActivityFeed/Source/MessageTableViewCell.swift new file mode 100644 index 0000000..a77abd8 --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/Source/MessageTableViewCell.swift @@ -0,0 +1,101 @@ +// +// MessageTableViewCell.swift +// ActivityFeed +// +// Created by Robert Walsh on 11/24/15. +// +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + * + */ + +import Foundation +import UIKit + +public class MessageTableViewCell : UITableViewCell { + + var titleLabel : UILabel + var bodyLabel : UILabel + var thumbnailView : UIImageView + var indexPath : NSIndexPath? + + public static let kMessageTableViewCellMinimumHeight: CGFloat = 50.0; + public static let kMessageTableViewCellAvatarHeight: CGFloat = 30.0; + + static var defaultFontSize: CGFloat { + return 16.0 + } + + override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + self.titleLabel = UILabel(frame: CGRect.zero) + self.bodyLabel = UILabel(frame: CGRect.zero) + self.thumbnailView = UIImageView(frame: CGRect.zero) + + super.init(style: style, reuseIdentifier: reuseIdentifier) + + self.selectionStyle = UITableViewCellSelectionStyle.None + self.backgroundColor = UIColor.whiteColor() + self.configureSubviews() + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override public func prepareForReuse() { + self.selectionStyle = UITableViewCellSelectionStyle.None + self.titleLabel.font = UIFont.boldSystemFontOfSize(MessageTableViewCell.defaultFontSize) + self.bodyLabel.font = UIFont.boldSystemFontOfSize(13) + self.titleLabel.text = "" + self.bodyLabel.text = "" + } + + func configureSubviews() { + self.titleLabel.translatesAutoresizingMaskIntoConstraints = false + self.titleLabel.backgroundColor = UIColor.clearColor() + self.titleLabel.userInteractionEnabled = false + self.titleLabel.numberOfLines = 0 + self.titleLabel.textColor = UIColor.grayColor() + self.titleLabel.font = UIFont.boldSystemFontOfSize(MessageTableViewCell.defaultFontSize) + + self.bodyLabel.translatesAutoresizingMaskIntoConstraints = false + self.bodyLabel.backgroundColor = UIColor.clearColor() + self.bodyLabel.userInteractionEnabled = false + self.bodyLabel.numberOfLines = 0 + self.bodyLabel.textColor = UIColor.grayColor() + self.bodyLabel.font = UIFont.boldSystemFontOfSize(13) + + self.thumbnailView.translatesAutoresizingMaskIntoConstraints = false + self.thumbnailView.userInteractionEnabled = false + self.thumbnailView.backgroundColor = UIColor(white: 0.9, alpha: 1.0) + self.thumbnailView.layer.cornerRadius = 15 + self.thumbnailView.layer.masksToBounds = true + + self.contentView.addSubview(self.thumbnailView) + self.contentView.addSubview(self.titleLabel) + self.contentView.addSubview(self.bodyLabel) + + let views = ["thumbnailView":self.thumbnailView, "titleLabel":self.titleLabel, "bodyLabel":self.bodyLabel] + let metrics = ["thumbSize":MessageTableViewCell.kMessageTableViewCellAvatarHeight, "padding":15, "right":10, "left":5] + + self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-left-[thumbnailView(thumbSize)]-right-[titleLabel(>=0)]-right-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) + self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-left-[thumbnailView(thumbSize)]-right-[bodyLabel(>=0)]-right-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) + self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-right-[titleLabel(20)]-left-[bodyLabel(>=0@999)]-left-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) + self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-right-[thumbnailView(thumbSize)]-(>=0)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/usergrid/blob/7442c881/sdks/swift/Samples/ActivityFeed/Source/MessageTextView.swift ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Source/MessageTextView.swift b/sdks/swift/Samples/ActivityFeed/Source/MessageTextView.swift new file mode 100644 index 0000000..135372e --- /dev/null +++ b/sdks/swift/Samples/ActivityFeed/Source/MessageTextView.swift @@ -0,0 +1,39 @@ +// +// MessageTextView.swift +// ActivityFeed +// +// Created by Robert Walsh on 11/24/15. +// +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. The ASF licenses this file to You + * under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. For additional information regarding + * copyright in this work, please see the NOTICE file in the top level + * directory of this distribution. + * + */ + +import Foundation +import SlackTextViewController + +class MessageTextView : SLKTextView { + override func willMoveToSuperview(newSuperview: UIView?) { + super.willMoveToSuperview(newSuperview) + self.backgroundColor = UIColor.whiteColor() + self.placeholderColor = UIColor.lightGrayColor() + self.placeholder = "Message" + self.pastableMediaTypes = .None + self.layer.borderColor = UIColor(red: 217/255, green: 217/255, blue: 217/255, alpha: 1.0).CGColor + } +}
