Created
February 12, 2016 17:48
-
-
Save mingsai/35d10e434a97584bab23 to your computer and use it in GitHub Desktop.
A Swift class to help manage cloud events using Apple's CloudKit platform. This is the experimental version.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // MNGCloudManager.swift | |
| // | |
| // | |
| // Created by Tommie N. Carter, Jr., MBA on 7/25/15. | |
| // Copyright © 2015 MING Technology. All rights reserved. | |
| // | |
| import Foundation | |
| import CloudKit | |
| import CoreData | |
| import UIKit | |
| enum StoryType { | |
| case Audio, Text, Picture, Video | |
| static let allValues = [Audio, Text, Picture, Video] | |
| } | |
| struct MNGCloudKitEvents { | |
| static let AccessError = "Cloud Access Error" | |
| static let SaveError = "Save Error" | |
| static let SaveSuccess = "Success" | |
| static let NoMatchFound = "No Match Found" | |
| static let MatchFound = "Match Found" | |
| static let ErrorOccurred = "Error Occurred" | |
| static let DeleteSuccess = "Delete Success" | |
| static let DeleteError = "Delete Error" | |
| static let ProcessCompleted = "ProcessCompleted" | |
| static let ProcessError = "Process Error" | |
| } | |
| struct MNGCloudAssetsRecord { | |
| static let RecordName = "Assets" | |
| static let AssetColumn = "asset" | |
| } | |
| struct MNGCloudSharedStoriesRecord { | |
| static let RecordName = "SharedStories" | |
| static let DateExpiresColumn = "dateExpires" | |
| static let LocationColumn = "location" | |
| static let StorySharedToListReferenceColumn = "sharedTo" | |
| static let StoryAssetColumn = "storyAsset" | |
| static let StoryTypeColumn = "type" //W|V|P|T | |
| static let StoryStatusColumn = "status" //use for public, private | |
| } | |
| struct MNGCloudInvitesRecord { | |
| static let RecordName = "Invites" | |
| static let DateJoinedColumn = "dateJoined" | |
| static let EmailColumn = "email" | |
| static let FamilyNameColumn = "familyName" | |
| static let GivenNameColumn = "givenName" | |
| static let PhoneColumn = "phone" | |
| static let StatusColumn = "status" | |
| static let NewUserIdReferenceColumn = "newUserId" | |
| } | |
| struct MNGCloudUserInfoRecord { | |
| static let RecordName = "Users" | |
| static let AppUserIdColumn = "appUserId" | |
| static let LocationColumn = "location" | |
| static let ProfilePhotoAssetColumn = "profilePhoto" | |
| } | |
| //Status = P(ending), R(egistered), F(ailed), B(locked) | |
| struct MNGCloudUserRegisterationRecord { | |
| static let RecordName = "Registered" | |
| static let DateExpiresColumn = "dateExpires" | |
| static let EmailColumn = "email" | |
| static let FamilyNameColumn = "familyName" | |
| static let GivenNameColumn = "givenName" | |
| static let PhoneColumn = "phone" | |
| static let SecretColumn = "secret" | |
| static let StatusColumn = "status" | |
| } | |
| @objc protocol MNGCloudManagerDelegate { | |
| optional func cloudManagerDidReturnKnownContacts(objects:[NSDictionary]) | |
| optional func cloudManagerDidReturnInvitesInfo(objects:[NSDictionary]) | |
| optional func cloudManagerDidReturnSharedStoryInfo(objects:[NSDictionary]) | |
| optional func cloudManagerDidReturnUser(id:String) | |
| optional func cloudManagerDidSaveStoryInfo(recordId:String) | |
| optional func cloudManagerDidFailToSaveStoryInfo(error:NSError) | |
| optional func cloudManagerDidSaveUserInfo(recordId:String) | |
| optional func cloudManagerDidSaveUserRegistrationInfo(recordId:String) | |
| optional func cloudManagerDidFailToSaveUserRegistrationInfo(error:NSError) | |
| optional func cloudManagerDidSaveInvitationInfo(recordId:String) | |
| optional func cloudManagerDidFailToSaveInvitationInfo(error:NSError) | |
| optional func cloudManagerDidFailWithCloudError (error: NSError) | |
| } | |
| class MNGCloudManager:NSObject { | |
| var delegate:MNGCloudManagerDelegate? = nil | |
| static let sharedInstance = MNGCloudManager() | |
| private struct Constants { | |
| static let CloudUserSubscribed = "CloudUserSubscribed" | |
| static let CloudUserSubscriptionID = "CloudUserScriptionID" | |
| static let SelectorCloudEventObserved = Selector ("cloudEventObserved:") | |
| } | |
| lazy var isSubscribed: Bool = { | |
| let keyfound = NSUserDefaults.standardUserDefaults().objectForKey(Constants.CloudUserSubscribed) != nil | |
| if !keyfound { | |
| //add default key value | |
| NSUserDefaults.standardUserDefaults().setBool(false, forKey: Constants.CloudUserSubscribed) | |
| } else if keyfound && NSUserDefaults.standardUserDefaults().boolForKey(Constants.CloudUserSubscribed) == true { | |
| return true | |
| } else { | |
| return false | |
| } | |
| return false | |
| }() | |
| let container = CKContainer.defaultContainer() | |
| lazy var publicDatabase:CKDatabase? = { | |
| return self.container.publicCloudDatabase | |
| }() | |
| lazy var privateDatabase:CKDatabase? = { | |
| return self.container.privateCloudDatabase | |
| }() | |
| deinit{ | |
| unregisterEventObservations() | |
| } | |
| override init(){ | |
| super.init() | |
| registerEventObservations() | |
| } | |
| //MARK: Shared Stories Methods | |
| func unshareStory(sharedID:CKRecordID){ | |
| } | |
| /* Saves the object graph to a CKAsset (fileURL) on the cloud 10 gb limit */ | |
| func shareStory(rootObject:AnyObject?, properties: [String: AnyObject?]) | |
| { | |
| //properties to set other than Story are Owner, SharedTo, Type | |
| guard rootObject != nil && properties.count != 0 else {return} | |
| let tmpPath = NSTemporaryDirectory() + NSUUID().UUIDString | |
| let tmpURL = NSURL(fileURLWithPath: tmpPath) | |
| let record = CKRecord(recordType: MNGCloudSharedStoriesRecord.RecordName) | |
| if NSKeyedArchiver.archiveRootObject(rootObject!, toFile: tmpPath) { | |
| let storyAsset = CKAsset(fileURL: tmpURL) | |
| record[MNGCloudSharedStoriesRecord.StoryAssetColumn] = storyAsset | |
| } | |
| for (key, value) in properties { | |
| record.setObject(value as? CKRecordValue, forKey: key)//(value, forKey: key) | |
| } | |
| publicDatabase!.saveRecord(record, completionHandler: | |
| ({returnRecord, error in | |
| if let err = error { | |
| self.notifyUser(MNGCloudKitEvents.SaveError, message: | |
| err.localizedDescription) | |
| } else { | |
| dispatch_async(dispatch_get_main_queue()) { | |
| //tell the delegate that the record was saved | |
| // self.notifyUser(MNGCloudKitEvents.CloudKitSavedSuccessTitle, | |
| // message: MNGCloudKitEvents.CloudKitSavedSuccessMessage) | |
| self.cleanupTempFile(tmpPath) | |
| } | |
| } | |
| })) | |
| } | |
| func share(story:AnyObject, user:String) { | |
| } | |
| func findSharedStoriesForUser(id:String) { | |
| } | |
| private func cleanupTempFile(atPath:String) { | |
| //cleanup the tmp file | |
| if NSFileManager.defaultManager().fileExistsAtPath(atPath) { | |
| do { | |
| try NSFileManager.defaultManager().removeItemAtPath(atPath) | |
| } catch let e as NSError { | |
| print(e.localizedDescription) | |
| } | |
| } | |
| } | |
| private func uploadAssetWithURL (assetURL:NSURL, completionHandler:(record:CKRecord)->()) { | |
| let assetRecord = CKRecord(recordType: MNGCloudAssetsRecord.RecordName) | |
| let asset = CKAsset(fileURL: assetURL) | |
| assetRecord[MNGCloudAssetsRecord.AssetColumn] = asset | |
| //TODO:Add properties to function call and loop to assign | |
| self.publicDatabase?.saveRecord(assetRecord, completionHandler: { (record, error) -> Void in | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| dispatch_async (dispatch_get_main_queue(), { () -> Void in | |
| //post notification with recordInfo | |
| //completionHandler(record); | |
| }) | |
| } | |
| }) | |
| } | |
| //MARK: Notification Methods | |
| func notifyUser(title: String, message: String) -> Void | |
| { | |
| let alert = UIAlertController(title: title, | |
| message: message, | |
| preferredStyle: UIAlertControllerStyle.Alert) | |
| let cancelAction = UIAlertAction(title: "OK", | |
| style: .Cancel, handler: nil) | |
| alert.addAction(cancelAction) | |
| //TODO: Create a listener to pick this up | |
| defaultCenter.postNotificationName(MNGCloudKitEvents.ProcessCompleted, object: alert) | |
| //send this as a notification object to a UIVC | |
| //self.presentViewController(alert, animated: true, completion: nil) | |
| } | |
| //MARK: Invite Methods | |
| func postInviteByPhone(phone:String){ | |
| } | |
| func postInviteByEmail(email:String){ | |
| } | |
| func updateInvite(record:CKRecord, status:String){ | |
| } | |
| //MARK: Registration Methods | |
| func postRegisteredUser(userID:String) { | |
| // call the function above in the following way: | |
| // (userID is the string you are intersted in!) | |
| findCurrentCKUser({ (instance, error) -> () in | |
| if let userID = instance?.recordName { | |
| print("received iCloudID \(userID)") | |
| } else { | |
| print("Fetched iCloudID was nil") | |
| } | |
| }) | |
| } | |
| //MARK: User Methods | |
| func configureCurrentCKUser (userInfo:NSDictionary) { | |
| if let container:CKContainer? = CKContainer.defaultContainer() { | |
| container!.fetchUserRecordIDWithCompletionHandler() { | |
| recordID, error in | |
| if error != nil { | |
| self.delegate?.cloudManagerDidFailWithCloudError!(error!) | |
| return | |
| } | |
| if let record:CKRecord? = CKRecord(recordType: "Users", recordID: recordID!) { | |
| //process user info | |
| if let photoAsset = userInfo[MNGCloudUserInfoRecord.ProfilePhotoAssetColumn] { | |
| record!.setObject(photoAsset as? CKAsset, forKey: MNGCloudUserInfoRecord.ProfilePhotoAssetColumn) | |
| } | |
| if let location = userInfo[MNGCloudUserInfoRecord.LocationColumn] { | |
| record!.setObject(location as? CLLocation, forKey: MNGCloudUserInfoRecord.LocationColumn) | |
| } | |
| if let appUserId = userInfo[MNGCloudUserInfoRecord.AppUserIdColumn] { | |
| record!.setObject(appUserId as? String, forKey: MNGCloudUserInfoRecord.AppUserIdColumn) | |
| } | |
| //save to cloud db | |
| self.publicDatabase?.saveRecord(record!, completionHandler: { (record, error) -> Void in | |
| if error != nil { | |
| //print(error!.localizedDescription) | |
| NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in | |
| self.delegate?.cloudManagerDidFailWithCloudError!(error!) | |
| }) | |
| return | |
| } | |
| NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in | |
| //print( self.delegate ) | |
| self.delegate?.cloudManagerDidSaveUserInfo!(record!.recordID.recordName) | |
| }) | |
| }) | |
| } | |
| } | |
| } | |
| } | |
| /// async gets iCloud record name of logged-in user | |
| func findCurrentCKUser(complete: (instance: CKRecordID?, error: NSError?) -> ()) { | |
| let container = CKContainer.defaultContainer() | |
| container.fetchUserRecordIDWithCompletionHandler() { | |
| recordID, error in | |
| if error != nil { | |
| print(error!.localizedDescription) | |
| complete(instance: nil, error: error) | |
| } else { | |
| print("fetched ID \(recordID?.recordName)") | |
| self.delegate?.cloudManagerDidReturnUser!(recordID!.recordName) | |
| complete(instance: recordID, error: nil) | |
| } | |
| } | |
| } | |
| func findUserByEmail (email:String) { | |
| } | |
| func findUserByPhone (phone:String) { | |
| } | |
| func findUsersInContactBook () { | |
| } | |
| func findContactsRelatedToUser() { | |
| let discoverOperation = CKDiscoverAllContactsOperation() | |
| discoverOperation.qualityOfService = NSQualityOfService.Background | |
| //discoverOperation.usesBackgroundSession = true | |
| discoverOperation.queuePriority = NSOperationQueuePriority.Normal | |
| discoverOperation.discoverAllContactsCompletionBlock = { | |
| (userInfos, error) in | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| //deal with the userInfos returned | |
| dispatch_async(dispatch_get_main_queue()) { [weak self] () -> Void in | |
| self?.notifyUser(MNGCloudKitEvents.MatchFound, | |
| message: MNGCloudKitEvents.MatchFound) | |
| //do something with the users' matching contacts | |
| //defaultCenter.postNotificationName(MNGCloudKitEvents.CloudKitMatchFound, object: userInfos.map{ ( $0 ) } ) | |
| } | |
| } | |
| } | |
| self.container.addOperation(discoverOperation) | |
| } | |
| func findSharedRecords <T> (typeIndicator:String!) -> [T]?{ | |
| guard typeIndicator != "" else { return nil } | |
| var typedResults: [T]? | |
| let format = "%K = %@" | |
| let predicate = NSPredicate(format: format, argumentArray: [MNGCloudSharedStoriesRecord.StoryTypeColumn,typeIndicator])//NSPredicate(value: true) | |
| let query = CKQuery(recordType: MNGCloudSharedStoriesRecord.RecordName, predicate: predicate) | |
| publicDatabase!.performQuery(query, inZoneWithID: nil) { (results, error ) -> Void in | |
| if error != nil { | |
| dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
| self.notifyUser(MNGCloudKitEvents.AccessError, message: (error?.localizedDescription)!) | |
| }) | |
| } else if results?.count > 0 { | |
| typedResults = [T]() | |
| for record in results! { | |
| if let tmp = record[MNGCloudSharedStoriesRecord.StoryAssetColumn] as? | |
| CKAsset { | |
| let story = NSKeyedUnarchiver.unarchiveObjectWithFile(tmp.fileURL.absoluteString) as! T | |
| typedResults!.append(story) | |
| } | |
| } | |
| } | |
| } | |
| if typedResults?.count > 0 { | |
| return typedResults! | |
| } else { | |
| return nil | |
| } | |
| } | |
| func findPrivateShareRecords <T> (typeIndicator:String!, toUser:String!) -> [T]?{ | |
| guard typeIndicator != "" && toUser != "" else { return nil } | |
| var typedResults: [T]? | |
| let format = "%K contains %@" | |
| //TODO: Wrap id as CKReference | |
| let predicate = NSPredicate(format: format, argumentArray: [MNGCloudSharedStoriesRecord.StoryTypeColumn,typeIndicator,MNGCloudSharedStoriesRecord.StorySharedToListReferenceColumn, toUser] ) //NSPredicate(value: true) | |
| let query = CKQuery(recordType: MNGCloudSharedStoriesRecord.RecordName, predicate: predicate) | |
| publicDatabase!.performQuery(query, inZoneWithID: nil) { (results, error ) -> Void in | |
| if error != nil { | |
| dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
| self.notifyUser(MNGCloudKitEvents.AccessError, message: (error?.localizedDescription)!) | |
| }) | |
| } else if results?.count > 0 { | |
| typedResults = [T]() | |
| for record in results! { | |
| if let tmp = record[MNGCloudSharedStoriesRecord.StoryAssetColumn] as? | |
| CKAsset { | |
| let story = NSKeyedUnarchiver.unarchiveObjectWithFile(tmp.fileURL.absoluteString) as! T | |
| typedResults!.append(story) | |
| } | |
| } | |
| } | |
| } | |
| if typedResults?.count > 0 { | |
| return typedResults! | |
| } else { | |
| return nil | |
| } | |
| } | |
| //MARK: Cloud Management Methods | |
| func requestDiscoverabilityPermission(completionHandler: (discoverable:Bool!)->()) { | |
| self.container.requestApplicationPermission(CKApplicationPermissions.UserDiscoverability, completionHandler: { (status, error) -> Void in | |
| if ((error) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| dispatch_async(dispatch_get_main_queue(), { () -> Void in | |
| //check status == CKApplicationPermissionStatus.Granted | |
| }) | |
| } | |
| }) | |
| } | |
| func discoverUserInfo( completionHandler:( user:CKDiscoveredUserInfo!)->() ) { | |
| self.container.fetchUserRecordIDWithCompletionHandler ({ userID, error -> Void in | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| self.container.discoverUserInfoWithUserRecordID (userID!, completionHandler: { (userInfo, error) -> Void in | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| dispatch_async (dispatch_get_main_queue(), { () -> Void in | |
| //post notification with userInfo | |
| }) | |
| } | |
| }) | |
| } | |
| }) | |
| } | |
| func saveRecord(aRecord:CKRecord, recordId:CKRecordID?){ | |
| self.publicDatabase?.saveRecord(aRecord, completionHandler: { (record, error) -> Void in | |
| if error != nil { | |
| //print(error!.localizedDescription) | |
| NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in | |
| self.delegate?.cloudManagerDidFailWithCloudError!(error!) | |
| }) | |
| return | |
| } | |
| //print("Saved Registration Record:\(record!.recordID.recordName)") | |
| NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in | |
| //print( self.delegate ) | |
| self.delegate?.cloudManagerDidSaveUserRegistrationInfo!(aRecord.recordID.recordName) | |
| }) | |
| }) | |
| } | |
| func saveRecord (type:String, object:AnyObject?, id:CKRecordID?) { | |
| var record:CKRecord? = nil | |
| if id != nil { | |
| record = CKRecord(recordType: type, recordID: id!) | |
| } else { | |
| record = CKRecord(recordType: type) | |
| } | |
| self.publicDatabase?.saveRecord(record!, completionHandler: { (record, error) in | |
| // | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| self.delegate?.cloudManagerDidFailWithCloudError!(error!) | |
| } else { | |
| dispatch_async (dispatch_get_main_queue(), { () -> Void in | |
| //post notification with recordInfo | |
| //completionHandler(record); | |
| }) | |
| } | |
| }) | |
| } | |
| func saveRecordWithMetadata (record:CKRecord, properties:[String:AnyObject]) { | |
| //save metadata | |
| for (key, value) in properties { | |
| record[key] = value as! String | |
| } | |
| self.publicDatabase?.saveRecord(record, completionHandler: { (record, error) in | |
| // | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| dispatch_async (dispatch_get_main_queue(), { () -> Void in | |
| //post notification with recordInfo | |
| //completionHandler(record); | |
| }) | |
| } | |
| }) | |
| } | |
| func deleteRecord (record:CKRecord) { | |
| self.publicDatabase?.deleteRecordWithID(record.recordID, completionHandler: { (record, error) -> Void in | |
| // | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| dispatch_async (dispatch_get_main_queue(), { () -> Void in | |
| //post notification with recordInfo | |
| //completionHandler(record); | |
| }) | |
| } | |
| }) | |
| } | |
| //MARK: Insert Modify Methods | |
| func insertSharedStoryRecord(storyInfo:NSDictionary){ | |
| let assetURL = NSURL() | |
| //make two dependent operations here? | |
| uploadAssetWithURL(assetURL) { (record) -> () in | |
| if let storyAssetReference:CKReference? = CKReference(record: record, action: .DeleteSelf) { | |
| //save to story record reference field | |
| } | |
| } | |
| } | |
| func modifySharedStoryRecord(storyInfo:NSDictionary, usingRecordID recordID: String){ | |
| } | |
| func insertInviteRecord(inviteInfo:NSDictionary) { | |
| if let inviteRecord:CKRecord? = CKRecord(recordType: MNGCloudInvitesRecord.RecordName) { | |
| if let joined = inviteInfo[MNGCloudInvitesRecord.DateJoinedColumn] as? NSDate { | |
| inviteRecord?.setObject(joined, forKey: MNGCloudInvitesRecord.DateJoinedColumn) | |
| } | |
| if let email = inviteInfo[MNGCloudInvitesRecord.EmailColumn] as? String { | |
| inviteRecord?.setObject(email, forKey: MNGCloudInvitesRecord.EmailColumn) | |
| } | |
| if let first = inviteInfo[MNGCloudInvitesRecord.GivenNameColumn] as? String { | |
| inviteRecord?.setObject(first, forKey: MNGCloudInvitesRecord.GivenNameColumn) | |
| } | |
| if let last = inviteInfo[MNGCloudInvitesRecord.FamilyNameColumn] as? String { | |
| inviteRecord?.setObject(last, forKey: MNGCloudInvitesRecord.FamilyNameColumn) | |
| } | |
| if let newUserId = inviteInfo[MNGCloudInvitesRecord.NewUserIdReferenceColumn] as? String { | |
| let _tmp = CKRecordID(recordName: newUserId) //record id for newly registered user | |
| let ckRef = CKReference(recordID: _tmp, action: .None) | |
| inviteRecord?.setObject(ckRef, forKey: MNGCloudInvitesRecord.NewUserIdReferenceColumn) | |
| } | |
| if let phone = inviteInfo[MNGCloudInvitesRecord.PhoneColumn] as? String { | |
| inviteRecord?.setObject(phone, forKey: MNGCloudInvitesRecord.PhoneColumn) | |
| } | |
| if let status = inviteInfo[MNGCloudInvitesRecord.StatusColumn] as? String { | |
| inviteRecord?.setObject(status, forKey: MNGCloudInvitesRecord.StatusColumn) | |
| } | |
| self.publicDatabase?.saveRecord(inviteRecord!, completionHandler: { (record, error) -> Void in | |
| if error != nil { | |
| //print(error!.localizedDescription) | |
| NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in | |
| self.delegate?.cloudManagerDidFailToSaveInvitationInfo!(error!) | |
| }) | |
| return | |
| } | |
| //print("Saved Registration Record:\(record!.recordID.recordName)") | |
| NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in | |
| //print( self.delegate ) | |
| self.delegate?.cloudManagerDidSaveInvitationInfo!(inviteRecord!.recordID.recordName) | |
| }) | |
| }) | |
| } | |
| } | |
| func modifyInviteRecord(inviteInfo:NSDictionary, usingRecordIDName recordName: String){ | |
| if let inviteRecord:CKRecord? = CKRecord(recordType: MNGCloudInvitesRecord.RecordName, recordID: CKRecordID(recordName: recordName)) { | |
| if let joined = inviteInfo[MNGCloudInvitesRecord.DateJoinedColumn] as? NSDate { | |
| inviteRecord?.setObject(joined, forKey: MNGCloudInvitesRecord.DateJoinedColumn) | |
| } | |
| if let email = inviteInfo[MNGCloudInvitesRecord.EmailColumn] as? String { | |
| inviteRecord?.setObject(email, forKey: MNGCloudInvitesRecord.EmailColumn) | |
| } | |
| if let first = inviteInfo[MNGCloudInvitesRecord.GivenNameColumn] as? String { | |
| inviteRecord?.setObject(first, forKey: MNGCloudInvitesRecord.GivenNameColumn) | |
| } | |
| if let last = inviteInfo[MNGCloudInvitesRecord.FamilyNameColumn] as? String { | |
| inviteRecord?.setObject(last, forKey: MNGCloudInvitesRecord.FamilyNameColumn) | |
| } | |
| if let newUserId = inviteInfo[MNGCloudInvitesRecord.NewUserIdReferenceColumn] as? String { | |
| let _tmp = CKRecordID(recordName: newUserId) //record id for newly registered user | |
| let ckRef = CKReference(recordID: _tmp, action: .None) | |
| inviteRecord?.setObject(ckRef, forKey: MNGCloudInvitesRecord.NewUserIdReferenceColumn) | |
| } | |
| if let phone = inviteInfo[MNGCloudInvitesRecord.PhoneColumn] as? String { | |
| inviteRecord?.setObject(phone, forKey: MNGCloudInvitesRecord.PhoneColumn) | |
| } | |
| if let status = inviteInfo[MNGCloudInvitesRecord.StatusColumn] as? String { | |
| inviteRecord?.setObject(status, forKey: MNGCloudInvitesRecord.StatusColumn) | |
| } | |
| } | |
| } | |
| func insertRegistrationRecord(regInfo:NSDictionary){ | |
| //Configure User Reference | |
| // if let currentCKUserID:CKRecordID? = CKRecordID(recordName: MNGAUSManager.sharedInstance.cloudUserId()) { | |
| // if let currentCKUserReference:CKReference? = CKReference(recordID: currentCKUserID!, action: CKReferenceAction.DeleteSelf) { | |
| //Configure Record | |
| if let registrationRecord:CKRecord? = CKRecord(recordType: MNGCloudUserRegisterationRecord.RecordName) { | |
| //registrationRecord!.setObject(currentCKUserReference, forKey: MNGCloudUserRegisterationRecord.UserIDReferenceColumn) | |
| if let email = regInfo[MNGCloudUserRegisterationRecord.EmailColumn] as? String{ | |
| registrationRecord?.setObject(email, forKey: MNGCloudUserRegisterationRecord.EmailColumn) | |
| } | |
| if let given = regInfo[MNGCloudUserRegisterationRecord.GivenNameColumn] as? String { | |
| registrationRecord?.setObject(given, forKey: MNGCloudUserRegisterationRecord.GivenNameColumn) | |
| } | |
| if let family = regInfo[MNGCloudUserRegisterationRecord.FamilyNameColumn] as? String { | |
| registrationRecord?.setObject(family, forKey: MNGCloudUserRegisterationRecord.FamilyNameColumn) | |
| } | |
| if let phone = regInfo[MNGCloudUserRegisterationRecord.PhoneColumn] as? String { | |
| registrationRecord?.setObject(phone, forKey: MNGCloudUserRegisterationRecord.PhoneColumn) | |
| } | |
| // if let appId = dictionary[MNGCloudUserRegisterationRecord.AppUserIDColumn] as? String { | |
| // registrationRecord!.setObject(appId, forKey: MNGCloudUserRegisterationRecord.AppUserIDColumn) | |
| // } | |
| if let dateExpires = regInfo[MNGCloudUserRegisterationRecord.DateExpiresColumn] as? NSDate { | |
| registrationRecord?.setObject(dateExpires, forKey: MNGCloudUserRegisterationRecord.DateExpiresColumn) | |
| } | |
| if let code = regInfo[MNGCloudUserRegisterationRecord.SecretColumn] as? String { | |
| registrationRecord?.setObject(code, forKey: MNGCloudUserRegisterationRecord.SecretColumn) | |
| } | |
| //Set active status | |
| if let status = regInfo[MNGCloudUserRegisterationRecord.StatusColumn] as? String { | |
| registrationRecord?.setObject(status, forKey: MNGCloudUserRegisterationRecord.StatusColumn) | |
| } | |
| self.publicDatabase?.saveRecord(registrationRecord!, completionHandler: { (record, error) -> Void in | |
| if error != nil { | |
| //print(error!.localizedDescription) | |
| NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in | |
| self.delegate?.cloudManagerDidFailToSaveUserRegistrationInfo!(error!) | |
| }) | |
| return | |
| } | |
| //print("Saved Registration Record:\(record!.recordID.recordName)") | |
| NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in | |
| //print( self.delegate ) | |
| self.delegate?.cloudManagerDidSaveUserRegistrationInfo!(registrationRecord!.recordID.recordName) | |
| }) | |
| }) | |
| } | |
| // } | |
| // } | |
| } | |
| func modifyRegistrationRecord(dictionary:NSDictionary, usingRecordID recordID: String){ | |
| } | |
| //MARK: Cloud Fetch Methods | |
| func fetchRecordWithID (recordID:String, completionHandler:(record:CKRecord)->()) { | |
| let current = CKRecordID(recordName: recordID) | |
| self.publicDatabase?.fetchRecordWithID(current, completionHandler: {(record, error) -> Void in | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| dispatch_async (dispatch_get_main_queue(), { () -> Void in | |
| //post notification with recordInfo | |
| //completionHandler(record); | |
| }) | |
| } | |
| }) | |
| } | |
| func fetchRecordsWithType (recordType:String, completionHandler:(records:[CKRecord]) ->() ) { | |
| //let containsPredicate = NSPredicate(format: "%K CONTAINS %@", argumentArray: [MNGCloudSharedStories.StorySharedToColumn, "*"]) | |
| let truePredicate = NSPredicate(value: true) | |
| let query = CKQuery(recordType: recordType, predicate: truePredicate) //test containsPredicate | |
| let queryOperation = CKQueryOperation (query: query) | |
| //columns to retrieve | |
| queryOperation.desiredKeys = [MNGCloudSharedStoriesRecord.StoryAssetColumn] | |
| var results = [CKRecord]() | |
| // Add results to the results array as they come back. | |
| queryOperation.recordFetchedBlock = { (record:CKRecord) -> Void in | |
| results.append(record) | |
| } | |
| // The query completion block will be called after all records are fetched. | |
| queryOperation.queryCompletionBlock = { (cursor,error) in | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| dispatch_async (dispatch_get_main_queue(), { () in | |
| //post notification with recordInfo | |
| completionHandler(records: results); | |
| }) | |
| } | |
| } | |
| // Add the operation to the database. The operation will be executed immediately. | |
| self.publicDatabase?.addOperation(queryOperation) | |
| } | |
| func fetchPrivateShareRecordsWithType (recordType:String, completionHandler:(records:[CKRecord]) ->() ) { | |
| //TODO: Wrap UserID as a CKReference | |
| let containsPredicate = NSPredicate(format: "%K CONTAINS %@", argumentArray: [MNGCloudSharedStoriesRecord.StorySharedToListReferenceColumn, defaultUserID]) | |
| let query = CKQuery(recordType: recordType, predicate: containsPredicate) | |
| let queryOperation = CKQueryOperation (query: query) | |
| //columns to retrieve | |
| queryOperation.desiredKeys = [MNGCloudSharedStoriesRecord.StoryAssetColumn] | |
| var results = [CKRecord]() | |
| // Add results to the results array as they come back. | |
| queryOperation.recordFetchedBlock = { (record:CKRecord) -> Void in | |
| results.append(record) | |
| } | |
| // The query completion block will be called after all records are fetched. | |
| queryOperation.queryCompletionBlock = { (cursor,error) in | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| dispatch_async (dispatch_get_main_queue(), { () in | |
| //post notification with recordInfo | |
| completionHandler(records: results); | |
| }) | |
| } | |
| } | |
| // Add the operation to the database. The operation will be executed immediately. | |
| self.publicDatabase?.addOperation(queryOperation) | |
| } | |
| //MARK: Cloud Subscription Methods | |
| private var uRecordID:CKRecordID? = nil | |
| lazy var currentUserRecordID:CKRecordID? = { | |
| if self.uRecordID != nil { | |
| return self.uRecordID! | |
| } | |
| let operation = CKFetchRecordsOperation.fetchCurrentUserRecordOperation() | |
| operation.fetchRecordsCompletionBlock = { (records:[CKRecordID: CKRecord]?, error:NSError?) -> Void in | |
| // Code never reached | |
| if ((error) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| debugPrint("fetchRecordsCompletionBlock") | |
| } | |
| for (userRecordID, userRecord) in records! { | |
| self.uRecordID = userRecordID | |
| } | |
| } | |
| self.publicDatabase?.addOperation(operation) | |
| return nil | |
| }() | |
| func subscribe () { | |
| if self.isSubscribed == false { | |
| let containsPredicate = NSPredicate(format: "%K CONTAINS %@", argumentArray: [MNGCloudSharedStoriesRecord.StorySharedToListReferenceColumn, defaultUserID]) | |
| let userSubscription = CKSubscription(recordType: MNGCloudSharedStoriesRecord.RecordName, predicate: containsPredicate, options: [CKSubscriptionOptions.FiresOnRecordCreation,CKSubscriptionOptions.FiresOnRecordUpdate, CKSubscriptionOptions.FiresOnRecordUpdate] ) | |
| let notification = CKNotificationInfo() | |
| notification.alertBody = "RecordsChanged" | |
| userSubscription.notificationInfo = notification | |
| self.publicDatabase?.saveSubscription(userSubscription, completionHandler: { (subscription, error) -> Void in | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| //dispatch_async (dispatch_get_main_queue(), { () -> Void in | |
| //post notification with recordInfo | |
| //completionHandler(record); | |
| NSUserDefaults.standardUserDefaults().setBool(true, forKey: Constants.CloudUserSubscribed) | |
| NSUserDefaults.standardUserDefaults().setObject(userSubscription.subscriptionID, forKey: Constants.CloudUserSubscriptionID) | |
| //}) | |
| }}) | |
| } | |
| } | |
| func unsubscribe () { | |
| if self.isSubscribed == true { | |
| let subscriptionID:String = (NSUserDefaults.standardUserDefaults().objectForKey(Constants.CloudUserSubscriptionID) as? String)! | |
| // Create an operation to modify the subscription with the subscriptionID. | |
| let modifyOperation = CKModifySubscriptionsOperation() | |
| modifyOperation.subscriptionIDsToDelete = [subscriptionID] | |
| modifyOperation.modifySubscriptionsCompletionBlock = { | |
| (savedSubcriptions, deletedSubscriptions, error) in | |
| if (( error ) != nil) { | |
| print(error!.localizedDescription) | |
| } else { | |
| NSUserDefaults.standardUserDefaults().removeObjectForKey(Constants.CloudUserSubscriptionID) | |
| } | |
| } | |
| // Add the operation to the database. The operation will be executed immediately. | |
| self.publicDatabase?.addOperation(modifyOperation) | |
| } | |
| } | |
| //MARK: Cloud Manager Event Methods | |
| override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { | |
| // | |
| if keyPath == NSUbiquityIdentityDidChangeNotification { | |
| print("iCloud Account Status Change", object, change, context) | |
| } | |
| } | |
| func registerEventObservations () { | |
| defaultCenter.addObserver(self, selector: Constants.SelectorCloudEventObserved, name: NSUbiquityIdentityDidChangeNotification, object: nil) | |
| } | |
| func unregisterEventObservations () { | |
| defaultCenter.removeObserver(self, name: NSUbiquityIdentityDidChangeNotification, object: nil) | |
| } | |
| func cloudEventObserved(notification:NSNotification) { | |
| print(notification) | |
| //NSUbiquityIdentityDidChangeNotification | |
| // NSURLRelationship | |
| } | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment