Questions about ios14 widgets -- fetching dynamic data from container app - ios

I am mainly just looking for clarification or resources. Let me explain my situation.
I have an app that internally relies on an always-up-to-date database of items. I'd like to show off items that were released close to today's date. I originally thought I'd just query my database and fetch the relevant items from there. So I began the long process of updating target values so the widget could see my classes, etc... But that was such a HEADACHE.
I thought surely there must be a more lightweight method the designers had in mind, so I then read about "app groups" and being able to pass information via saved settings/preferences. So basically when the app runs, you store some data as json and then you can fetch that information in your widget.
But then, to my knowledge, the data won't update unless the user runs the app again. I was hoping I could keep this widget up to date even if the user hasn't used the app in a long time.
What exactly is the process I should be using to achieve this? Are "app groups" basically the only way to do this? Will I just have to accept that I will often times have stale data?

Related

How bad is it to show Parse object id's to user?

I have a built in QR Code scanner in my iOS app. My backend runs on Parse, and I want the user to be able to pick certain objects on the app and encode their id's into a QR Code and share it around so that users can later scan a QR code, receive the object id's, and query them on the database to later fetch and display them somewhere.
However, what is stopping someone from using a QR scanner outside my app, looking at the object id's encoded into the QR, and messing something up? How bad is it to somehow allow users to see the object id of an entry in your Parse database? Will this heavily compromise security?
I thought about encrypting the object id's but am afraid my app will be rejected by Apple because of not following proper standards. What do you guys suggest?
Short answer: No.
There is no major security risk in giving away object IDs. Unless the 3rd parties had access to your app keys, then there is no way for them to access your data, even if they already knew everything about it. As long as you keep your app keys well hidden, there is no way your users can change anything outwith what you've de
Remember that your object ID's are only unique in the scope of your app (perhaps only even in the scope of that particular class), so when they find the object ID, they don't know if it's your app, my app, or anyone else's app - to them, it is as useful as holding a random set of digits.
The bigger issue I would say is that you cannot set the object IDs, so if for whatever reason that line is deleted, you can reinstate every part of it, but they'll all have different object IDs. This would mean your users running around with meaningless QR codes. Sure you can restore from a backup, but you'll lose any other changes since then. This is why I would never recommend indexing using Object IDs, rather that you create a new column "ID" that can then be changed by you, and then scripting a piece of cloud code logic in the side to ensure it is unique.
Sharing the object ID is not an issue, so long as your app has proper security. Hopefully your app's security does not rely on keeping the object ID secret.
Encryption is fine in iOS apps, so long as you file the proper paperwork. One of my apps uses a very high level of encryption and is available in every country, except France. You just need to file the correct paperwork and it's not that hard to do.

Creating CloudKit records on scheduled days

I'm working on an app right now that lets the user create new records on a recurring basis, and lets the schedule how many days in advance they want to create those records. This will almost always take place at a time when the app is not running, so I'm exploring my options for getting the app to be woken up to create the objects. As far as I see it there are four options, one of which is probably not really an option, since I'm trying to use only CloudKit and avoid creating a server-side component.
Option 1:
Use Background fetch to periodically refresh the records and check to see if anything is changed. In this instance I would probably have some kind of CloudKit record that represented the recurrence, in addition to the record type that needs to be created. Then I can just check the recurrence object and create a new record if needed
Option 2:
Schedule a local notification when the user schedules the recurrence. I thought this was going to work, but as far as I can tell, the app will not actually be launched even if it's a silent notification, unlike remote notifications.
Option 3:
Write some code locally that will check a data structure whenever the app is launched to check to see if any new records need to be created.
Option 4:
Create a server application that will create the records for me. Like I said, not really something that I want to do, even if it's the "best" option usually.
With option 1 you can not be certain that your app is running.
Option 2 won't work. As you said the app won't be activated. Or the notification must nog be silent and the user has to select to open the app.
Option 3 is much better than 1 and 2 if you don't mind that it could happen that the records won't be created for a long time if the user never opens up your app.
Option 4 is the best option for this. you will have full control over when to add what.
But... Do you already know in front what data to add? Then why are you adding that data? Can't you just calculate it and assume it's there? Maybe even based on a settings record or so?

How to ensure data consistency and truly take advantage of Core Data?

I've worked on several iOS apps, some of them utilize Core Data, and some of them don't. While I consider myself having a basic to somewhat good understanding of Core Data, there's always something that makes me doubt the usefulness of it. I've done a lot of reading on the subject, and the general consensus seems to be the advantages of using it outweighs the disadvantages. I recently submitted an app without using Core Data, and always planned on going back to update the project to utilize it when I have the time for some optimization work. Now's the time, but I wonder if it makes sense for the app I'm working on, and maybe I am not using it correctly all along. Please advise and point out what I am missing.
The project I am working on is a social networking app, which also has a front-end site. We have standard features like a newsfeed, event listing, the ability to follow/unfollow someone, and a map with POIs at user's location. Currently, we're using pagination whenever needed when requesting data from server.
My understanding of why Core Data is great:
Easier to manage data with complicated relationship
Easier to access data without having to pass them around
Easier to manipulate, fetch, and sort your data
Better memory utilization
Improve perceived performance by preloading data stored locally until latest data's received
The problem I am having is, since I am using pagination when requesting for data instead of requesting for all at once. The data stored locally is only a subset of the current state in the database. Let's use newsfeed as an example. If I do the following, it will cause some problems:
User manually refresh the newsfeed -> Controller notifies model that it needs the latest 20 items -> Model requests for the latest 20 items in the newsfeed and save them as NSManagedObject -> Model notifies controller that data is ready -> Fetch the latest 20 items to show in UITableView
If user A refreshes the newsfeed, background the app, and then user B deletes his post in the newsfeed (let's say it was 10th item) before user A foregrounds the app again to refresh the newsfeed. In user A's newsfeed, B's post will still be up there because according to the createdAt attribute, it's indeed one of the latest 20 items.
To fix this problem, I can think of a few solutions:
Add a flag to the item to indicate it's removed
Always discard local data when new data arrives
Disable pagination
Instead of using the workflow described above, always present the requested data only instead of fetching the latest
Solution 1 means custom code is required to deal with different clients since browser doesn't need deleted items but iOS client does. However, even though it can work, it can potentially mess up the pagination mechanism and can cause weird behaviours in the client. For example, if a large amount of items gets removed, the latest 20 items will contain only a few items that will actually show up in the newsfeed on the client when user refreshes it. As user follows more people, more stories will be inserted in his newsfeed as well. This solution won't work very well in this situation.
Solution 2 totally defeats the purpose of using Core Data in the first place unless I am missing something.
Solution 3 means the client always needs to request for all data. This is nearly impossible to do because as you get more data, the time to retrieve and process them will make the app slow and unresponsive. It also doesn't make sense from technical and UX point of view.
Solution 4 also kinda defeats the purpose of using Core Data because it's the same workflow when we only store data in memory. You can still fetch and find objects but they might be invalid on the server already at the time of access.
Am I missing something? How is Core Data supposed to be used in this scenario? How do you ensure data consistency when the client doesn't have all the data? Thanks you in advance.

How do I perform Core Data Migration to an existing app, if all I'm changing is the SQL Db's content?

I've checked a lot of sites and answers and I can't find any solutions specific to my problem.
I don't need to change the schema for my Core data model, all I need is to modify (add some) content to the current backing SQL Database.
Any direction on this will be welcome. Thanks.
PS: I tried Apple docs and they were about as useful to me as sunshine on Mecury.
Also go easy please, I'm a beginner.
Thanks.
UPDATE;
To shed more light on my issue, my app works as thus. I have preloaded static information on the app that can't be changed by the user, each day has new content. Every month, I push an update with entirely new content specific to that month. However, when my app entered production, upon the update I pushed for this month, my users were complaining that they couldn't access the month's data. This led to me spamming them with Push notifications to have them delete the app and do a fresh install to access the new data.
How can I fix this issue? my schema stays the same, only the data changes.
If I understand correctly you want to pre-fill a Core Data database ?
If you don't care about pre-existing data on existing app, you can make an iPhone or Mac app with the same model, and let it generate the database, like explain here (Any way to pre populate core data?) it's also the way recommended in a really great book if you want to learn more about Core Data (http://pragprog.com/book/mzcd2/core-data).
Do not ever make SQL request directly, Core Data work in his own magic way.
Don't work on the SQLite-Database directly. Change all your Data through NSManagedObjectContext! To find a good strategy look up examples from Batch-Importing.
Update: You could actually have two PersistentStores (one with just static data (readonly) and the other one with user-generated data). You could interchange the readonly which you prefilled with a commandline util and downloaded from a server. You cannot have direct relationships between those two store though.
I would say that it depends on the amount of data in this prefilled store wether you should go this way or just use a plist and reference some string constants in your user data store. Try to do it with a plist as this is the simpler approach.

How to split an iOS sqlite db?

I have an existing iOS app that uses core data for app data and user data. My problem is that updating app data is a nightmare (my first app, so I didn't do it ideally the first time). I would like to split the app data and user data into 2 separate sqlite dbs (or stores, correct me if my terminology is wrong).
Any tips would be appreciated.
Having two sqlite files is a good idea. The pain is splitting them now.
Create a new store that only exists in your app bundle. Make sure the data is unchanged from when you first released the app.
You are going to need to walk the "user" store and find all of the data that is identical to what exists in the "reference" store and delete it. If the user has changed that data then I would leave it and let the user sort out duplicates.
Once that is complete your app can resume normal function and load up both stores. I would set a flag somewhere so that you know this has been done and you don't run the check on every launch. The "user" store's metadata is a good place.
Note, this will need to be done before the user can "use" your app. This probably means changing your launch routines so that if a migration and filter is needed you tell the user what is going on.
I don't think having multiple persistent stores is the right solution. You can simply have separate entities within a single persistent store. Core Data will handle it properly.

Resources