void CancelPost(NSObject sender) { // Hides the keyboards and then returns back to SubmitPostViewController HiddenText.EndEditing(true); TagField.EndEditing(true); DismissViewController(true, null); }
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); }