void Run() { //var testDisposable = new TestDisposable(); //Debug.Log("made dispasable: " + testDisposable); //StartCoroutine(WaitABit()); var op = new CKModifyRecordsOperation(null, new CKRecordID[] { new CKRecordID("1CB545B1-7CA3-423E-A215-67DA56578270"), new CKRecordID("321A8AD3-0FA9-40C3-8D76-D76328A0A7F1") }); database = CKContainer.DefaultContainer().PrivateCloudDatabase; Debug.Log("Setting callback"); op.ModifyRecordsCompletionBlock = (records, recordIds, error) => { Debug.Log("Modify records done"); }; //Debug.Log("Setting QoS"); op.Configuration.QualityOfService = NSQualityOfService.Default; database.AddOperation(op); StartCoroutine(WaitABit()); }
private void OnQueryComplete(CKRecord[] records, NSError error) { Debug.Log("OnQueryComplete"); if (error != null) { Debug.LogError(error.LocalizedDescription); } else { var result = records.FirstOrDefault(); if (result != null) { Debug.Log(string.Format("found record: '{0}' with name: '{1}'", result.RecordID.RecordName, result.StringForKey("name"))); } // Let's be tidy. Delete all the records we created // create an array of record id's from the records we saved var recordIds = recordsToSearch.Select(record => record.RecordID).ToArray(); Debug.Log("Cleaning up, deleting the records we created...."); var op = new CKModifyRecordsOperation(null, recordIds); op.ModifyRecordsCompletionBlock = OnRecordsDeleted; op.Configuration.QualityOfService = NSQualityOfService.UserInitiated; database.AddOperation(op); } }
private void Run() { Debug.Log("Example 6 - Per Record Progress"); database = CKContainer.DefaultContainer().PrivateCloudDatabase; // Let's create 5 files at 1MB a piece // So we have enough data to see some upload progress // BTW CloudKit recommends that if your data exceeds 1MB you should put // it inside a CKAsset for (int i = 0; i < numFiles; i++) { var record = new CKRecord("BigFile"); byte[] bytes = new byte[1000000]; record.SetBuffer(bytes, "bytes"); records[i] = record; } var op = new CKModifyRecordsOperation(records, null); op.Configuration.QualityOfService = NSQualityOfService.UserInitiated; op.PerRecordProgressBlock = OnPerRecordProgress; op.PerRecordCompletionBlock = OnPerRecordComplete; op.ModifyRecordsCompletionBlock = OnRecordsSaved; database.AddOperation(op); }
private void OnQuery(CKRecord[] records, NSError error) { Debug.Log("query finished"); if (error != null) { Debug.LogError(error.LocalizedDescription); return; } Debug.Log($"got {records.Length} records"); DebugLogRecords(records); Debug.Log("cleaning up...deleting records"); var deleteOp = new CKModifyRecordsOperation(null, records.Select(r => r.RecordID).ToArray()); deleteOp.Configuration.QualityOfService = NSQualityOfService.UserInitiated; deleteOp.ModifyRecordsCompletionBlock = (ckRecords, ids, arg3) => { if (error != null) { Debug.LogError(error.LocalizedDescription); } else { Debug.Log("records deleted, you can exit the sample"); } }; database.AddOperation(deleteOp); }
public void Can_access_group() { Assert.DoesNotThrow(() => { var op = new CKModifyRecordsOperation(); var group = op.Group; }); }
public void OperationIDTest() { Assert.DoesNotThrow(() => { var op = new CKModifyRecordsOperation(); var id = op.OperationID; }); }
private void Run() { Debug.Log("Example 3 - Querying"); database = CKContainer.DefaultContainer().PrivateCloudDatabase; // We need a bunch of records to search through names = new string[] { "Alice", "Bob", "Charles", "Danni", "Exavier" }; // Make an array of CKRecords and set the name field to each of the // names in the array above... // recordsToSearch = names.Select(name => { var record = new CKRecord("Person"); record.SetString(name, "name"); return(record); }).ToArray(); // CloudKit uses a CKModifyRecrodsOperation for both saving and deleting // (which is sorta wierd). The first parameter is records to save, the // second is record id's to delete // Debug.Log("Creating records"); CKModifyRecordsOperation op = new CKModifyRecordsOperation( recordsToSearch, null ); // Important to set quality of service to UserInitiated or cloudkit // may run your query a LONG time from now. Like minutes from now // (seriously). The default value of NSQualityOfServiceUtility is insane // You can read more about QoS here: // https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html op.Configuration.QualityOfService = NSQualityOfService.UserInitiated; // The modify records completion block is a callback function that's // invoked when the operation is complete op.ModifyRecordsCompletionBlock = OnRecordsSaved; database.AddOperation(op); var op2 = new CKFetchRecordsOperation(recordsToSearch.Select(x => x.RecordID).ToArray()); op2.FetchRecordsCompletionHandler = (dictionary, error) => { Debug.Log("Fetch records complete"); //foreach (var kvp in dictionary) //{ // Debug.Log(string.Format("key:{0} value:{1}", kvp.Key.RecordName, kvp.Value)); //} }; database.AddOperation(op2); }
private void DeleteRecords() { Debug.Log("Cleaning Up"); var op = new CKModifyRecordsOperation(null, records.Select(r => r.RecordID).ToArray()); op.Configuration.QualityOfService = NSQualityOfService.UserInitiated; op.ModifyRecordsCompletionBlock = OnRecordsDeleted; database.AddOperation(op); }
public void Adding_operation_sets_datbase_property_on_operation() { var op = new CKModifyRecordsOperation(); var database = CKContainer.DefaultContainer().PrivateCloudDatabase; database.AddOperation(op); Assert.AreEqual(op.Database, database); }
public void Can_add_operation() { var op = new CKModifyRecordsOperation(); var database = CKContainer.DefaultContainer().PrivateCloudDatabase; TestDelegate sut = () => database.AddOperation(op); Assert.DoesNotThrow(sut); }
public void Can_set_and_get_save_policy( [Values(CKRecordSavePolicy.SaveAllKeys, CKRecordSavePolicy.SaveChangedKeys, CKRecordSavePolicy.SaveIfServerRecordUnchanged)] CKRecordSavePolicy savePolicy ) { var op = new CKModifyRecordsOperation(); op.SavePolicy = savePolicy; Assert.AreEqual(op.SavePolicy, savePolicy); }
public void Default() { // watchOS does not allow `init` so we need to ensure that our default .ctor // match the existing `init*` with null values (so we can remove it) using (var mro = new CKModifyRecordsOperation()) { Assert.That(op.Atomic, Is.EqualTo(mro.Atomic), "Atomic"); Assert.That(op.RecordsToSave, Is.EqualTo(mro.RecordsToSave), "RecordsToSave"); Assert.That(op.RecordIdsToDelete, Is.EqualTo(mro.RecordIdsToDelete), "RecordIdsToDelete"); Assert.That(op.SavePolicy, Is.EqualTo(mro.SavePolicy), "SavePolicy"); Assert.That(op.ClientChangeTokenData, Is.EqualTo(mro.ClientChangeTokenData), "ClientChangeTokenData"); Assert.That(op.PerRecordProgress, Is.EqualTo(mro.PerRecordProgress), "PerRecordProgress"); Assert.That(op.PerRecordCompletion, Is.EqualTo(mro.PerRecordCompletion), "PerRecordCompletion"); Assert.That(op.Completed, Is.EqualTo(mro.Completed), "Completed"); } }
private void OnRecordZoneCreated(CKRecordZone zone, NSError error) { Debug.Log(string.Format("Created record zone with name {0}", zone.ZoneID.ZoneName)); // records you want to save to a custom zone are initialized with the zoneId var save1 = new CKRecord("SaveGame", customZone.ZoneID); // or if you need a custom record name, initialize with a recordID with the zoneId var save2 = new CKRecord("SaveGame", new CKRecordID("MySave", customZone.ZoneID)); var op = new CKModifyRecordsOperation(new CKRecord[] { save1, save2 }, null); op.Configuration.QualityOfService = NSQualityOfService.UserInitiated; op.ModifyRecordsCompletionBlock = OnRecordsSaved; database.AddOperation(op); }
// Start is called before the first frame update void Start() { Debug.Log("Example - NSSortDescriptor"); Debug.Log("container is: " + CKContainer.DefaultContainer().ContainerIdentifier); database = CKContainer.DefaultContainer().PrivateCloudDatabase; var n = 10; Debug.Log($"making {n} records"); var records = new CKRecord[n]; for (var i = 0; i < records.Length; i++) { records[i] = new CKRecord(recordType); } // Make some records share the same field value // so we can test primary/secondary sorting for (var i = 1; i < n; i += 2) { var field = RandomString(8); records[i - 1].SetString(field, primaryFieldKey); records[i].SetString(field, primaryFieldKey); } for (var i = 0; i < n; i++) { var field = RandomString(4); Debug.Log(field); records[i].SetString(field, secondaryFieldKey); } Debug.Log("Saving records"); var op = new CKModifyRecordsOperation(records, null); op.Configuration.QualityOfService = NSQualityOfService.UserInitiated; op.ModifyRecordsCompletionBlock = OnRecordsSaved; database.AddOperation(op); }
public void SetUp() { TestRuntime.AssertXcodeVersion(6, 0); op = new CKModifyRecordsOperation(null, null); }
public void SetUp() { TestRuntime.AssertXcodeVersion(6, 0); TestRuntime.AssertSystemVersion(PlatformName.MacOSX, 10, 10, throwIfOtherPlatform: false); op = new CKModifyRecordsOperation(null, null); }
public void Can_Create_CKModifyRecordsOperation_With_Records_To_Save_And_RecordsIds_To_Delete() { var sut = new CKModifyRecordsOperation(new CKRecord[] { }, new CKRecordID[] { }); Assert.IsNotNull(sut); }
public void Can_create_CKModifyRecordsOperation() { var sut = new CKModifyRecordsOperation(); Assert.IsNotNull(sut); }
public void Configuration_Exists() { var op = new CKModifyRecordsOperation(); Assert.IsNotNull(op); }
void PublishPost(NSObject sender) { // Prevents multiple posting, locks as soon as a post is made PostButton.Enabled = false; UIActivityIndicatorView indicator = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.Gray); indicator.StartAnimating(); PostButton.CustomView = indicator; // Hides the keyboards and dispatches a UI update to show the upload progress HiddenText.EndEditing(true); TagField.EndEditing(true); ProgressBar.Hidden = false; // Creates post record type and initizalizes all of its values CKRecord newRecord = new CKRecord(Post.RecordType); newRecord [Post.FontKey] = (NSString)ImageLabel.Font.Name; newRecord [Post.ImageRefKey] = new CKReference(ImageRecord.Record.Id, CKReferenceAction.DeleteSelf); newRecord [Post.TextKey] = (NSString)HiddenText.Text; string[] tags = TagField.Text.ToLower().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); newRecord [Post.TagsKey] = NSArray.FromObjects(tags); Post newPost = new Post(newRecord); newPost.ImageRecord = ImageRecord; // Only upload image record if it is not on server, otherwise just upload the new post record CKRecord[] recordsToSave = ImageRecord.IsOnServer ? new CKRecord[] { newRecord } : new CKRecord[] { newRecord, ImageRecord.Record }; // TODO: https://trello.com/c/A9T8Spyp second param is null CKModifyRecordsOperation saveOp = new CKModifyRecordsOperation(recordsToSave, new CKRecordID[0]); saveOp.PerRecordProgress = (CKRecord record, double progress) => { // Image record type is probably going to take the longest to upload. Reflect it's progress in the progress bar if (record.RecordType == Image.RecordType) { InvokeOnMainThread(() => { var val = (float)(progress * 0.95); ProgressBar.SetProgress(val, true); }); } }; // When completed it notifies the tableView to add the post we just uploaded, displays error if it didn't work saveOp.Completed = (CKRecord[] savedRecords, CKRecordID[] deletedRecordIDs, NSError operationError) => { Error errorResponse = HandleError(operationError); switch (errorResponse) { case Error.Success: // Tells delegate to update so it can display our new post InvokeOnMainThread(() => { DismissViewController(true, null); MainController.Submit(newPost); }); break; case Error.Retry: CKErrorInfo errorInfo = new CKErrorInfo(operationError.UserInfo); nint retryAfter = errorInfo.RetryAfter.HasValue ? errorInfo.RetryAfter.Value : 3; Console.WriteLine("Error: {0}. Recoverable, retry after {1} seconds", operationError.Description, retryAfter); Task.Delay((int)retryAfter * 1000).ContinueWith(_ => PublishPost(sender)); break; case Error.Ignore: Console.WriteLine("Error saving record: {0}", operationError.Description); string errorTitle = "Error"; string dismissButton = "Okay"; string errorMessage = operationError.Code == (long)CKErrorCode.NotAuthenticated ? "You must be logged in to iCloud in order to post" : "Unrecoverable error with the upload, check console logs"; InvokeOnMainThread(() => { UIAlertController alert = UIAlertController.Create(errorTitle, errorMessage, UIAlertControllerStyle.Alert); alert.AddAction(UIAlertAction.Create(dismissButton, UIAlertActionStyle.Cancel, null)); PostButton.Enabled = true; PresentViewController(alert, true, null); ProgressBar.Hidden = true; PostButton.CustomView = null; }); break; default: throw new NotImplementedException(); } }; CKContainer.DefaultContainer.PublicCloudDatabase.AddOperation(saveOp); }
void PublishPost (NSObject sender) { // Prevents multiple posting, locks as soon as a post is made PostButton.Enabled = false; UIActivityIndicatorView indicator = new UIActivityIndicatorView (UIActivityIndicatorViewStyle.Gray); indicator.StartAnimating (); PostButton.CustomView = indicator; // Hides the keyboards and dispatches a UI update to show the upload progress HiddenText.EndEditing (true); TagField.EndEditing (true); ProgressBar.Hidden = false; // Creates post record type and initizalizes all of its values CKRecord newRecord = new CKRecord (Post.RecordType); newRecord [Post.FontKey] = (NSString)ImageLabel.Font.Name; newRecord [Post.ImageRefKey] = new CKReference (ImageRecord.Record.Id, CKReferenceAction.DeleteSelf); newRecord [Post.TextKey] = (NSString)HiddenText.Text; string[] tags = TagField.Text.ToLower ().Split (new char[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries); newRecord [Post.TagsKey] = NSArray.FromObjects (tags); Post newPost = new Post (newRecord); newPost.ImageRecord = ImageRecord; // Only upload image record if it is not on server, otherwise just upload the new post record CKRecord[] recordsToSave = ImageRecord.IsOnServer ? new CKRecord[] { newRecord } : new CKRecord[] { newRecord, ImageRecord.Record }; // TODO: https://trello.com/c/A9T8Spyp second param is null CKModifyRecordsOperation saveOp = new CKModifyRecordsOperation (recordsToSave, new CKRecordID[0]); saveOp.PerRecordProgress = (CKRecord record, double progress) => { // Image record type is probably going to take the longest to upload. Reflect it's progress in the progress bar if (record.RecordType == Image.RecordType) InvokeOnMainThread (() => { var val = (float)(progress * 0.95); ProgressBar.SetProgress (val, true); }); }; // When completed it notifies the tableView to add the post we just uploaded, displays error if it didn't work saveOp.Completed = (CKRecord[] savedRecords, CKRecordID[] deletedRecordIDs, NSError operationError) => { Error errorResponse = HandleError (operationError); switch (errorResponse) { case Error.Success: // Tells delegate to update so it can display our new post InvokeOnMainThread (() => { DismissViewController (true, null); MainController.Submit (newPost); }); break; case Error.Retry: CKErrorInfo errorInfo = new CKErrorInfo (operationError.UserInfo); nint retryAfter = errorInfo.RetryAfter.HasValue ? errorInfo.RetryAfter.Value : 3; Console.WriteLine ("Error: {0}. Recoverable, retry after {1} seconds", operationError.Description, retryAfter); Task.Delay ((int)retryAfter * 1000).ContinueWith (_ => PublishPost (sender)); break; case Error.Ignore: Console.WriteLine ("Error saving record: {0}", operationError.Description); string errorTitle = "Error"; string dismissButton = "Okay"; string errorMessage = operationError.Code == (long)CKErrorCode.NotAuthenticated ? "You must be logged in to iCloud in order to post" : "Unrecoverable error with the upload, check console logs"; InvokeOnMainThread (() => { UIAlertController alert = UIAlertController.Create (errorTitle, errorMessage, UIAlertControllerStyle.Alert); alert.AddAction (UIAlertAction.Create (dismissButton, UIAlertActionStyle.Cancel, null)); PostButton.Enabled = true; PresentViewController (alert, true, null); ProgressBar.Hidden = true; PostButton.CustomView = null; }); break; default: throw new NotImplementedException (); } }; CKContainer.DefaultContainer.PublicCloudDatabase.AddOperation (saveOp); }