Advertisement
Guest User

Untitled

a guest
Feb 12th, 2016
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.28 KB | None | 0 0
  1.  
  2. // MNGCloudManager.swift
  3. //
  4. //
  5. // Created by Tommie N. Carter, Jr., MBA on 7/25/15.
  6. // Copyright © 2015 MING Technology. All rights reserved.
  7. //
  8.  
  9. import Foundation
  10. import CloudKit
  11. import CoreData
  12. import UIKit
  13.  
  14.  
  15. enum StoryType {
  16. case Audio, Text, Picture, Video
  17. static let allValues = [Audio, Text, Picture, Video]
  18. }
  19.  
  20. struct MNGCloudKitEvents {
  21. static let AccessError = "Cloud Access Error"
  22. static let SaveError = "Save Error"
  23. static let SaveSuccess = "Success"
  24. static let NoMatchFound = "No Match Found"
  25. static let MatchFound = "Match Found"
  26. static let ErrorOccurred = "Error Occurred"
  27. static let DeleteSuccess = "Delete Success"
  28. static let DeleteError = "Delete Error"
  29. static let ProcessCompleted = "ProcessCompleted"
  30. static let ProcessError = "Process Error"
  31. }
  32.  
  33. struct MNGCloudAssetsRecord {
  34. static let RecordName = "Assets"
  35. static let AssetColumn = "asset"
  36. }
  37.  
  38. struct MNGCloudSharedStoriesRecord {
  39. static let RecordName = "SharedStories"
  40. static let DateExpiresColumn = "dateExpires"
  41. static let LocationColumn = "location"
  42. static let StorySharedToListReferenceColumn = "sharedTo"
  43. static let StoryAssetColumn = "storyAsset"
  44. static let StoryTypeColumn = "type" //W|V|P|T
  45. static let StoryStatusColumn = "status" //use for public, private
  46.  
  47. }
  48.  
  49. struct MNGCloudInvitesRecord {
  50. static let RecordName = "Invites"
  51. static let DateJoinedColumn = "dateJoined"
  52. static let EmailColumn = "email"
  53. static let FamilyNameColumn = "familyName"
  54. static let GivenNameColumn = "givenName"
  55. static let PhoneColumn = "phone"
  56. static let StatusColumn = "status"
  57. static let NewUserIdReferenceColumn = "newUserId"
  58. }
  59. struct MNGCloudUserInfoRecord {
  60. static let RecordName = "Users"
  61. static let AppUserIdColumn = "appUserId"
  62. static let LocationColumn = "location"
  63. static let ProfilePhotoAssetColumn = "profilePhoto"
  64. }
  65. //Status = P(ending), R(egistered), F(ailed), B(locked)
  66. struct MNGCloudUserRegisterationRecord {
  67. static let RecordName = "Registered"
  68. static let DateExpiresColumn = "dateExpires"
  69. static let EmailColumn = "email"
  70. static let FamilyNameColumn = "familyName"
  71. static let GivenNameColumn = "givenName"
  72. static let PhoneColumn = "phone"
  73. static let SecretColumn = "secret"
  74. static let StatusColumn = "status"
  75. }
  76. @objc protocol MNGCloudManagerDelegate {
  77. optional func cloudManagerDidReturnKnownContacts(objects:[NSDictionary])
  78. optional func cloudManagerDidReturnInvitesInfo(objects:[NSDictionary])
  79. optional func cloudManagerDidReturnSharedStoryInfo(objects:[NSDictionary])
  80. optional func cloudManagerDidReturnUser(id:String)
  81. optional func cloudManagerDidSaveStoryInfo(recordId:String)
  82. optional func cloudManagerDidFailToSaveStoryInfo(error:NSError)
  83. optional func cloudManagerDidSaveUserInfo(recordId:String)
  84. optional func cloudManagerDidSaveUserRegistrationInfo(recordId:String)
  85. optional func cloudManagerDidFailToSaveUserRegistrationInfo(error:NSError)
  86. optional func cloudManagerDidSaveInvitationInfo(recordId:String)
  87. optional func cloudManagerDidFailToSaveInvitationInfo(error:NSError)
  88. optional func cloudManagerDidFailWithCloudError (error: NSError)
  89. }
  90. class MNGCloudManager:NSObject {
  91.  
  92. var delegate:MNGCloudManagerDelegate? = nil
  93. static let sharedInstance = MNGCloudManager()
  94.  
  95. private struct Constants {
  96. static let CloudUserSubscribed = "CloudUserSubscribed"
  97. static let CloudUserSubscriptionID = "CloudUserScriptionID"
  98. static let SelectorCloudEventObserved = Selector ("cloudEventObserved:")
  99. }
  100.  
  101. lazy var isSubscribed: Bool = {
  102.  
  103. let keyfound = NSUserDefaults.standardUserDefaults().objectForKey(Constants.CloudUserSubscribed) != nil
  104.  
  105. if !keyfound {
  106. //add default key value
  107. NSUserDefaults.standardUserDefaults().setBool(false, forKey: Constants.CloudUserSubscribed)
  108. } else if keyfound && NSUserDefaults.standardUserDefaults().boolForKey(Constants.CloudUserSubscribed) == true {
  109. return true
  110. } else {
  111. return false
  112. }
  113. return false
  114. }()
  115.  
  116. let container = CKContainer.defaultContainer()
  117. lazy var publicDatabase:CKDatabase? = {
  118. return self.container.publicCloudDatabase
  119. }()
  120. lazy var privateDatabase:CKDatabase? = {
  121. return self.container.privateCloudDatabase
  122. }()
  123.  
  124. deinit{
  125. unregisterEventObservations()
  126. }
  127.  
  128. override init(){
  129. super.init()
  130. registerEventObservations()
  131. }
  132. //MARK: Shared Stories Methods
  133. func unshareStory(sharedID:CKRecordID){
  134.  
  135. }
  136. /* Saves the object graph to a CKAsset (fileURL) on the cloud 10 gb limit */
  137. func shareStory(rootObject:AnyObject?, properties: [String: AnyObject?])
  138. {
  139. //properties to set other than Story are Owner, SharedTo, Type
  140. guard rootObject != nil && properties.count != 0 else {return}
  141.  
  142. let tmpPath = NSTemporaryDirectory() + NSUUID().UUIDString
  143. let tmpURL = NSURL(fileURLWithPath: tmpPath)
  144. let record = CKRecord(recordType: MNGCloudSharedStoriesRecord.RecordName)
  145.  
  146. if NSKeyedArchiver.archiveRootObject(rootObject!, toFile: tmpPath) {
  147. let storyAsset = CKAsset(fileURL: tmpURL)
  148. record[MNGCloudSharedStoriesRecord.StoryAssetColumn] = storyAsset
  149. }
  150.  
  151. for (key, value) in properties {
  152. record.setObject(value as? CKRecordValue, forKey: key)//(value, forKey: key)
  153. }
  154.  
  155. publicDatabase!.saveRecord(record, completionHandler:
  156. ({returnRecord, error in
  157. if let err = error {
  158. self.notifyUser(MNGCloudKitEvents.SaveError, message:
  159. err.localizedDescription)
  160. } else {
  161. dispatch_async(dispatch_get_main_queue()) {
  162.  
  163. //tell the delegate that the record was saved
  164.  
  165. // self.notifyUser(MNGCloudKitEvents.CloudKitSavedSuccessTitle,
  166. // message: MNGCloudKitEvents.CloudKitSavedSuccessMessage)
  167. self.cleanupTempFile(tmpPath)
  168.  
  169. }
  170. }
  171. }))
  172. }
  173. func share(story:AnyObject, user:String) {
  174. }
  175. func findSharedStoriesForUser(id:String) {
  176.  
  177. }
  178.  
  179. private func cleanupTempFile(atPath:String) {
  180. //cleanup the tmp file
  181. if NSFileManager.defaultManager().fileExistsAtPath(atPath) {
  182.  
  183. do {
  184.  
  185. try NSFileManager.defaultManager().removeItemAtPath(atPath)
  186. } catch let e as NSError {
  187. print(e.localizedDescription)
  188. }
  189.  
  190. }
  191. }
  192.  
  193.  
  194.  
  195. private func uploadAssetWithURL (assetURL:NSURL, completionHandler:(record:CKRecord)->()) {
  196.  
  197. let assetRecord = CKRecord(recordType: MNGCloudAssetsRecord.RecordName)
  198. let asset = CKAsset(fileURL: assetURL)
  199. assetRecord[MNGCloudAssetsRecord.AssetColumn] = asset
  200.  
  201.  
  202. //TODO:Add properties to function call and loop to assign
  203. self.publicDatabase?.saveRecord(assetRecord, completionHandler: { (record, error) -> Void in
  204.  
  205. if (( error ) != nil) {
  206.  
  207. print(error!.localizedDescription)
  208.  
  209. } else {
  210.  
  211. dispatch_async (dispatch_get_main_queue(), { () -> Void in
  212. //post notification with recordInfo
  213. //completionHandler(record);
  214.  
  215. })
  216. }
  217. })
  218. }
  219.  
  220. //MARK: Notification Methods
  221. func notifyUser(title: String, message: String) -> Void
  222. {
  223. let alert = UIAlertController(title: title,
  224. message: message,
  225. preferredStyle: UIAlertControllerStyle.Alert)
  226.  
  227. let cancelAction = UIAlertAction(title: "OK",
  228. style: .Cancel, handler: nil)
  229.  
  230. alert.addAction(cancelAction)
  231.  
  232. //TODO: Create a listener to pick this up
  233. defaultCenter.postNotificationName(MNGCloudKitEvents.ProcessCompleted, object: alert)
  234.  
  235. //send this as a notification object to a UIVC
  236. //self.presentViewController(alert, animated: true, completion: nil)
  237. }
  238. //MARK: Invite Methods
  239. func postInviteByPhone(phone:String){
  240.  
  241. }
  242. func postInviteByEmail(email:String){
  243.  
  244. }
  245. func updateInvite(record:CKRecord, status:String){
  246.  
  247. }
  248.  
  249. //MARK: Registration Methods
  250. func postRegisteredUser(userID:String) {
  251. // call the function above in the following way:
  252. // (userID is the string you are intersted in!)
  253. findCurrentCKUser({ (instance, error) -> () in
  254. if let userID = instance?.recordName {
  255. print("received iCloudID \(userID)")
  256. } else {
  257. print("Fetched iCloudID was nil")
  258. }
  259. })
  260. }
  261.  
  262. //MARK: User Methods
  263. func configureCurrentCKUser (userInfo:NSDictionary) {
  264. if let container:CKContainer? = CKContainer.defaultContainer() {
  265. container!.fetchUserRecordIDWithCompletionHandler() {
  266. recordID, error in
  267.  
  268. if error != nil {
  269. self.delegate?.cloudManagerDidFailWithCloudError!(error!)
  270. return
  271. }
  272. if let record:CKRecord? = CKRecord(recordType: "Users", recordID: recordID!) {
  273. //process user info
  274. if let photoAsset = userInfo[MNGCloudUserInfoRecord.ProfilePhotoAssetColumn] {
  275. record!.setObject(photoAsset as? CKAsset, forKey: MNGCloudUserInfoRecord.ProfilePhotoAssetColumn)
  276. }
  277. if let location = userInfo[MNGCloudUserInfoRecord.LocationColumn] {
  278. record!.setObject(location as? CLLocation, forKey: MNGCloudUserInfoRecord.LocationColumn)
  279. }
  280. if let appUserId = userInfo[MNGCloudUserInfoRecord.AppUserIdColumn] {
  281. record!.setObject(appUserId as? String, forKey: MNGCloudUserInfoRecord.AppUserIdColumn)
  282. }
  283.  
  284. //save to cloud db
  285. self.publicDatabase?.saveRecord(record!, completionHandler: { (record, error) -> Void in
  286. if error != nil {
  287. //print(error!.localizedDescription)
  288. NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in
  289. self.delegate?.cloudManagerDidFailWithCloudError!(error!)
  290. })
  291. return
  292. }
  293.  
  294. NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in
  295. //print( self.delegate )
  296. self.delegate?.cloudManagerDidSaveUserInfo!(record!.recordID.recordName)
  297. })
  298. })
  299. }
  300. }
  301. }
  302. }
  303. /// async gets iCloud record name of logged-in user
  304. func findCurrentCKUser(complete: (instance: CKRecordID?, error: NSError?) -> ()) {
  305. let container = CKContainer.defaultContainer()
  306. container.fetchUserRecordIDWithCompletionHandler() {
  307. recordID, error in
  308. if error != nil {
  309. print(error!.localizedDescription)
  310. complete(instance: nil, error: error)
  311. } else {
  312. print("fetched ID \(recordID?.recordName)")
  313. self.delegate?.cloudManagerDidReturnUser!(recordID!.recordName)
  314. complete(instance: recordID, error: nil)
  315. }
  316. }
  317. }
  318.  
  319. func findUserByEmail (email:String) {
  320.  
  321. }
  322. func findUserByPhone (phone:String) {
  323.  
  324. }
  325. func findUsersInContactBook () {
  326.  
  327. }
  328. func findContactsRelatedToUser() {
  329.  
  330. let discoverOperation = CKDiscoverAllContactsOperation()
  331. discoverOperation.qualityOfService = NSQualityOfService.Background
  332.  
  333. //discoverOperation.usesBackgroundSession = true
  334. discoverOperation.queuePriority = NSOperationQueuePriority.Normal
  335. discoverOperation.discoverAllContactsCompletionBlock = {
  336. (userInfos, error) in
  337. if (( error ) != nil) {
  338.  
  339. print(error!.localizedDescription)
  340.  
  341. } else {
  342.  
  343. //deal with the userInfos returned
  344. dispatch_async(dispatch_get_main_queue()) { [weak self] () -> Void in
  345. self?.notifyUser(MNGCloudKitEvents.MatchFound,
  346. message: MNGCloudKitEvents.MatchFound)
  347.  
  348. //do something with the users' matching contacts
  349. //defaultCenter.postNotificationName(MNGCloudKitEvents.CloudKitMatchFound, object: userInfos.map{ ( $0 ) } )
  350.  
  351. }
  352. }
  353.  
  354. }
  355. self.container.addOperation(discoverOperation)
  356.  
  357. }
  358. func findSharedRecords <T> (typeIndicator:String!) -> [T]?{
  359. guard typeIndicator != "" else { return nil }
  360.  
  361. var typedResults: [T]?
  362.  
  363. let format = "%K = %@"
  364. let predicate = NSPredicate(format: format, argumentArray: [MNGCloudSharedStoriesRecord.StoryTypeColumn,typeIndicator])//NSPredicate(value: true)
  365.  
  366. let query = CKQuery(recordType: MNGCloudSharedStoriesRecord.RecordName, predicate: predicate)
  367.  
  368. publicDatabase!.performQuery(query, inZoneWithID: nil) { (results, error ) -> Void in
  369. if error != nil {
  370. dispatch_async(dispatch_get_main_queue(), { () -> Void in
  371. self.notifyUser(MNGCloudKitEvents.AccessError, message: (error?.localizedDescription)!)
  372. })
  373. } else if results?.count > 0 {
  374.  
  375. typedResults = [T]()
  376.  
  377. for record in results! {
  378. if let tmp = record[MNGCloudSharedStoriesRecord.StoryAssetColumn] as?
  379. CKAsset {
  380. let story = NSKeyedUnarchiver.unarchiveObjectWithFile(tmp.fileURL.absoluteString) as! T
  381. typedResults!.append(story)
  382. }
  383. }
  384. }
  385. }
  386.  
  387. if typedResults?.count > 0 {
  388. return typedResults!
  389. } else {
  390. return nil
  391. }
  392. }
  393.  
  394. func findPrivateShareRecords <T> (typeIndicator:String!, toUser:String!) -> [T]?{
  395. guard typeIndicator != "" && toUser != "" else { return nil }
  396.  
  397. var typedResults: [T]?
  398. let format = "%K contains %@"
  399. //TODO: Wrap id as CKReference
  400. let predicate = NSPredicate(format: format, argumentArray: [MNGCloudSharedStoriesRecord.StoryTypeColumn,typeIndicator,MNGCloudSharedStoriesRecord.StorySharedToListReferenceColumn, toUser] ) //NSPredicate(value: true)
  401.  
  402. let query = CKQuery(recordType: MNGCloudSharedStoriesRecord.RecordName, predicate: predicate)
  403.  
  404. publicDatabase!.performQuery(query, inZoneWithID: nil) { (results, error ) -> Void in
  405. if error != nil {
  406. dispatch_async(dispatch_get_main_queue(), { () -> Void in
  407. self.notifyUser(MNGCloudKitEvents.AccessError, message: (error?.localizedDescription)!)
  408. })
  409. } else if results?.count > 0 {
  410.  
  411. typedResults = [T]()
  412.  
  413. for record in results! {
  414. if let tmp = record[MNGCloudSharedStoriesRecord.StoryAssetColumn] as?
  415. CKAsset {
  416. let story = NSKeyedUnarchiver.unarchiveObjectWithFile(tmp.fileURL.absoluteString) as! T
  417. typedResults!.append(story)
  418. }
  419. }
  420. }
  421. }
  422.  
  423. if typedResults?.count > 0 {
  424. return typedResults!
  425. } else {
  426. return nil
  427. }
  428. }
  429.  
  430. //MARK: Cloud Management Methods
  431. func requestDiscoverabilityPermission(completionHandler: (discoverable:Bool!)->()) {
  432.  
  433. self.container.requestApplicationPermission(CKApplicationPermissions.UserDiscoverability, completionHandler: { (status, error) -> Void in
  434. if ((error) != nil) {
  435. print(error!.localizedDescription)
  436. } else {
  437.  
  438. dispatch_async(dispatch_get_main_queue(), { () -> Void in
  439. //check status == CKApplicationPermissionStatus.Granted
  440.  
  441. })
  442. }
  443. })
  444. }
  445.  
  446. func discoverUserInfo( completionHandler:( user:CKDiscoveredUserInfo!)->() ) {
  447.  
  448. self.container.fetchUserRecordIDWithCompletionHandler ({ userID, error -> Void in
  449.  
  450. if (( error ) != nil) {
  451.  
  452. print(error!.localizedDescription)
  453.  
  454. } else {
  455.  
  456.  
  457. self.container.discoverUserInfoWithUserRecordID (userID!, completionHandler: { (userInfo, error) -> Void in
  458.  
  459. if (( error ) != nil) {
  460.  
  461. print(error!.localizedDescription)
  462.  
  463. } else {
  464.  
  465. dispatch_async (dispatch_get_main_queue(), { () -> Void in
  466. //post notification with userInfo
  467.  
  468. })
  469. }
  470.  
  471. })
  472. }
  473. })
  474. }
  475. func saveRecord(aRecord:CKRecord, recordId:CKRecordID?){
  476.  
  477.  
  478. self.publicDatabase?.saveRecord(aRecord, completionHandler: { (record, error) -> Void in
  479. if error != nil {
  480. //print(error!.localizedDescription)
  481. NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in
  482. self.delegate?.cloudManagerDidFailWithCloudError!(error!)
  483. })
  484. return
  485. }
  486. //print("Saved Registration Record:\(record!.recordID.recordName)")
  487.  
  488. NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in
  489. //print( self.delegate )
  490. self.delegate?.cloudManagerDidSaveUserRegistrationInfo!(aRecord.recordID.recordName)
  491. })
  492.  
  493. })
  494. }
  495. func saveRecord (type:String, object:AnyObject?, id:CKRecordID?) {
  496. var record:CKRecord? = nil
  497.  
  498. if id != nil {
  499. record = CKRecord(recordType: type, recordID: id!)
  500. } else {
  501. record = CKRecord(recordType: type)
  502. }
  503.  
  504.  
  505. self.publicDatabase?.saveRecord(record!, completionHandler: { (record, error) in
  506. //
  507. if (( error ) != nil) {
  508.  
  509. print(error!.localizedDescription)
  510. self.delegate?.cloudManagerDidFailWithCloudError!(error!)
  511.  
  512. } else {
  513.  
  514. dispatch_async (dispatch_get_main_queue(), { () -> Void in
  515. //post notification with recordInfo
  516. //completionHandler(record);
  517.  
  518. })
  519. }
  520. })
  521. }
  522. func saveRecordWithMetadata (record:CKRecord, properties:[String:AnyObject]) {
  523.  
  524. //save metadata
  525. for (key, value) in properties {
  526. record[key] = value as! String
  527. }
  528.  
  529.  
  530. self.publicDatabase?.saveRecord(record, completionHandler: { (record, error) in
  531. //
  532. if (( error ) != nil) {
  533.  
  534. print(error!.localizedDescription)
  535.  
  536. } else {
  537.  
  538. dispatch_async (dispatch_get_main_queue(), { () -> Void in
  539. //post notification with recordInfo
  540. //completionHandler(record);
  541.  
  542. })
  543. }
  544. })
  545. }
  546. func deleteRecord (record:CKRecord) {
  547.  
  548. self.publicDatabase?.deleteRecordWithID(record.recordID, completionHandler: { (record, error) -> Void in
  549. //
  550. if (( error ) != nil) {
  551.  
  552. print(error!.localizedDescription)
  553.  
  554. } else {
  555.  
  556. dispatch_async (dispatch_get_main_queue(), { () -> Void in
  557. //post notification with recordInfo
  558. //completionHandler(record);
  559.  
  560. })
  561. }
  562. })
  563. }
  564. //MARK: Insert Modify Methods
  565. func insertSharedStoryRecord(storyInfo:NSDictionary){
  566. let assetURL = NSURL()
  567.  
  568. //make two dependent operations here?
  569. uploadAssetWithURL(assetURL) { (record) -> () in
  570. if let storyAssetReference:CKReference? = CKReference(record: record, action: .DeleteSelf) {
  571. //save to story record reference field
  572.  
  573.  
  574. }
  575.  
  576. }
  577.  
  578. }
  579. func modifySharedStoryRecord(storyInfo:NSDictionary, usingRecordID recordID: String){
  580.  
  581. }
  582. func insertInviteRecord(inviteInfo:NSDictionary) {
  583. if let inviteRecord:CKRecord? = CKRecord(recordType: MNGCloudInvitesRecord.RecordName) {
  584. if let joined = inviteInfo[MNGCloudInvitesRecord.DateJoinedColumn] as? NSDate {
  585. inviteRecord?.setObject(joined, forKey: MNGCloudInvitesRecord.DateJoinedColumn)
  586. }
  587. if let email = inviteInfo[MNGCloudInvitesRecord.EmailColumn] as? String {
  588. inviteRecord?.setObject(email, forKey: MNGCloudInvitesRecord.EmailColumn)
  589. }
  590. if let first = inviteInfo[MNGCloudInvitesRecord.GivenNameColumn] as? String {
  591. inviteRecord?.setObject(first, forKey: MNGCloudInvitesRecord.GivenNameColumn)
  592. }
  593. if let last = inviteInfo[MNGCloudInvitesRecord.FamilyNameColumn] as? String {
  594. inviteRecord?.setObject(last, forKey: MNGCloudInvitesRecord.FamilyNameColumn)
  595. }
  596. if let newUserId = inviteInfo[MNGCloudInvitesRecord.NewUserIdReferenceColumn] as? String {
  597. let _tmp = CKRecordID(recordName: newUserId) //record id for newly registered user
  598. let ckRef = CKReference(recordID: _tmp, action: .None)
  599. inviteRecord?.setObject(ckRef, forKey: MNGCloudInvitesRecord.NewUserIdReferenceColumn)
  600. }
  601. if let phone = inviteInfo[MNGCloudInvitesRecord.PhoneColumn] as? String {
  602. inviteRecord?.setObject(phone, forKey: MNGCloudInvitesRecord.PhoneColumn)
  603. }
  604. if let status = inviteInfo[MNGCloudInvitesRecord.StatusColumn] as? String {
  605. inviteRecord?.setObject(status, forKey: MNGCloudInvitesRecord.StatusColumn)
  606. }
  607.  
  608. self.publicDatabase?.saveRecord(inviteRecord!, completionHandler: { (record, error) -> Void in
  609. if error != nil {
  610. //print(error!.localizedDescription)
  611. NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in
  612. self.delegate?.cloudManagerDidFailToSaveInvitationInfo!(error!)
  613. })
  614. return
  615. }
  616. //print("Saved Registration Record:\(record!.recordID.recordName)")
  617.  
  618. NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in
  619. //print( self.delegate )
  620. self.delegate?.cloudManagerDidSaveInvitationInfo!(inviteRecord!.recordID.recordName)
  621. })
  622.  
  623. })
  624.  
  625. }
  626. }
  627. func modifyInviteRecord(inviteInfo:NSDictionary, usingRecordIDName recordName: String){
  628. if let inviteRecord:CKRecord? = CKRecord(recordType: MNGCloudInvitesRecord.RecordName, recordID: CKRecordID(recordName: recordName)) {
  629.  
  630. if let joined = inviteInfo[MNGCloudInvitesRecord.DateJoinedColumn] as? NSDate {
  631. inviteRecord?.setObject(joined, forKey: MNGCloudInvitesRecord.DateJoinedColumn)
  632. }
  633. if let email = inviteInfo[MNGCloudInvitesRecord.EmailColumn] as? String {
  634. inviteRecord?.setObject(email, forKey: MNGCloudInvitesRecord.EmailColumn)
  635. }
  636. if let first = inviteInfo[MNGCloudInvitesRecord.GivenNameColumn] as? String {
  637. inviteRecord?.setObject(first, forKey: MNGCloudInvitesRecord.GivenNameColumn)
  638. }
  639. if let last = inviteInfo[MNGCloudInvitesRecord.FamilyNameColumn] as? String {
  640. inviteRecord?.setObject(last, forKey: MNGCloudInvitesRecord.FamilyNameColumn)
  641. }
  642. if let newUserId = inviteInfo[MNGCloudInvitesRecord.NewUserIdReferenceColumn] as? String {
  643. let _tmp = CKRecordID(recordName: newUserId) //record id for newly registered user
  644. let ckRef = CKReference(recordID: _tmp, action: .None)
  645. inviteRecord?.setObject(ckRef, forKey: MNGCloudInvitesRecord.NewUserIdReferenceColumn)
  646. }
  647. if let phone = inviteInfo[MNGCloudInvitesRecord.PhoneColumn] as? String {
  648. inviteRecord?.setObject(phone, forKey: MNGCloudInvitesRecord.PhoneColumn)
  649. }
  650. if let status = inviteInfo[MNGCloudInvitesRecord.StatusColumn] as? String {
  651. inviteRecord?.setObject(status, forKey: MNGCloudInvitesRecord.StatusColumn)
  652. }
  653. }
  654. }
  655. func insertRegistrationRecord(regInfo:NSDictionary){
  656.  
  657. //Configure User Reference
  658. // if let currentCKUserID:CKRecordID? = CKRecordID(recordName: MNGAUSManager.sharedInstance.cloudUserId()) {
  659. // if let currentCKUserReference:CKReference? = CKReference(recordID: currentCKUserID!, action: CKReferenceAction.DeleteSelf) {
  660.  
  661. //Configure Record
  662. if let registrationRecord:CKRecord? = CKRecord(recordType: MNGCloudUserRegisterationRecord.RecordName) {
  663.  
  664. //registrationRecord!.setObject(currentCKUserReference, forKey: MNGCloudUserRegisterationRecord.UserIDReferenceColumn)
  665.  
  666. if let email = regInfo[MNGCloudUserRegisterationRecord.EmailColumn] as? String{
  667. registrationRecord?.setObject(email, forKey: MNGCloudUserRegisterationRecord.EmailColumn)
  668. }
  669. if let given = regInfo[MNGCloudUserRegisterationRecord.GivenNameColumn] as? String {
  670. registrationRecord?.setObject(given, forKey: MNGCloudUserRegisterationRecord.GivenNameColumn)
  671. }
  672. if let family = regInfo[MNGCloudUserRegisterationRecord.FamilyNameColumn] as? String {
  673. registrationRecord?.setObject(family, forKey: MNGCloudUserRegisterationRecord.FamilyNameColumn)
  674. }
  675. if let phone = regInfo[MNGCloudUserRegisterationRecord.PhoneColumn] as? String {
  676. registrationRecord?.setObject(phone, forKey: MNGCloudUserRegisterationRecord.PhoneColumn)
  677. }
  678. // if let appId = dictionary[MNGCloudUserRegisterationRecord.AppUserIDColumn] as? String {
  679. // registrationRecord!.setObject(appId, forKey: MNGCloudUserRegisterationRecord.AppUserIDColumn)
  680. // }
  681. if let dateExpires = regInfo[MNGCloudUserRegisterationRecord.DateExpiresColumn] as? NSDate {
  682. registrationRecord?.setObject(dateExpires, forKey: MNGCloudUserRegisterationRecord.DateExpiresColumn)
  683. }
  684.  
  685. if let code = regInfo[MNGCloudUserRegisterationRecord.SecretColumn] as? String {
  686. registrationRecord?.setObject(code, forKey: MNGCloudUserRegisterationRecord.SecretColumn)
  687. }
  688.  
  689. //Set active status
  690. if let status = regInfo[MNGCloudUserRegisterationRecord.StatusColumn] as? String {
  691. registrationRecord?.setObject(status, forKey: MNGCloudUserRegisterationRecord.StatusColumn)
  692. }
  693.  
  694. self.publicDatabase?.saveRecord(registrationRecord!, completionHandler: { (record, error) -> Void in
  695. if error != nil {
  696. //print(error!.localizedDescription)
  697. NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in
  698. self.delegate?.cloudManagerDidFailToSaveUserRegistrationInfo!(error!)
  699. })
  700. return
  701. }
  702. //print("Saved Registration Record:\(record!.recordID.recordName)")
  703.  
  704. NSOperationQueue.mainQueue().addOperationWithBlock ({ Void in
  705. //print( self.delegate )
  706. self.delegate?.cloudManagerDidSaveUserRegistrationInfo!(registrationRecord!.recordID.recordName)
  707. })
  708.  
  709. })
  710. }
  711. // }
  712. // }
  713.  
  714.  
  715. }
  716. func modifyRegistrationRecord(dictionary:NSDictionary, usingRecordID recordID: String){
  717.  
  718. }
  719.  
  720. //MARK: Cloud Fetch Methods
  721. func fetchRecordWithID (recordID:String, completionHandler:(record:CKRecord)->()) {
  722. let current = CKRecordID(recordName: recordID)
  723.  
  724. self.publicDatabase?.fetchRecordWithID(current, completionHandler: {(record, error) -> Void in
  725.  
  726. if (( error ) != nil) {
  727.  
  728. print(error!.localizedDescription)
  729.  
  730. } else {
  731.  
  732. dispatch_async (dispatch_get_main_queue(), { () -> Void in
  733. //post notification with recordInfo
  734. //completionHandler(record);
  735.  
  736. })
  737. }
  738. })
  739. }
  740. func fetchRecordsWithType (recordType:String, completionHandler:(records:[CKRecord]) ->() ) {
  741.  
  742. //let containsPredicate = NSPredicate(format: "%K CONTAINS %@", argumentArray: [MNGCloudSharedStories.StorySharedToColumn, "*"])
  743. let truePredicate = NSPredicate(value: true)
  744. let query = CKQuery(recordType: recordType, predicate: truePredicate) //test containsPredicate
  745. let queryOperation = CKQueryOperation (query: query)
  746.  
  747. //columns to retrieve
  748. queryOperation.desiredKeys = [MNGCloudSharedStoriesRecord.StoryAssetColumn]
  749. var results = [CKRecord]()
  750.  
  751.  
  752. // Add results to the results array as they come back.
  753. queryOperation.recordFetchedBlock = { (record:CKRecord) -> Void in
  754. results.append(record)
  755. }
  756.  
  757. // The query completion block will be called after all records are fetched.
  758. queryOperation.queryCompletionBlock = { (cursor,error) in
  759. if (( error ) != nil) {
  760.  
  761. print(error!.localizedDescription)
  762.  
  763. } else {
  764.  
  765. dispatch_async (dispatch_get_main_queue(), { () in
  766. //post notification with recordInfo
  767. completionHandler(records: results);
  768.  
  769. })
  770. }
  771. }
  772. // Add the operation to the database. The operation will be executed immediately.
  773. self.publicDatabase?.addOperation(queryOperation)
  774.  
  775. }
  776. func fetchPrivateShareRecordsWithType (recordType:String, completionHandler:(records:[CKRecord]) ->() ) {
  777.  
  778. //TODO: Wrap UserID as a CKReference
  779. let containsPredicate = NSPredicate(format: "%K CONTAINS %@", argumentArray: [MNGCloudSharedStoriesRecord.StorySharedToListReferenceColumn, defaultUserID])
  780. let query = CKQuery(recordType: recordType, predicate: containsPredicate)
  781. let queryOperation = CKQueryOperation (query: query)
  782.  
  783. //columns to retrieve
  784. queryOperation.desiredKeys = [MNGCloudSharedStoriesRecord.StoryAssetColumn]
  785. var results = [CKRecord]()
  786.  
  787.  
  788. // Add results to the results array as they come back.
  789. queryOperation.recordFetchedBlock = { (record:CKRecord) -> Void in
  790. results.append(record)
  791. }
  792.  
  793. // The query completion block will be called after all records are fetched.
  794. queryOperation.queryCompletionBlock = { (cursor,error) in
  795. if (( error ) != nil) {
  796.  
  797. print(error!.localizedDescription)
  798.  
  799. } else {
  800.  
  801. dispatch_async (dispatch_get_main_queue(), { () in
  802. //post notification with recordInfo
  803. completionHandler(records: results);
  804.  
  805. })
  806. }
  807. }
  808. // Add the operation to the database. The operation will be executed immediately.
  809. self.publicDatabase?.addOperation(queryOperation)
  810.  
  811. }
  812.  
  813. //MARK: Cloud Subscription Methods
  814. private var uRecordID:CKRecordID? = nil
  815. lazy var currentUserRecordID:CKRecordID? = {
  816.  
  817. if self.uRecordID != nil {
  818. return self.uRecordID!
  819. }
  820.  
  821. let operation = CKFetchRecordsOperation.fetchCurrentUserRecordOperation()
  822.  
  823. operation.fetchRecordsCompletionBlock = { (records:[CKRecordID: CKRecord]?, error:NSError?) -> Void in
  824. // Code never reached
  825.  
  826. if ((error) != nil) {
  827. print(error!.localizedDescription)
  828.  
  829. } else {
  830.  
  831. debugPrint("fetchRecordsCompletionBlock")
  832. }
  833.  
  834. for (userRecordID, userRecord) in records! {
  835. self.uRecordID = userRecordID
  836. }
  837.  
  838. }
  839. self.publicDatabase?.addOperation(operation)
  840. return nil
  841. }()
  842.  
  843. func subscribe () {
  844. if self.isSubscribed == false {
  845. let containsPredicate = NSPredicate(format: "%K CONTAINS %@", argumentArray: [MNGCloudSharedStoriesRecord.StorySharedToListReferenceColumn, defaultUserID])
  846.  
  847. let userSubscription = CKSubscription(recordType: MNGCloudSharedStoriesRecord.RecordName, predicate: containsPredicate, options: [CKSubscriptionOptions.FiresOnRecordCreation,CKSubscriptionOptions.FiresOnRecordUpdate, CKSubscriptionOptions.FiresOnRecordUpdate] )
  848.  
  849. let notification = CKNotificationInfo()
  850. notification.alertBody = "RecordsChanged"
  851. userSubscription.notificationInfo = notification
  852.  
  853. self.publicDatabase?.saveSubscription(userSubscription, completionHandler: { (subscription, error) -> Void in
  854.  
  855.  
  856. if (( error ) != nil) {
  857.  
  858. print(error!.localizedDescription)
  859.  
  860. } else {
  861.  
  862. //dispatch_async (dispatch_get_main_queue(), { () -> Void in
  863. //post notification with recordInfo
  864. //completionHandler(record);
  865. NSUserDefaults.standardUserDefaults().setBool(true, forKey: Constants.CloudUserSubscribed)
  866. NSUserDefaults.standardUserDefaults().setObject(userSubscription.subscriptionID, forKey: Constants.CloudUserSubscriptionID)
  867. //})
  868. }})
  869.  
  870.  
  871. }
  872. }
  873.  
  874. func unsubscribe () {
  875. if self.isSubscribed == true {
  876.  
  877. let subscriptionID:String = (NSUserDefaults.standardUserDefaults().objectForKey(Constants.CloudUserSubscriptionID) as? String)!
  878.  
  879. // Create an operation to modify the subscription with the subscriptionID.
  880. let modifyOperation = CKModifySubscriptionsOperation()
  881.  
  882.  
  883. modifyOperation.subscriptionIDsToDelete = [subscriptionID]
  884.  
  885. modifyOperation.modifySubscriptionsCompletionBlock = {
  886. (savedSubcriptions, deletedSubscriptions, error) in
  887.  
  888. if (( error ) != nil) {
  889.  
  890. print(error!.localizedDescription)
  891.  
  892. } else {
  893.  
  894. NSUserDefaults.standardUserDefaults().removeObjectForKey(Constants.CloudUserSubscriptionID)
  895. }
  896.  
  897. }
  898. // Add the operation to the database. The operation will be executed immediately.
  899. self.publicDatabase?.addOperation(modifyOperation)
  900. }
  901.  
  902. }
  903.  
  904.  
  905. //MARK: Cloud Manager Event Methods
  906. override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
  907. //
  908. if keyPath == NSUbiquityIdentityDidChangeNotification {
  909. print("iCloud Account Status Change", object, change, context)
  910. }
  911. }
  912. func registerEventObservations () {
  913. defaultCenter.addObserver(self, selector: Constants.SelectorCloudEventObserved, name: NSUbiquityIdentityDidChangeNotification, object: nil)
  914. }
  915. func unregisterEventObservations () {
  916. defaultCenter.removeObserver(self, name: NSUbiquityIdentityDidChangeNotification, object: nil)
  917.  
  918. }
  919. func cloudEventObserved(notification:NSNotification) {
  920. print(notification)
  921. //NSUbiquityIdentityDidChangeNotification
  922. // NSURLRelationship
  923. }
  924. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement