I love [App.Net](http://alpha.app.net), because of the many interesting discussions that go on there. So, recently, [Ben Brooks](brroksreview.net) brought up a point I've been thinking about for quite a long time. Actually, exactly since I first implemented iCloud together with Core Data in an iOS app. The point Ben made was about [app silos and the file system](http://brooksreview.net/2013/01/app-silos/) (read the entire piece, that's a good one), and the inherent advantage of iCloud over Dropbox… if we except that iCloud does not allow to share documents between apps. Not being a developer, Ben sees the solution from the user's point of view, which is always the most interesting point for us developers. The solution he would like to see implemented is elegant (quoted from his piece): - Enable iCloud - Open files from a dialog that pops up listing all the files you have made in that app. - Saving is automatic. - If you ever need access to a specific file outside of iCloud, open Plain Cloud. Then the critical point (still quoting Ben): "I think the easiest way for Apple to appease those less than impressed with iCloud is to add the “Open in…” dialog to all iCloud apps and finally allow users to “share” iCloud documents between apps." This sparked quite a reaction, and [Federico Viticci](http://www.macstories.net) at MacStories made a fair point in his [response piece: "Open in… is not a solution"](http://www.macstories.net/links/open-in-is-not-the-solution/). Quoting Federico: "The problem is still the same as September 2011: duplicates. Decades of computing have shown that the filesystem is the single most complicated aspect of managing documents for the majority of users. People forget about “where they put stuff on the computer” all the time, and others keep simple levels of hierarchies because going deeper into the filesystem is, for them, annoying, “dangerous”, complex, or a combination of all these factors. In this regard, Apple’s “silo” model had a liberating effect: _here are your documents, available in an app with a nice icon that you can immediately recognize_." ### Why is it a hard problem? ### Both authors have fair points, and I'd like to discuss a bit more on what is going on behind the scenes. The first question we should address, and that will also answer the question "why is iCloud wonky at times", is: "is it a difficult problem?" The answer is: Yes! It is an incredibly difficult problem, for various reasons… and the silo is not the main culprit. If we backup a bit, what do we have, as developers, to implement iCloud? We can essentially store a dictionary, some documents in a silo (basically, a folder), or a database with all that goes with it. iCloud does the syncing automagically (well, no, in fact, but let's suppose it does for now). In that list, for a normal implementation, ie. without considering any sharing, the first item will always remain attached to one app only. The dictionary is used mainly to store user specific settings/preferences, or simple data like high scores and the like. The second is getting you to the app silo, and is… okay to implement. At least syncing is properly done, and most edge cases are dealt with properly. What one needs to understand is that the dev task is not to perform an upload or download of the file when it is created or modified: that's easy, the iOS SDK does and excellent job at that. What is hard is all the edge cases. Example: your connection drops while you re-opened a file that is still opened and edited on another device. Which one gets precedence? Or my last favorite one: connection drops while moving between 3 cell towers due to competing signals. Which transfer resumes first? Trust me, when you understand that you're going to have to deal with all these exceptions one by one, you cry[^1]. Now, the case of documents is fairly straightforward, the case of a database is a nightmare. Here, not only do you have to deal with one-to-one or one-to-many relationships, but it also introduces many-to-many relationships. Without entering into details, a broken relationship means: you're fucked. Well, your user is, as he will need to refresh his database from the last known good version. Again, Apple does a pretty good job at preventing this… but the implementation is far from easy. Contrast that with Dropbox or Parse.com[^2], which deal simply with one-to-many relationships - easy (easier). ### Is there a solution? ### Been thinking about that a lot lately. For the reasons exposed by Federico, data export is not appropriate. Though that would be the easy one: iCloud allows you to share a link already, one could easily imagine that this link could be used to "open in…" in another app. But this breaks the synchronization, as there is no way, unless the other app pushes back another link and the first (original) app is able to re-open and sync… So we're doing twice the job, the two developers need to agree on formats and most importantly all these edge cases when things get bad. And they will. End of the discussion, cannot be done that way. One little known feature of Core Data is that it now (since iOS6, but I may be mistaken, it may have come with iOS5 actually) allows you to store large chunks of data externally. Typically large images (larger than 1Mb) can be used by your app and left in the Photos.app - you can even "lock" the original image imported. That's useful for instance in the case of photo albums, where you do not want to duplicate the image data, as solid state drive space is expensive on these devices. That's an awesome feature, and a working example of what a "contract" between apps should or could be. So, "contracts" between apps and the system seem like the perfect solution, right? The dev signs a contract with the system, that lets him interact with a certain kind of documents, which means that the app gets a key to bypass the silos: come in, get out, with the rights to modify just one type of document. Simple in essence, we even get the "open in…" and this corresponds to Ben's typical workflow. The main difference with the above-mentioned discussions is that: the document does not leave its original silo, it's just the access that is shared. Can Apple do it with a flick of the switch? Not that easy, but not that complicated actually. Most of the building stones are in place, but, but… ### Why don't I have it now? ### Let's get back to what the dev would have to implement first: say his document structure, declare his document extension, and give permissions to access the files of a certain type in his sandbox. Easy. Then gobble up all that information into his provisioning profile, via a new certificate. Oops. One more layer of nightmare dealing with f$%#$%^ing provisioning profiles. But we eventually get there. On Apple's side: probably generate a couple of private/public keys to manage the permissions to the silo. Easy. So, where's the catch? The catch remains: if app B breaks say the document in app A, who are you pissed after? Here's a nastier one: version control on multiple users documents. An even nastier one: jaibreak removes the key and replaces it by its own. The falsely authorized document (and we're no longer talking about plaintext or images here, but of more complex data structures - think Word or Postscript files) now contains a trojan that, thanks to the tempered-with key, gets access to the root of the non-jailbroken device, and, and… Bang! Come to think about it: Windows 8 implements contracts, I think. In a sense, they have kept the same undelying file system, and revolved around those problems. Now, how many security fixes have Win8 users (the dreaded system updates and patches) implemented since the beta days? Raising my case: how many security and system updates have you implemented sice iOS6 came out last June? Is this worth the discomfort of the sandbox system? Hell yes! ### Will it eventually come? ### Eventually, I would think that yes, this is possible. The situation is complex, and some solutions exist. The most probable at this point is that of a "Neutral" ground, that does not break the sandbox. One would place the file in the "Neutral" zone, to be used by others, after accepting the terms of the "Neutral" zone. iCloud would then take care of the syncing between apps, just as it does (when everything works ok) for the documents your app saves in the cloud. In a sense, that "Neutral" zone would be an exchange hub that is managed by the system, not by the app. And _that_ is way easier to do from both Apple and the developer's point of view. I could see it happening, with some restrictions regarding file types. It is true that both TextEdit and Preview need their equivalent on iOS (particularly the later, damn that thing is good if you don't mention the few bugs that are plagging it), but that's not all. [^1]: particularly after troubleshooting the first one, when you realize that there's 20 more cases that will throw you out. And cache management is a bitch. [^2]: Parse.com is described by all those who have used it as "what iCloud should have been". While I'm a big fan and have been implementing it in Client apps since its beta stage, I still must confess that it has the advantages of its limitations. The database structure is way more simple than what is allowed by Core Data… but their "saveEventually" function is generally worth the extra complexity added by flattening your data structure. That is, when it is possible.