Independent operation of watchOS app when sharing app with iOS app - ios

My iOS app uses CoreData as its data store and I have added a watchOS app to accompany it. Currently the workflow between the iOS and watchOS apps is as follows:
The watchOS app exposes a menu representing a subset of functions available in the iOS app
Choosing one of these options sends a message to the iOS app telling it which option was selected
The iOS app responds by packaging up any data needed by the watch for that particular function into a dictionary and sending this back to the watch in the reply handler
The watchOS app presents an interface to the user allowing them to change the values in the data
Each change sends a message to the iOS app which updates the core data store with the new values
This is working fine but clearly requires the phone to be connected to the watch throughout the use of the app for it to work. I'm wondering whether a model like the following would be possible:
As above
As above
As above
3a. The watch stores the data locally
As above
Each change updates the watch app's local copy of the data
The user can later check the data back in to the iOS app at which point it is merged into the core data database
I can guarantee that conflicts would not be an issue as the user would never be able to modify data which had already been created on the phone (it is not a requirement of the app to be able to do so).
So my question is, would the latter case allow the watchOS app to operate independently of the iOS app with the exception of transferring data, and is this a preferable method to the way I am handing this currently?

It's simpler for your watch app to be dependent on the phone. It's more complex for it to operate independently of the phone. Only you can
answer whether the added complexity to support true independence is worth it, since you're the person who has to implement, support, and maintain any additional code needed.
Do the changes make the watch app independent?
No, they don't let the watch app operate independently, since the watch still must request/receive data from the phone during steps 2 and 3.
For the watch app to be completely independent while away from the phone, it would have to query a local copy of the data which the phone updated as needed, instead of requiring the phone to send any remote data that the watch needs.
Is the change preferable?
Not as it stands. Your proposed change to defer updating the phone (even though it's still reachable) may require much unnecessary code related to locally storing data for the present, and merging updates back to the phone in the future.
Also, while you promise there presently is no merge conflict to deal with, there's no guarantee that any revisions you make to your app in the future won't introduce the possibility for conflicts to occur.
If you choose to establish two persistent stores, it would make your app less fragile to implement a merge policy now, to avoid your updates from completely failing to save, should a future conflict occur.
The real question...
Is the freedom to operate away from the phone (for hours) worth showing stale (or possibly misleading) data to the user?
Unless you also provide an indication showing when the data was refreshed by the phone, the user may assume that the displayed information is current and accurate, even though it may be hours old.
This adds more complexity to the watch app either in the user-facing UI or behind the scenes to handle stale data.
For your consideration, Apple Watch's Weather app simply shows no data at all when it can't obtain the current weather data from the phone (since users would want to know the current temperature and chance of precipitation).

Related

Force removal/invalidation of iOS app from user devices

Assuming you created an app that users have downloaded that is just awful and you neither want to fix it nor have anyone continue to use it so that it won't tarnish your brand, is there a way to end its life on user's iOS devices?
Curious if there is some store setting to force it to work with earlier versions of iOS and invalidates the current app, or code that would force an update that says the app is no longer available.
As many have confirmed, there is no way to remove an application from someone's device. For these cases though, many companies have servers that the application sends a request to on launch, that returns either a need to update the app, a message, or to tell the user the app has been discontinued and that the app cannot be used anymore, stopping them from using the app from there on.
The last use case might be useful to you, but of course this is a proactive solution, not a reactive one.

Retrieve user defaults information from an Apple Watch

I have an iPhone and an Apple Watch paired together, and there are some values stored in the user defaults of the phone. I want my Apple Watch to be able to retrieve that stored information somehow and bring it back to the Watch. What is the best method of achieving this with Swift?
Since watchOS2, you don't have any built in function for communicating between the iOS and watchOS app other than the WatchConnectivity framework. Due to the fact that Watch apps are no longer considered App Extensions, they don't have access to AppGroups and hence to UserDefaults on the iPhone.
For syncing UserDefaults, the updateApplicationContext(_:) function seems to be the best solution. You can send a dictionary of data with this function (the data you just saved to UserDefaults on the iPhone) and the system tries to make sure that the data is received by the time your app is displayed to the user. If the function is called several times before the app would be visible to the user (run in the foreground), the system overwrites the previous data, so the Watch app only receives the most recent data to display.

Share database [core data] between different devices, not just the user's ones

What is the best way, to share a database between different devices, that are not just the user’s ones, but for example could be his friend’s phone. That means that iCloud is not an option.
Example:
 All of my data is app-user specific, so basically:
user logs into my app, do some work
then he can log in with the same acc on his friend phone and data should be the same
Is there an any way to upload the whole user specific database to some online storage provider (like firebase,… ) and then download it on another device and initialise core data stack, when the same user logs in on a different device?
Or is it the only way to sync data with the server and than preload the database?
You could simply upload the whole database file(s) and then download it on another device. The problem though is portability. You need to ensure that both devices support the same version of the database so they are compatible. To port the same thing to another platform is again a different story but doable when not using core data.
Then there is a problem of conflicts. Imagine you forget to log out from the second device and you open it after a week and the database is accidentally synced back to the server. This will make you lose all the data you created on your "main" device.
So in general it is possible to sync the whole thing but you will have loads of issues. You should create a server that supports all entities and works through ids (so you know the object was modified and not created) and date modified to be able to resolve conflicts.
Syncing data between multiple devices is the biggest reason to use something like Firebase. That's one of its primary purposes. You would use Firebase for data storage instead of Core Data, and it would automatically handle syncing between devices. You don't write code to upload or download anything, you just read and write Firebase data and it handles the syncing. It supports user accounts, so if a user logs on on a different device, their data automatically syncs to that device. There are numerous other options besides Firebase, of course.
CloudKit also syncs between different devices, but it's linked to the current iCloud account on the phone. Since you want in-app login, it's not so good.

Packing IOS App with Large Amount of Data

How can I have the customer of an IOS app select and change selection data for use with an app?
I have an app that is designed to operate away from wifi. As such, it needs to carry its data around with it. This makes the data requirements rather large.
A base package is 25MB of data. However, it is likely people who use this app would want as much as 1GB of data.
Is it possible to do selective data downloads and updates from the app store?
How else could this be done
How can I have the customer of an iOS app select and change selection of data for use with an app?
Hard to say. It's not clear what you're talking about. Downloading data through an app is a well researched topic. You shouldn't have any trouble finding examples for downloading data to an app, here or elsewhere.
Is it possible to do selective data downloads and updates from the app store? How else could this be done?
Again, its not 100% clear what you mean. I don't think you can use the app store to provide new data to users who downloaded your app, unless you're talking about a full app update that comes bundled with your new data set.
I worked on a project once that had to work offline, but also work with a very large data set as well as some mapping components. We required users to first download our app, then after authenticating, the app would automatically download a cache of data while connected to a WiFi hotspot. When the user was out of WiFi range the app would operate off the data set they downloaded and would operate normally. When they came back into range it would ping the server to find out if their data was stale. If it was stale it would download new data. The WiFi connection requirement ensured that they would have an optimal experience fetching the latest data.
My thought is to create a menu in your app that lets the user select which "packages" of data they want to save to their device and run those downloads in the background when the user has an internet connection.

How can one app provide data to another without swiching apps?

Scenario:
I "control" two different apps, App A and App B, both which the user has installed
App A is running
App A needs to obtain a string that was set by App B when App B last ran.
After obtaining the string, App A will still be running
User should not receive any feedback this communication is happening. E.g. no "switching animations" between A or B, no pop-ups, etc.
Constraints:
Apps are released under different vendors
Apps are already in the app store; updated versions will have this communication ability.
It is acceptable for the data stored in App B to be accessible to other apps on the device.
It is not acceptable for the data stored in App B to be visible to general third parties (e.g. if an external server is used, there needs to be some sort of secured scheme)
The data read should be able to occur immediately upon App A being opened after install. For instance, I cannot require the user of App A to enter log in credentials for an external communication service.
Must work on non-jailbroken devices.
This is seeming rather difficult to pull off in iOS7. Help is appreciated.
Tricky work around. Not recommended, but it will get the job done if you can't afford servers.
On the first app create a contact in the user's contacts book. Give it a generic name like "000 - NameOfAppB Data - Don't Delete" (I start with "000" so it goes to the bottom of the users contact book so they never see it, I also add "don't delete" so if the user does somehow find it they don't delete it hahaha) (who looks at contact books anyways). In the contact info under notes add your NSData in string format.
Then when app A is opened search for that contact, read the data, then delete the contact.
Apple does allow you to create and delete users contacts without their permission. (At least in 2011 they did, this may have changed).
This might serve your purpose
https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/Reference/reference.html
I am not sure of its limitations though, i have seen implementations where credentials have been shared between apps.

Resources