示例#1
0
        public void LoadImage(string[] keys, Action updateBlock = null)
        {
            // Fetches the imageRecord this post record references in its ImageRefKey.
            // Only fetches the values associated with the keys passed in to the NSArray
            var imgRecordId = ((CKReference)PostRecord[ImageRefKey]).RecordId;
            CKFetchRecordsOperation imageOp = new CKFetchRecordsOperation(new CKRecordID[] {
                imgRecordId
            });

            imageOp.DesiredKeys = keys;
            imageOp.Completed   = (NSDictionary recordDict, NSError error) => {
                if (error != null && error.Code == (long)CKErrorCode.PartialFailure)
                {
                    CKErrorInfo info = new CKErrorInfo(error);
                    error = info[imgRecordId];
                }

                Error errorResponse = HandleError(error);
                switch (errorResponse)
                {
                case Error.Success:
                    CKRecord fetchedImageRecord = (CKRecord)recordDict[imgRecordId];
                    ImageRecord = new Image(fetchedImageRecord);
                    if (updateBlock != null)
                    {
                        updateBlock();
                    }
                    break;

                case Error.Retry:
                    Utils.Retry(() => LoadImage(keys, updateBlock), error);
                    ImageRecord = null;
                    break;

                case Error.Ignore:
                    Console.WriteLine("Error: {0}", error.Description);
                    ImageRecord = null;
                    break;

                default:
                    throw new NotImplementedException();
                }
            };
            PublicDB.AddOperation(imageOp);
        }
示例#2
0
        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);
        }
示例#3
0
            // This method fetches the whole ImageRecord that a user taps on and then passes it to the delegate
            public override void ItemSelected(UICollectionView collectionView, NSIndexPath indexPath)
            {
                // If the user has already tapped on a thumbnail, prevent them from tapping any others
                if (controller.lockSelectThumbnail)
                {
                    return;
                }
                else
                {
                    controller.lockSelectThumbnail = true;
                }

                // Starts animating the thumbnail to indicate it is loading
                controller.ImageCollection.SetLoadingFlag(indexPath, true);

                // Uses convenience API to fetch the whole image record associated with the thumbnail that was tapped
                CKRecordID userSelectedRecordID = controller.ImageCollection.GetRecordId(indexPath);

                controller.PublicCloudDatabase.FetchRecord(userSelectedRecordID, (record, error) => {
                    // If we get a partial failure, we should unwrap it
                    if (error != null && error.Code == (long)CKErrorCode.PartialFailure)
                    {
                        CKErrorInfo info = new CKErrorInfo(error);
                        error            = info[userSelectedRecordID];
                    }

                    Error errorResponse = controller.HandleError(error);

                    switch (errorResponse)
                    {
                    case Error.Success:
                        controller.ImageCollection.SetLoadingFlag(indexPath, false);
                        Image selectedImage = new Image(record);
                        InvokeOnMainThread(() => {
                            controller.MasterController.GoTo(controller, selectedImage);
                        });
                        break;

                    case Error.Retry:
                        Utils.Retry(() => {
                            controller.lockSelectThumbnail = false;
                            ItemSelected(collectionView, indexPath);
                        }, error);
                        break;

                    case Error.Ignore:
                        Console.WriteLine("Error: {0}", error.Description);
                        string errorTitle       = "Error";
                        string errorMessage     = "We couldn't fetch the full size thumbnail you tried to select, try again";
                        string dismissButton    = "Okay";
                        UIAlertController alert = UIAlertController.Create(errorTitle, errorMessage, UIAlertControllerStyle.Alert);
                        alert.AddAction(UIAlertAction.Create(dismissButton, UIAlertActionStyle.Cancel, null));
                        InvokeOnMainThread(() => controller.PresentViewController(alert, true, null));
                        controller.ImageCollection.SetLoadingFlag(indexPath, false);
                        controller.lockSelectThumbnail = false;
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                });
            }
示例#4
0
        static int FetchRetryDelay(NSError error)
        {
            CKErrorInfo errorInfo = new CKErrorInfo(error.UserInfo);

            return((int)(errorInfo.RetryAfter.HasValue ? errorInfo.RetryAfter.Value : 3));
        }