Giter VIP home page Giter VIP logo

nenosinc / iclouddocumentsync Goto Github PK

View Code? Open in Web Editor NEW
1.2K 77.0 177.0 12.46 MB

Integrate iCloud into iOS document projects with one-line code methods. Sync, upload, manage, and remove documents from iCloud quickly and easily. Helps to make iCloud "just work" for developers too.

License: Other

Objective-C 100.00%
icloud-document-sync icloud-document-storage icloud objective-c icloud-account icloud-framework icloud-features icloud-availability icloud-delegate sync

iclouddocumentsync's Introduction

iCloud Document Sync makes it easy for developers to integrate the iCloud document storage APIs into iOS applications. This is how iCloud document-storage and management should've been out of the box from Apple. Integrate iCloud into iOS (OS X coming soon) Objective-C document projects with one-line code methods. Sync, upload, manage, and remove documents to and from iCloud with only a few lines of code (compared to the hundreds of lines and hours that it usually takes). Get iCloud up and running in your iOS app in only a few minutes.

If you like the project, please star it on GitHub! Watch the project on GitHub for updates. If you use iCloud Document Sync in your app, send an email to hello[at]nenos.one or let us know on Twitter @nenosapp.

Project Features

iCloud Document Sync is a great way to use iCloud document storage in your iOS app. Below are a few key project features and highlights.

  • Sync, Upload, Read, Write, Share, Save, Remove, and Edit any iCloud document in only one line of code.
  • Just drag and drop the iCloud Framework (iCloud.framework) into your project and you can begin using iCloud - no complicated setup
  • Access in-depth documentation with docsets, code comments, and verbose logging
  • Useful delegate methods and properties let you access and manage advanced iCloud features
  • Manage any kind of file with iCloud through use of NSData
  • iOS Sample-app to illustrate how easy it is to use iCloud Document Sync
  • Frequent updates to the project based on user issues and requests
  • Easily contribute to the project

Table of Contents

Project Information

Learn more about the project requirements, licensing, and contributions.

Requirements

Requires Xcode 5.0.1+ for use in any iOS Project. Requires a minimum of iOS 6.0 as the deployment target.

Current Build Target Earliest Supported Build Target Earliest Compatible Build Target
iOS 8.1 iOS 7.0 iOS 6.0
Xcode 6.1.1 Xcode 5.1.1 Xcode 5.0.1
LLVM 6.0 LLVM 5.0 LLVM 5.0

REQUIREMENTS NOTE
Supported means that the library has been tested with this version. Compatible means that the library should work on this OS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly.

License

This project is licensed under the MIT License. See the full iCloud Document Sync license here.

Attribution is not required, but it appreciated. We have spent a lot of time, energy, and resources working on this project - so a little Thanks! (or something to that affect) would be much appreciated. If you use iCloud Document Sync in your app, send an email to [email protected] or let us know on Twitter @iRareMedia.

Contributions

Any contribution is more than welcome! You can contribute through pull requests and issues on GitHub. Learn more about contributing to the project here.

Sample App

The iOS Sample App included with this project demonstrates how to use many of the features in iCloud Document Sync. You can refer to the sample app for an understanding of how to use and setup iCloud Document Sync. The app should work with iCloud as-is (you may need to provide your own Bundle ID though).

Installation

Adding iCloud Document Sync to your project is easy. There are multiple ways to add iCloud Document Sync to your project. Choose the process below which best suits your needs. Follow the steps to get everything up and running in only a few minutes.

CocoaPods Setup

The easiest way to install iCloud Document Sync is to use CocoaPods. To do so, simply add the following line to your Podfile:

pod 'iCloudDocumentSync'

Framework Setup

The iCloud.framework can be retrieved in two different ways:

  1. Clone the project to your computer and build the Framework target. The iCloud.framework file will be copied to the project directory. Drag and drop the .framework file into your project.
  2. Download your preferred iCloud Document Sync Framework release from the Project Releases section. Frameworks are available as far back as version 7.0. Unzip then drag and drop the .framework file into your project.

Traditional Setup

Drag and drop the iCloud folder into your Xcode project. When you do so, check the "Copy items into destination group's folder" box. Delete the iCloud-Prefix.pch file.

Swift Project Setup

To use iCloud Document Sync in a Swift project, you must create a bridging header.

If you already have a bridging header, simply import iCloud.h (use the #import <iCloud/iCloud.h> syntax when importing the framework, otherwise use #import "iCloud.h").

If you do not already have a bridging header, install iCloud Document Sync into your project using any of the above processes. When adding the files to Xcode, you will be prompted to create a bridging header - create one. Then, import iCloud Document Sync (see paragraph above).

Setup

After installing iCloud Document Sync, it only takes a few lines of code to get it up an running.

  1. Import iCloud (see relevant install instructions above) to your header file(s).

  2. Subscribe to the <iCloudDelegate> delegate.

  3. Set the delegate and optionally enable verbose logging:

    [[iCloud sharedCloud] setDelegate:self]; // Set this if you plan to use the delegate [[iCloud sharedCloud] setVerboseLogging:YES]; // We want detailed feedback about what's going on with iCloud, this is OFF by default

  4. Setup iCloud when your app starts. It is crucial that you call this method before doing any document handling operations. You can either pass a specific Ubiquity Container ID (see your entitlements file) or nil to use the first Ubiquity Container ID in your entitlements.

    [[iCloud sharedCloud] setupiCloudDocumentSyncWithUbiquityContainer:nil];

  5. It is recommended that the first call to iCloud is setDelegate, this way all subsequent operations and method calls can interact with the delegate and provide appropriate information.

Documentation

Key methods, properties, types, and delegate methods available on the iCloud class are documented below. If you're using Xcode 5 with iCloud Document Sync, documentation is available directly within Xcode (just Option-Click any method for Quick Help). For more advanced documentation please install the docset included with this project. This will allow you to view iCloud Document Sync documentation inside of Xcode's Organizer Window. Additional documentation can also be found on the Wiki page (including how to register your app for iCloud, iCloud fundamentals, etc.).

Methods

There are many methods available on iCloud Document Sync. The most important / highlight methods are documented below. All other methods are documented in the docset and with in-code comments.

Checking for iCloud Availability

iCloud Document Sync checks for iCloud availability before performing any iCloud-related operations. Any iCloud Document Sync methods may return prematurely and without warning if iCloud is unavailable. Therefore, you should always check if iCloud is available before performing any iCloud operations.

BOOL cloudIsAvailable = [[iCloud sharedCloud] checkCloudAvailability];
if (cloudIsAvailable) {
    //YES
}

This checks if iCloud is available by looking for the application's ubiquity token. It returns a boolean value; YES if iCloud is available, and NO if it is not. Check the log / documentation for details on why it may not be available. You can also check for the availability of the iCloud ubiquity container by calling the following method:

BOOL cloudContainerIsAvailable = [[iCloud sharedCloud] checkCloudUbiquityContainer];

The checkCloudAvailability method will call the iCloudAvailabilityDidChangeToState: withUbiquityToken: withUbiquityContainer: delegate method.

Syncing Documents

To get iCloud Document Sync to initialize for the first time, and continue to update when there are changes you'll need to initialize iCloud. By initializing iCloud, it will start syncing with iCloud for the first time and in the future.

[[iCloud sharedCloud] init];

You can manually fetch changes from iCloud too:

[[iCloud sharedCloud] updateFiles];

iCloud Document Sync will automatically detect changes in iCloud documents. When something changes the delegate method below is fired and will pass an NSMutableArray of all the files (NSMetadata Items) and their names (NSStrings) stored in iCloud.

- (void)iCloudFilesDidChange:(NSMutableArray *)files withNewFileNames:(NSMutableArray *)fileNames

Uploading Documents

iCloud Document Sync uses UIDocument and NSData to store and manage files. All of the heavy lifting with NSData and UIDocument is handled for you. There's no need to actually create or manage any files, just give iCloud Document Sync your data, and the rest is done for you.

To create a new document or save and close an existing one, use the method below.

[[iCloud sharedCloud] saveAndCloseDocumentWithName:@"Name.ext" withContent:[NSData data] completion:^(UIDocument *cloudDocument, NSData *documentData, NSError *error) {
    if (error == nil) {
        // Code here to use the UIDocument or NSData objects which have been passed with the completion handler
    }
}];

The completion handler will be called when a document is saved or created. The completion handler has a UIDocument and NSData parameter that contain the document and it's contents. The third parameter is an NSError that will contain an error if one occurs, otherwise it will be nil.

You can also upload any documents created while offline, or locally. Files in the local documents directory that do not already exist in iCloud will be moved into iCloud one by one. This process involves lots of file manipulation and as a result it may take a long time. This process will be performed on the background thread to avoid any lag or memory problems. When the upload processes end, the completion block is called on the main thread.

[[iCloud sharedCloud] uploadLocalOfflineDocumentsWithRepeatingHandler:^(NSString *fileName, NSError *error) {
    if (error == nil) {
        // This code block is called repeatedly until all files have been uploaded (or an upload has at least been attempted). Code here to use the NSString (the name of the uploaded file) which have been passed with the repeating handler
    }
} completion:^{
    // Completion handler could be used to tell the user that the upload has completed
}];

Note the repeatingHandler block. This block is called every-time a local file is uploaded, therefore it may be called multiple times in a short period. The NSError object contains any error information if an error occurred, otherwise it will be nil.

Removing Documents

You can delete documents from iCloud by using the method below. The completion block is called when the file is successfully deleted.

[[iCloud sharedCloud] deleteDocumentWithName:@"docName.ext" completion:^(NSError *error) {
    // Completion handler could be used to update your UI and tell the user that the document was deleted
}];

Retrieving Documents and Data

You can open and retrieve a document stored in your iCloud documents directory with the method below. This method will attempt to open the specified document. If the file does not exist, a blank one will be created. The completion handler is called when the file is opened or created (either successfully or not). The completion handler contains a UIDocument, NSData, and NSError all of which contain information about the opened document.

[[iCloud sharedCloud] retrieveCloudDocumentWithName:@"docName.ext" completion:^(UIDocument *cloudDocument, NSData *documentData, NSError *error) {
	if (!error) {
		NSString *fileName = [cloudDocument.fileURL lastPathComponent];
		NSData *fileData = documentData;
	}
}];

First check if there was an error retrieving or creating the file, if there wasn't you can proceed to get the file's contents and metadata.

You can also check whether or not a file actually exists in iCloud or not by using the method below.

BOOL fileExists = [[iCloud sharedCloud] doesFileExistInCloud:@"docName.ext"];
if (fileExists == YES) {
	// File Exists in iCloud
}

Sharing Documents

You can upload an iCloud document to a public URL by using the method below. The completion block is called when the public URL is created.

NSURL *publicURL = [[iCloud sharedCloud] shareDocumentWithName:@"docName.ext" completion:^(NSURL *sharedURL, NSDate *expirationDate, NSError *error) {
    // Completion handler that passes the public URL created, the expiration date of the URL, and any errors. Could be used to update your UI and tell the user that the document was uploaded
}];

Renaming and Duplicating Documents

Rename a document stored in iCloud

[[iCloud sharedCloud] renameOriginalDocument:@"oldName.ext" withNewName:@"newName.ext" completion:^(NSError *error) {
    // Called when renaming is complete
}];

Duplicating a document stored in iCloud

[[iCloud sharedCloud] duplicateOriginalDocument:@"docName.ext" withNewName:@"docName copy.ext" completion:^(NSError *error) {
    // Called when duplication is complete
}];

Monitoring Document State

iCloud tracks the state of a document when stored in iCloud. Document states include: Normal / Open, Closed, In Conflict, Saving Error, and Editing Disabled (learn more about UIDocumentState). Get the current document state of a file stored in iCloud with this method:

[[iCloud sharedCloud] documentStateForFile:@"oldName.ext" completion:^(UIDocumentState *documentState, NSString *userReadableDocumentState, NSError *error) {
    // Completion handler that passes two parameters, an NSError and a UIDocumentState. The documentState parameter represents the document state that the specified file is currently in (may be nil if the file does not exist). The NSError parameter will contain a 404 error if the file does not exist.
}];

Monitor changes in a document's state by subscribing a specific target / selector / method.

BOOL success = [[iCloud sharedCloud] monitorDocumentStateForFile:@"docName.ext" onTarget:self withSelector:@selector(methodName:)];

Stop monitoring changes in a document's state by removing notifications for a specific target.

BOOL success = [[iCloud sharedCloud] stopMonitoringDocumentStateChangesForFile:@"docName.ext" onTarget:self];

File Conflict Handling

When a document's state changes to in conflict, your application should take the appropriate action by resolving the conflict or letting the user resolve the conflict. You can monitor for document state changes with the monitorDocumentStateForFile:onTarget:withSelector: method. iCloud Document Sync provides two methods that help handle a conflict with a document stored in iCloud. The first method lets you find all conflicting versions of a file:

NSArray *documentVersions = [[iCloud sharedCloud] findUnresolvedConflictingVersionsOfFile:documentName];

The array returned contains a list of NSFileVersion objects for the specified file. You can then use this list of file versions to either automatically merge changes or have the user select the correct version. Use the following method to resolve the conflict by submitting the "correct" version of the file.

[[iCloud sharedCloud] resolveConflictForFile:@"docName.ext" withSelectedFileVersion:[NSFileVersion object]];

Delegate

iCloud Document Sync delegate methods notify you of the status of iCloud and your documents stored in iCloud. To use the iCloud delegate, subscribe to the iCloudDelegate protocol and then set the delegate property. To use the iCloudDocument delegate, subscribe to the iCloudDocumentDelegate protocol and then set the delegate property.

iCloud Availability Changed

Called (automatically by iOS) when the availability of iCloud changes. The first parameter, cloudIsAvailable, is a boolean value that is YES if iCloud is available and NO if iCloud is not available. The second parameter, ubiquityToken, is an iCloud ubiquity token that represents the current iCloud identity. Can be used to determine if iCloud is available and if the iCloud account has been changed (ex. if the user logged out and then logged in with a different iCloud account). This object may be nil if iCloud is not available for any reason. The third parameter, ubiquityContainer, is the root URL path to the current application's ubiquity container. This URL may be nil until the ubiquity container is initialized.

- (void)iCloudAvailabilityDidChangeToState:(BOOL)cloudIsAvailable withUbiquityToken:(id)ubiquityToken withUbiquityContainer:(NSURL *)ubiquityContainer

iCloud Files Changed

When the files stored in your app's iCloud Document's directory change, this delegate method is called. The first parameter, files, contains an array of NSMetadataItems which can be used to gather information about a file (ex. URL, Name, Dates, etc). The second parameter, fileNames, contains an array of the name of each file as NSStrings.

- (void)iCloudFilesDidChange:(NSMutableArray *)files withNewFileNames:(NSMutableArray *)fileNames

iCloud File Conflict

When uploading multiple files to iCloud there is a possibility that files may exist both locally and in iCloud - causing a conflict. iCloud Document Sync can handle most conflict cases and will report the action taken in the log. When iCloud Document Sync can't figure out how to resolve the file conflict (this happens when both the modified date and contents are the same), it will pass the files and relevant information to you using this delegate method. The delegate method contains two NSDictionaries, one which contains information about the iCloud file, and the other about the local file. Both dictionaries contain the same keys with the same types of objects stored at each key:

  • fileContent contains the NSData of the file.
  • fileURL contains the NSURL pointing to the file. This could possibly be used to gather more information about the file.
  • modifiedDate contains the NSDate representing the last modified date of the file.

Below is the delegate method to be used

- (void)iCloudFileConflictBetweenCloudFile:(NSDictionary *)cloudFile andLocalFile:(NSDictionary *)localFile;

iCloud Query Parameter

Called before creating an iCloud Query filter. Specify the type of file to be queried. If this delegate method is not implemented or returns nil, all files stored in the documents directory will be queried. Should return a single file extension formatted (as an NSString) like this: @"txt"

- (NSString *)iCloudQueryLimitedToFileExtension

iCloud Document Error

Delegate method fired when an error occurs during an attempt to read, save, or revert a document. This delegate method is only available on the iCloudDocumentDelegate with the iCloudDocument class. If you implement the iCloudDocument delegate, then you must implement this method - it is required.

- (void)iCloudDocumentErrorOccured:(NSError *)error

iclouddocumentsync's People

Contributors

bgfriend0 avatar criistii avatar crobertsbmw avatar fmalekpour avatar hassanvfx avatar hirokimu avatar iaugux avatar jackjackbauer avatar jneiluj avatar p2 avatar pkclsoft avatar qyl avatar readmecritic avatar sam-spencer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iclouddocumentsync's Issues

iCloud file list?

It would be great if we could get a list of the current files in iCloud.

Now I'm storing a list separately elsewhere, but this is a hassle.

Critical UIDocument Failure on Entering/Exiting Application

My coworker and I spent the last few days slamming our heads through walls debugging a subtle issue. Finally solved it.

Problem:

Short: iOS is passing messages to the UIDocuments iCloudDocumentSync uses AFTER the UIDocuments have been deallocated.

Long: iCloudDocumentSync uses UIDocuments (iCloudDocument) to wrap data conveniently for developers. Unfortunately, UIDocuments are somewhat heavy weight in that they have state which the system relies on to determine what messages to send to the UIDocument. It turns out that when the app becomes active again after coming back from another screen, iOS sends a (setInConflict:) message to all UIDocuments it thinks are open, but the UIDocuments have already been deallocated (since they are only used as wrappers). The bug was hard to pin down (try searching for "setInConflict" on Google... there's one result.)

Solution:

You have two choices. Either make a conspicuous caution in the iCloudDocumentSync documentation that ANY UIDocument that is passed out from iCloudDocumentSync (e.g., in the completion handler for the retrieveDocument method) should either be retained by the developer or be closed with [document closeWithCompletionHandler:]. I personally chose to close my UIDocuments.

The other option is to close the UIDocument inside iCloudDocumentSync so the developer doesn't need to know anything about closing UIDocuments.

iOS-64bit?

Hi,

thank you so much for your work! It really helped a lot!

Do you have any plans to support the new 64-bit-architecture? Any chance we might see a recompiled framework?

This would clear the way for our app to go all 64-bit-native :-)

iCloudFilesDidChange returns wrong values

I've got a crash report from Crashlytics (just once until now and not reproducible) reporting a crash in my
- (void)iCloudFilesDidChange:(NSMutableArray *)files withNewFileNames:(NSMutableArray *)fileNames
delegate-function. It boils down to files.count is not equal to fileNames.count - which in turn points to the Cloud.m function, - (void)updateFiles, delivering a different number of values in the discoveredFiles array and the names array (in the iOS7-and-later-part).

Do you have any idea, how this may have happened?

Other than that, this seems to be a very stable version by now. Thank you so much for your work!!!

feature-branch not getting notification on update?

Hi,
I just tried the promising feature-branch (7.3) and everything worked fine - except for the missing update-notifications. My app is not getting any notifications, when a document has changed.
Could this be related to the missing NSMetadataQueryDidUpdateNotification?

Exclude folder from synchronisation

First of all, great project. Really made my life easier.

In my project I am using a folder for temporary saves. Is there any way to exclude this folder from the iCloud synchronisation process?

Thanks,

Get public sharable link for an uploaded file

I would like to be able to get a public sharable link for an iCloud file I save using your API. This can normally be achieved with URLForPublishingUbiquitousItemAtURL in NSFileManager.

It would be really great if we could somehow expose this function in your API.

Files not syncing to device correctly

Files on my 5s say they upload to iCloud correctly. iCloud Drive shows these files, but my 4S doesn't show these files, I have not tested but I'm sure if I upload a file from my 4s it will show in the iCloud on there, and iCloud Drive but my 5s won't show that file. So for some reason the files are not being synced locally?

Query All Files / Folders in a Folder

It is unclear how to query files / folders on iCloud. I would need to find all folders in a certain folder.
From what I understand the getListOfCloudFiles method returns an array of URLs from the iCloud root. However, I need to be able to query the available folders.

retrieveCloudDocumentWithName:completion causes memory leak with large NSData files

I have about eight 10 MB files I'm trying to sync between an iPhone 6 and iPad Air on iOS 8.1.2 (latest - 12B440) that are on fast WiFi. In iCloudFilesDidChange:withNewFileNames: I call retrieveCloudDocumentWithName:completion: which works, but then I get memory warning and the app crashes (even if I don't have anything inside the completion block).

Memory spikes from 50MB to 400MB then crashes. It seems that iCloudFilesDidChange:withNewFileNames: is getting called way more times then there are files being synced.

Is there a memory leak in retrieveCloudDocumentWithName:completion: or is their some cleanup I need to do to release memory in it's completion block?

Decryption Error

Get keyData from iCloud:
• wrappedOffset = keyDataSize - (ECP_LEN + WRAPPED_KEY_LEN)
• get wrappedKey (at wrappedOffset)
• get CLASS_KEY
• iOS 5/6: ((UINT32_)(keyData + wrappedOffset))[-1]
• iOS 7: ((UINT32_)(keyData + wrappedOffset))[-3]
• decrypt wrappedKey using CLASS_KEY
• get AES_KEY from wrappedKey
• file decryption: by 0x1000 blocks (unique IV for every block)

I have key data and file. Can you guide me in Objective-C decryption?

Using ubiquitousDocumentsDirectoryURL when URLForUbiquityContainerIdentifier has returned nil

I was attempting to call this again to force an update to the ubiquity container if the user had signed into iCloud while the app was still running.

I ran into a couple of problems:

  1. If an exception is caught no return value is specified. Shouldn't the last line of ubiquitousDocumentsDirectoryURL be 'return nil;' ?

  2. If the ubiquityContainer is null shouldn't the function return nil rather than proceeding to check if the directory exists?

Deleted file gets instantly downloaded again as a new file

Hey!

First of all, thanks for making iCloudDocumentSync, I'm pretty happy using and exploring it at the moment.
Though I've got an issue with it and hope you can help me: The moment I delete a document, it's gone for maybe 1-2 seconds. Right after that a query comes in saying that my document still does exist and therefore downloading it (since I configured it that it downloades all docuements that it does not have yet).
Why does it (still) show a deleted document in a query? Is there a race going on, hence it's still listing the document since the query wasn't aware of the deletition yet?
What do you recommend to fix this?

I hope you can help me!

iCloud documents not listed or opened due to file system hidden attribute

While testing in the simulator I found that some of my documents were not being returned in iCloudFilesDidChange. This seem to be happening because the code checks for NSURLIsHiddenKey and I assume the files have this state before they are synced to the local device.

Removing this check fixed the problem. This is also confirmed in the StackOverflow question:

http://stackoverflow.com/questions/14114193/icloud-nsmetadata-query-results-are-blank

This answer:

http://stackoverflow.com/a/14114826

Suggest that the code doesn't need any additional filtering because NSMetadataQueryUbiquitousDocumentsScope was used.

I also changed the test for file existence in retrieveCloudDocumentWithName . Instead, I used

if ( [self.fileManager isUbiquitousItemAtURL:fileURL] )

New files fail to save, but existing files are updated

I am using the saveAndCloseDocumentWithName:withContent:completion: method to create a new file, but I get an error. However the next time I open the app, after it automatically uploads all files to iCloud, the same method works just fine to overwrite an existing file. Any ideas?

Files with the same name in different folders

As a followup to my previous question:
I have 2 files:
/Documents/FolderA/thumb.png
/Documents/FolderB/thumb.png

How do I use retrieveCloudDocumentWithName: to differentiate between the 2?

#import <iCloud/iCloudDocument.h>

When I drag in the iCloud.framework folder, and add #import <iCloud/iCloud.h> to my app delegate header file and subscribe to the delegate -- if I build it I get an error:

import < iCloud/iCloudDocument.h > File Not Found.

Sample App

Add an iOS sample app to demonstrate how iCloud Document Sync works and how to get the most out of all of it's features.

Download files from iCloud

Hi,
thanks for your framework.

I'm using your framework for sync .plist files.
I can upload all files to iCloud, but I've problems in dowloading it.

My questions: file name is test.plist

Could you post sample code to:

  • upload file to iCloud (copy, not move files)
  • check if the file has been updated (local copy vs iCloud file)
  • download the file to document directory overwriting existing file

Thanks for your support!

Alex

Not an issue But make some usefull

Realy nice one ,

But if you had set this with examples then it will make more impact on beginner and all-ready users, of this great effort of your
1)upload retrive image,
2)upload retrive folder
3)upload sql

Thanks

ubiquitousDocumentsDirectoryURL repeated crash

I don't have these crashes on my device but many users complain and I can see in TestFlight that there are many crashes, all this one:

*** -[NSFileManager createDirectoryAtURL:withIntermediateDirectories:attributes:error:]: URL is nil
SafeNotes -[iCloud ubiquitousDocumentsDirectoryURL] in iCloud.m on Line 158

Can I fix this in my own code? Or is this a bug in the framework?

Crash in Framework

Before finishing my 64-bit-homework, I'd updated my app with the latest master-branch-version, but now crash-reports start coming in with this error

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'must pass a valid file URL to -[UIDocument initWithFileURL:]'

Without being able to symbolicate it down to the cause - I suppose because the crash-point is within the framework. Do you have any idea, what happened here?

Thank you once again!!!

Simple Typo in iCloudDocumentSync Documentation

Under "Monitoring Document State" in the iCloudDocumentSync documentation, the completion handler is given this input signature: (UIDocumentState *documentState, NSError *error) but the actual signature should be (UIDocumentState *documentState, NSString *userReadableDocumentState, NSError *error).

Automated Documentation Builds

Documentation builds should be automated when building the Documentation target in Xcode. the docset bundle should be copied to the project's Documentation folder automatically.

setDocumentText method missing?

In the latest framework, there's an error in this method:

- (void)setDocumentData:(NSData *)newData {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul), ^{
        NSData *oldData = contents;
        contents = [newData copy];

        // Register the undo operation
        [self.undoManager setActionName:@"Data Change"];
        [self.undoManager registerUndoWithTarget:self selector:@selector(setDocumentText:) object:oldData];
    });
}

It shows as a warning because setDocumentText method doesn't seem to exist. I'm wondering if it's a typo or it's missing from one of the commits. I don't quite know enough yet about how it works to fix it, but I'm sure it's a simple fix for you.

Crash after calling application:openURL:sourceApplication:annotation:

I have a very strange bug. My app needs to be able to open custom files (currently sending them as email attachments). The moment a file is imported (successfully) and the application:openURL:sourceApplication:annotation: is called, the next time I use the

[iCloud uploadLocalOfflineDocumentsWithRepeatingHandler:completion:] 

method, it crashes.

screen shot 2013-12-13 at 17 02 50

My guess is that you should skip this kind of files when synchronising.

Also on a related note: Is there a way to ignore certain folders when synchronising local files?

URLForUbiquityContainerIdentifier in main thread?

Hi,

I maybe missing something, but the way I see it, the call to

+ (BOOL)checkCloudAvailability {
    // Check for iCloud Availability by finsing the Ubiquity URl of the app
    NSURL *returnedURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; 
}

in iCloud.m line 88 ff. is running on the main thread, isn't it? But it really should not:

In the Apple developer documentation, Apple said:

Always call the URLForUbiquityContainerIdentifier: method from a background thread—not from your app’s main thread. This method depends on local and remote services and, for this reason, does not always return immediately.

And should this not be called only once, when initializing the iCloud? When checking for iCloud availability the method ubiquityIdentityToken is pointed out by Apple.

While your fantastic library runs much more stable now, the only issue I have are crash logs coming in based upon some mysterious thread-thing. Maybe this is related?

Thank you once again so much for your work!!!!

Need guidance / Access all files from iCloud

I am preparing a Demo iCloud Project for my College presentation. I have started implemented it and luckily I found this demo and implementation. It is very simple. Great work by the developers.

I have some questions please reply if you have solutions:

  1. Can I use it for College Presentation Demo?
  2. How I can create a new folder in Apps Document Folder?
  3. How I can get all created reminders/event, Key Notes, etc. which I have create on iCloud.com (web browser). I am not getting all of the files from iCloud.com. I am only getting my apps folders... I think it might be possible.

Deleting iCloud files

Hi, thank you. Your project is very helpful.
I seem to have an issue with deleting files from iCloud, though. Sometimes they get deleted but usually they stay and just trigger iCloudFilesDidChange, Also if I delete them from the local storage they get downloaded right away as new files, I can prevent that while the app is running by placing them into an array of deleted files but most of the time they still remain in the iCLoud storage after [iCLoud deleteDocumentWithName...] even though no error is triggered. Those are small .plist files.

Another issue, when I delete files from iCloud storage manually through the iCloud account Manage Storage, it triggers an infinite loop of errors in iPad if the app is running at that moment. [iCloudDocument handle error... Cocoa error 513

Thanks!
Alex

Not compatible with iOS 5.1.1, documentation needs updating

Your main project Readme states:

Requires Xcode 5.0.1 for use in any iOS Project. Requires a minimum of iOS 5.1.1 as the deployment target.

Supported build target - iOS 7.0 (Xcode 5.0.1, Apple LLVM compiler 5.0)
Earliest supported deployment target - iOS 6.0
Earliest compatible deployment target - iOS 5.1.1
NOTE: 'Supported' means that the library has been tested with this version. 'Compatible' means that the library should work on this OS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly.

However, ubiquityIdentityToken was introduced in iOS 6.0 and is used in a couple of places in iCloud.m. Also, NSUbiquityIdentityDidChangeNotification was introduced in 6.0.

Please update your readme to increase the earliest compatible deployment target as it is clear it DOES rely upon unavailable SDK features.

iCloudFilesDidChange: called repeatedly

The iCloudFilesDidChange method:

- (void)iCloudFilesDidChange:(NSMutableArray *)files withNewFileNames:(NSMutableArray *)fileNames

Is called nearly five times in a row after each other. I would like to display a spinner until the sync is done, but I don't know whether it will be called three times, four times, etc. So I don't know when to stop the spinner.

But ignoring the spinner (I can work around that), why is this method called so many times after one change? Wouldn't it be simpler if was just called once?

Renaming and moving a file

First of all, thanks for the great work! It really simplifies the use of iCloud in XCode.

I believe you don't have any methods for moving or renaming iCloud documents, right? It would be great to add them. I have the code here:

Renaming Files

- (void)renameIcloudFileWithURL:(NSURL*)sourceURL destURL:(NSURL*)destinationURL success:(void (^)())successBlock failure:(void (^)(NSError *))failureBlock {
    NSParameterAssert(sourceURL);
    NSParameterAssert(destinationURL);
    NSParameterAssert(successBlock);
    NSParameterAssert(failureBlock);

    // Do the actual renaming
    __block NSError *moveError = nil;
    __block BOOL moveSuccess = NO;
    void (^accessor)(NSURL*, NSURL*) = ^(NSURL *newURL1, NSURL *newURL2) {
        NSFileManager *fileManager = [[NSFileManager alloc] init];
        moveSuccess = [fileManager moveItemAtURL:sourceURL toURL:destinationURL error:&moveError];
    };

    // Coordinate renaming
    NSError *coordinatorError = nil;
    NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
    [coordinator coordinateWritingItemAtURL:sourceURL
                              options:NSFileCoordinatorWritingForMoving
                     writingItemAtURL:destinationURL
                              options:NSFileCoordinatorWritingForReplacing
                                error:&coordinatorError
                           byAccessor:accessor];

    if (moveSuccess) {
        successBlock();
        return;
    }

    if (moveError) {
       failureBlock(moveError);
       return;
    }

    if (coordinatorError) {
       failureBlock(coordinatorError);
       return;
    }

    NSAssert(NO, @"should not happen");
}

Moving Files

- (void)_moveURL:(NSURL*)sourceURL destURL:(NSURL*)destinationURL success:(void (^)())successBlock failure:(void (^)(NSError *))failureBlock {
    NSParameterAssert(sourceURL);
    NSParameterAssert(destinationURL);
    NSParameterAssert(successBlock);
    NSParameterAssert(failureBlock);

    // Do the actual renaming
    __block NSError *moveError = nil;
    __block BOOL moveSuccess = NO;
    void (^accessor)(NSURL*, NSURL*) = ^(NSURL *newURL1, NSURL *newURL2) {
        NSFileManager *fileManager = [[NSFileManager alloc] init];
        moveSuccess = [fileManager moveItemAtURL:sourceURL toURL:destinationURL error:&moveError];
    };

    // Coordinate renaming
    NSError *coordinatorError = nil;
    NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
    [coordinator coordinateWritingItemAtURL:sourceURL
                              options:NSFileCoordinatorWritingForMoving
                     writingItemAtURL:destinationURL
                              options:NSFileCoordinatorWritingForReplacing
                                error:&coordinatorError
                           byAccessor:accessor];

    if (moveSuccess) {
        successBlock();
        return;
    }

    if (moveError) {
        failureBlock(moveError);
        return;
    }

    if (coordinatorError) {
        failureBlock(coordinatorError);
        return;
    }

    NSAssert(NO, @"should not happen");
}

Hope this helps! And thanks again...

iCloud Framework

Hi Buddy,
I am unable to find the iCloud.framework in the project. Please let me know how to download or from where I can download this framework.

Thanks in advance
Manoj

Getting NSData from a document returns NULL

Although files are properly written to the iCloud App Sandbox (this can be checked on the iCloud developer site), they are not being read properly. When calling the method below, it always returns nil or NULL:

+ (NSData *)getDataFromDocumentNamed:(NSString *)name

We plan to fix this issue as soon as possible. Please feel free to help out or contribute to help fix this problem or others.

File not deleted after calling deleteDocumentWithName

Hello everybody,
I love iCloudDocumentSync it works perfectly, but my question is:

Is there a reason why After I call deleteDocumentWithName on a valid iCloud filename, it is not deleted, and there's no error.

It seems that the cloud continues to push me the file that I'm managing to delete.

Can you help me please ?

I want to delete that file from ALL devices.

Thank you very much and again congratulations!

Giorgio

Thread Management, Singleton Double Init, Save Document Bug

I'm wondering, if the iCloud.m methods - (BOOL)checkCloudUbiquityContainer and - (NSURL *)ubiquitousContainerURL are returning as expected, when they return a value after dispatching to another thread to get that value. In...

- (NSURL *)ubiquitousContainerURL {
    dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
        ubiquityContainer = [fileManager URLForUbiquityContainerIdentifier:nil];
    });

    return ubiquityContainer;
}

you're correctly dispatching the time consuming URLForUbiquityContainerIdentifier:nil method to retrieve the ubiquityContainer but you're returning it from the main thread (i.e. without waiting for a result).

But then, I may be missing the point here...

I found the singleton-implementaion in version 7 to be very useful - just the initialization process is a bit confusing; I'm sure not the only one who's looking for some kind of completion handler returning after iCloud is finished with the initialization so I could setup some other things.

Thank you so much for your work!!!

Use a document without caring whether it's in local or remote storage

I notice that there is the option to "Sync documents to iCloud by moving them from the documents directory".

To use this functionality would I first look in the Documents directory and then iCloud?

I think to enhance this, it would be great to have a function which handles this logic for me... e.g. if it exists in iCloud it returns that document, otherwise it checks the local Documents directory. That way in my code I could happily just "use" the file without caring whether it's in local or remote storage.

Then the syncing could happen in the background without me having to check location in my code in each place I want to use the file.

Folder support

Can you add folder support? Currently It returns all the files even in folders and then reports the files in the folders are missing. It would be nice to show the actual folder though and then navigate into the folder.

OS X Compatibility

Make the library work with OS X apps to for a seamless integration across all devices and platforms. Especially add the ability to display the Open File / Save File views.

How to get list modified files?

In method iCloudFilesDidChange:withNewFileNames after changing one file returns list with all files iCloud store, how to get only modified files?

ARC Feature-check False Fail in Version 7.2

In a non-ARC project I have set iCloud.m to compile with the -fobjc-arc flag, but iCloud.h does not appear to be aware that ARC is enabled, so pursuant to version 7.2's new feature-check, iCloudDocumentSync will not compile. I am not aware of a method in Xcode to enabled ARC for a header file. Should the feature-check occur in the implementation file rather than the header file?

iOS 8 Compatibility

We are porting our app to iOS 8 with library version 7.3.0. We are finding that the methods below are not working and the handler is not called.

- (void)retrieveCloudDocumentWithName:(NSString *)documentName  completion:(void (^__strong)(UIDocument *__strong, NSData *__strong, NSError *__strong))handler;

- (void)saveAndCloseDocumentWithName:(NSString *)documentName withContent:(NSData *)content completion:(void (^__strong)(UIDocument *__strong,  NSData *__strong, NSError *__strong))handler;

Do you supporting iOS 8, or plan to release a new version soon?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.