iOS application with local and iCloud support - icloud

If the ubiquity container (iCloud folder) is not available for whatever reason, I add any new documents to the users 'Documents' directory, however, should it become available again I add the documents to the ubiquity container.
My question is, what is the best method to saving documents seen as a ubiquity container is so unreliable?
For example, if a user switches off documents in the cloud, those documents are deleted. Is there a notification to listen out for when this happens so I can transfer them to the local directory?
And vice versa, if a user switches the documents in the cloud on, is there a notification to move documents from local to ubiquitous store?
Thanks

No automatic notification, the files in the ubiquity container either disappear or reappear. Your app logic has to take account of what files need moved into and out of iCloud when they're visible to you, but once they're gone, they're gone!
IMHO, having data disappear is one of the most user-confusing things about iCloud. The user expects it to sync stuff, but it's an all or nothing game at the moment. The only way around this if you really want more 'sync like' behaviour is to have both a local non-ubiquity copy, AND a copy in the local ubiquity container so it gets uploaded to the iCloud servers. That then means you've effectively got two copies of everything on every device. Messy.
Much easier to stick to the Apple mandated method, and assume the user knows what they're doing if they log out of iCloud, or delete your data from iCloud.

Related

What's the underlying reason that object storage can not support edit/update/append file?

I know object is immutable and its content could not be edited, but I'm curious about why.
Is it because S3 use RESTful API and PUT doesn't support partial write? But why not just transfer the data of the updated blocks and update the file by S3 backend server? Or implement the HTTP PATCH method?
By the way, when playing video (.mp4) that store on S3, it seems it can support random read because I can do jump in the progress bar instantly without waiting, I'm not sure wheter the S3 client I use (RaiDrive) has local cache or S3 itself support random playing video.
It has nothing to do with a patch request. A patch request just means the method verb string is patch. Someone still has to provide the ability to do what you are asking for.
The main reason is that by making it immutable entirely makes the ability to provide distributed, replicated, versioned, scalabale, and highly available storage system like s3 a bit easier.
If it were mutable - it would make building a system like s3 a lot more difficult.
Many distributed storage systems move to immutability to make it easier to architect and design. Even google file system only allows appending which is why they use level db to support workloads instead of btree type dbs that require writing to the middle of files

Drupal 8 - What is PrivateTempStoreFactory and it's purpose?

Is this the same as php $_sessions?
Does it use php $_sessions? (edited)
When should I use it?
What are some down sides of using it?
Can or should I use it to store user input and results of forms for later operations?
And is it secure? (edited)
The private temporary storage differs from session storage in very significant ways and it is not intended as a replacement of it.
For logged in users, sessions are completely irrelevant, the data stored in the temporary storage is shared among all sessions of a given user, current and future.
Only for an anonymous user are sessions relevant: should their sessions expire, the contents is not retrievable any more because it is tied to the session ID. But the data is not stored in the session storage for anonymous users either, only the session ID is relevant.
The data expires after a time set on the container parameter called tempstore.expire which has nothing to do with the session cookie lifetime (nor is the latter relevant for logged in users).
There is metadata associated with each piece of data: the owner (either the logged in user id or a session id) and the updated time.
The durability expectations completely differ. Sessions are fundamentally ephemeral. Many places will tie sessions to IP addresses. It is certainly tied to a browser and as such, to a device. As a corollary, if clients can't expect sesssions to last, there's no reason for the server to cling to them heavily: putting the session storage on fast but less durable storage (say, memcached etc) is a completely valid speedup strategy. However, the private temporary storage is durable -- within expire, of course. A typical thing to store in a session is a "flash" message -- the one you set with drupal_set_message. If you set one such and then the session gets lost, oh well. Yeah, informing the user would've been nice but oh well. I certainly wouldn't expect to see a flash message follow me across browsers and devices.
In theory, a typical thing to store in the private temp storage would be a shopping cart. In practice, this is not done because a) carts, if not for the end user but for the back office are valuable, not temporary data b) when a user logs in, their session data is migrated but their private temp storage is not. WHether this is a bug is debateable, at the time of this writeup I can't find a core issue about this. This is a possible downside. So a Views UI like complex edit is one possible use case but note the Views UI itself uses the shared temporary storage facility, not the private one. In fact, the only usage I can find are node previews.
Here a very good articles about Storing Session Data with Drupal 8.
It cover exactly all your questions & more !
Take a look at it, the author give you also a lot of other links to help you.
Here a short summary:
1. Is this the same as php $_sessions?
Roughly equivalent. But (and it's an important but) using Drupal 8 services provides needed abstraction and structure for interacting with a global construct. It's part of an overall architecture that allows developers to build and extend complex applications sustainably.
2. When should I use it?
In past versions of Drupal, I might have just thrown the data in $_SESSION. In Drupal 8 there's a service for that; actually, two services: use user.private_tempstore and user.shared_tempstore for temporarily storing user-specific and non-user-specific data, respectively.
3. What are some down sides of using it?
Knowing POO.
4. Can or should I use it to store user input in forms for later operations?
Should.

Cannot restore lifetimevirtualgood item that was given as a gift

I use this method
soomla::CCStoreInventory::sharedStoreInventory()->giveItem(REMOVE_ADS_ITEM_ID, 1);
to give player one remove-ads item. After that, player remove and reinstall app again and click on Restore Purchase button but no remove-ads item is restored.
I'm so confused that given item cannot restore or there are somethings I missed? Please help.
The restore functionality works by looking up what IAPs the user owns (on the App Store/Google Play/etc.), and gives each non-consumable locally so that Soomla knows about it.
Since you're just giving the item locally directly, restore items has no idea that the item was granted (since you're wiping the data that says it was). It's still only looking at the official stores.
What you can do is sync what items the user owns to the cloud, and restore from that, using a UID. If you want complete control, this is the best bet, but that involves your own servers and coming up with a way of generating UID purely from device information, and not one-size-fits-all. Then you'd give the items locally when you can verify that the same user owns it on your server.
But there is an easier way. Soomla has an official implementation where they do all of this for you: Grow Sync.
Update (May 2016): Soomla is now shutting down Grow Sync, Highway, etc. so you can no longer rely on those services.

Should app allow user to switch iCloud on or off?

The Apple documentations says:
When a user launches your iCloud-enabled app for the first time,
invite them to use iCloud.
Never prompt the user again about
whether they want to use iCloud vs. local storage.
What if the user does not pick iCloud the first time, but decides to use it later?
What if after using iCloud for a few days, the user decides to switch back to local storage?
What if a user runs out of iCloud storage space, but does not want to pay for additional space?
Should an app be designed to allow users to toggle between local and iCloud storage? If yes, what's the best way to deal with this?
Thanks.
Yes, you definitely need to be able to migrate a user between the two storage methods, for the reasons you include above plus more - what if the user signs out of iCloud? And what if that is followed by another iCloud user signing in? You need to handle this stuff and be able to move things when you can and even when you can't do that, save stuff in the right place and where the user expects.
How you handle it will depend on what types of iCloud storage you are using. For the key value store, you should also be caching that stuff locally (it's not an NSUserDefaults substitute).
For document and Core Data, you can sometimes migrate persistent stores back into local stores, and you can sometimes move documents out of iCloud to local storage. I'd recommend reading both the Document Programming on iOS guide and the iCloud guide to get at least a base idea of how to handle this.
One thing that can be tough is detecting some of these changes - the APIs are a bit underbaked in this regard. One technique that is used by some are 'sentinel files' that you place in ubiquity - if they're missing, you know that the iCloud universe as you knew it has changed.
Take a look at how Apple's apps handle this, like iWork. There's an iCloud switch in their settings bundle.

Use cookies without sending them back to the server

I need a way to stash some data that is global to the browser. If I open a new window with a URL from my app, e.g. via a bookmark, I need to access some data that was created in another window and never sent to the server.
As far as I can tell the only thing that is global to the browser and not just a window, (like window.name), is a cookie. The problem I'm running into is if I set a cookie the cookie is then sent with every request to the server, but I don't ever want this data on the wire. Is there any way to set a cookie and just use it purely as a bucket for storing some data and never send that data to the server?
The HTML 5 storage API looks like exactly what you want here, but unfortunately it's only supported by a handful of browsers right now.
Is there any way to set a cookie and just use it purely as a bucket for storing some data and never send that data to the server?
No.
You'll need to look into a plugin that provides dedicated offline storage facility, or use the HTML5 storage API and tell everyone to upgrade their browsers
If you decide to go the plugin route, as far as I am aware you have 3 options:
Google Gears
Flash - it has an offline storage facility - you could write a small flash app to store things using this facility, then interop with it from javascript.
Silverlight also has offline storage - as with flash you could write a small app to do the storage, then interop with it from javascript.
I'd probably look into using flash first, as everyone already has it.
Development would likely be a lot easier if you were to use silverlight. It's not as widely installed, but it is spreading pretty rapidly. Last I heard* something like 30% of browsers had it installed which is pretty impressive.
Google gears would unfortunately be a distant third. People are going to be installing flash and silverlight for other reasons, but nobody has gears.
*This is an entirely unsubstantiated quote, but does seem to fit with what I've seen on various people's computers, etc.
Can you mandate that your users install Google Gears? It's a javascript API that lets you store local info- also lets you persist between sessions, which may be useful for your app.
Why not just read a field in the parent window using window.opener ? Or if you've three windows running - parent and two children which I think you might be implying then read/write to a hidden field in the parent from the children.
Sounds like your app is running 100% local, if that is the case the browser isn't the way to go anyway. Cookies can be easily deleted. If your app isn't local the webserver should be the one supplying information. Cookies are never the correct way to store sensitive information or information that should persist over longer amounts of time.