Sharing data between apps on iOS - ios

I have several small apps that share common data (images, sounds files, etc). This data bloats the size of each app. When the user installs 2 or more of these apps that will bloat the device space with duplicate data. Is there a way that I can share this data between my apps so that each app doesn't duplicate this data within its bundle?

You can have a common file space between apps by using app groups. An example of how to use them can be found here: Sharing data in between apps in IOS
You can use this as part of a solve for not duplicating the data in every bundle. One way might be to have the data hosted on a server somewhere and when the app is installed you can check the App Group for the common data, if it is not there, you can download it and store it there. Then the next app that is installed will have the data already available. This should help avoid having to include it in every small app.
You can set up the code to check the shared location and download the data in a framework and share it between all your apps making it a bit easier to maintain. If you do not already have a content management system then you could google for a few that have iOS support. There are many out there. You would then host the shared data there. This would give you the ability to update the data for each app while they are in the field which could be a time saver. If these apps are very small though, this may be overkill.

No, this is not currently possible. Ideally, this kind of resource-sharing would require creating a common framework bundle that would have to
be submitted separately to the App Store as a third-party framework, so that even if only one of your apps is present on the
device, it would be able to load the appropriate resources and function properly.
Apple currently only allows third-party frameworks embedded within the app bundle.
Even if two of your apps use the same exact version of your framework, they have to embed it separately.

Related

Best practice for storing and updating images in Xcode project

I am building my flash card iOS app for reviewing my learning Japanese using SwiftUI language.
The problem is how to storing and updating my images(>500 images). Please help me, any suggestion is appreciated, thanks for reading my post.
I think you're asking about how to manage 500+ images in an Xcode project. You could just add all the images to your project and load them as you would any image. You could use asset catalogs, which have the advantage that they let you store different versions of a resource for use on different devices, and only the ones needed for the device the app runs on will actually be installed on the device. See How Many Images Can/Should you Store in xcassets in Xcode? and Asset Catalog Format Reference for more information about asset catalogs. But any way you slice it, managing 500+ images is going to be cumbersome. There's probably a better way...
Managing all those images in your app isn't just a problem for you as the developer; building them into the app will also create problems for the user. Even if each image is relatively small, having hundreds of them in the app will probably make the app huge. That means it'll take a long time to install, and the app will use a lot of storage on the device. Every time you release a new version of the app, with more words, or even just to fix a few small bugs, the user will have to download all that data all over again.
Instead, you should consider building an app that can fetch the data it needs from a server. Ideally, you could apply that approach to all your app's data, not just the images. Maybe you'll organize your flash cards into sets of a few dozen, so that you can fetch a set of cards and the associated images pretty quickly, and sets that the user hasn't used for a while can be removed to free up space on the device. You'll be able to update a set of flash cards without having to update the app, and when you do update the app your users won't have to download all the data all over again.
You've said that you're a beginner, so this approach might seems very difficult. That's OK, you can start with a simpler approach and then improve as you go along. For example, you might just put all the images on a server and fetch them one at a time as you need them. Your flash card data file could contain just a dictionary with words and the URLs associated with those words. There are lots of examples of loading an image from an URL here on SO and elsewhere, so I'm not going to provide code for that, but it won't be hard to find. The earlier you start thinking about how to design your app so that it can scale as you add more and more words, the easier it will be to maintain the app later.
500 images can have a huge size. Applications that published on Appstore have size limit and Apple does not recommend to make big apps.
Store them on server and load needed images on fly. Also you will get possibility to update your images, remove add new.
If you don't have a backend, you can use something easy and free (Firebase storage for example) or with minimal code writing on AWS.
If you need to keep them on device - store them as files in the Documents or another apps folder, do not use CoreData for it (you can keep only the list of names/urls in database).
After loading image to be displayed for user, you can prefetch next bunch of images.
Use Alamofire, or SDWebImage to load images from network (I prefer last). These frameworks can do many useful things with images.
To load images:
you can have a list of your images (just list of the names and urls)
or
you can know only path and names pattern and generate links dynamically (like https://myserver/imageXXX.png.

Sharing code between iOS apps and their watch apps

I have been trying to figure out the best way to structure my watch apps for the last couple of days, and haven't had a lot of success. Currently in my iPhone apps I have several libraries that I use for various standard things. This includes things like the base class of my data objects, helpers for converting them from JSON, and base classes for my services.
The problem that this causes for me is that I am unable to find a way to include these libraries in my watch extension, and this means that I can't even share any of the data objects from my main application because all of them rely on the library.
So, my question is, is there a way that I can share a library between my main app, and the watch app?

Where to store some private data inside Swift Module, Cocoa Touch framework?

I need to store some private data (current session ticket or settings) inside my current Swift module. For the simple app the options usually are NSUserDefaults or some file on the disk so I don't need any app using my Cocoa Touch Framework to be able to access (at least modify) this data from outside, cause some app may clean it's own documents folder for some reasons and developer might simply not know about my data stored here. Same situation with NSUserDefaults.
Do modules have it's own documents folder?
I'm just wondering, what is the correct way to do that?
Any help would be great, thanks!
A Swift module defines a framework. Frameworks get their own bundle (which they can use for static assets that ship with the framework) but I believe that there is no API guidance or convention defining where they should persist data that the framework wants to hide from the app.
If you look at Apple's File System Programming Guide, it only has a section on defining "App-specific" locations for persisting data. The Framework Programming Guide doesn't seem to say anything about defining locations that are per-framework.
Given that, what I would do in my framework code is just use the app-specific storage location, but put all of my framework's data under a subdirectory or distinctive key string that clearly marked it with the name of the framework and was likely to be unique. So instead of saving to the Application Support/ directory, I'd save to Application Support/MyFramework/.
This will stop your framework from stomping on the hosting application's data. It won't stop a malicious hosting application from inspecting what your framework is saving, but that's a much harder problem to solve. Also, a clumsily-written hosting application could erase your data if it just erased all of its own data with a wildcard, but that might be its intent.
UPDATE:
As the commenter suggested, the keychain is also a reasonable place. But the keychain's security infrastructure does not (I believe) actually cryptographically protect you from the hosting app. Nonetheless it is a key value store that the hosting app is less likely to completely purge by accident.
If you really want to try to hide larger quantities of your framework's data from the hosting app then, alternatively, you could explore using URLForDirectory(_:inDomain:appropriateForURL:create:) to find a system-wide (rather than app-specific) temporary directory, and then hide your framework's data in there. But I think all of those directories are subject to deletion at will by the system, so it would only work if you were saving data that your framework could regenerate later, perhaps based on a smaller seed of data, stored in a place like the keychain.
The bottom line is if you're shipping a framework for other people to use, you cannot strongly hide anything from an application developer using the framework. They can attach a debugger. Then you lose. (If you want to go into the deep end on this, there's a whole area called "white box cryptography" that describes protecting data from an adversary that can completely observe your operations. This is the basis of modern DRM systems.)

Share Files between Apps on the same iPad (Without iCloud)

I have two iPad apps, one which downloads data from a server and stores it on the iPad and another one (the main app) which uses the data later.
(It would make sense to combine the two but it's a client requirement)
But I see no way to share the data between the two apps.
I have heard there are ways to do it using:
Custom URL Schemes
Document Support on iPad Devices
UIPasteboard
But I cannot find any thing explaining how to use any of these effectively.
Can anyone point me in the right direction.
Just to clarify:
It is an iPad only app
Both apps will not run at the same time
Basically I need to access the documents or caches folder of one app from another
Using iCloud or any other third part service is not possible
It would be great if I could make the downloader app into a sort of configuration page for the main app (if it is even possible)
So keeping these in mind which one would be the most suitable?
This link at github may be useful... Looks like someone has already made a file manager, using these elements you may be able to do what you are looking for. But as far as I know, your app is extremely sandboxed and does not really interact with other apps/the file system very much at all (Apple is very limiting that way)
EDIT
this post seems to have the explanations of local data sharing methods you were looking for. None of the methods in this post requires any connectivity, just a device and 2 apps :) Good luck!

Lua in iOS and side-loading scripts

The latest game by Gameloft called Order&Chaos starts with a Checking for Update screen, which indicates that they're able to update certain data without updating the entire binary.
I'm quite certain that they're using some kind of scripting language like Lua in their app and updating these scripts to e.g. change certain values (like buying price of items).
What's your experience with side-loading or updating scripts in your iOS application?
I don't mean loading new graphics or other contents, but game logic like my path finding implementation in Lua.
Apple cleary states that this isn't allowed
3.3.2 An Application may not download or install executable code.
Interpreted code may only be used in
an Application if all scripts, code
and interpreters are packaged in the
Application and not downloaded. The
only exception to the foregoing is
scripts and code downloaded and run by
Apple's built-in WebKit framework.
This happens in most of these applications TinyChef, RestaurantStory, HotelStory, etc..
They update content, but not the core program. Just adds new content or modifies the existing using external files and DB updates from a remote server.
Example, what they do is download new graphics and add a new item to their Desserts table of their DB and finally when they show all their Desserts the new one shows up and its ready to be cooked as if it was in the app from the beginning.
I could elaborate more info if you need.
UPDATE
If you are using lua, you could easily add, say new levels to your games, just by downloading a file containing your level data. Im sure that you are familiar with using external files one per level/item/character with a common format you then parse in your app.
You can have your path finding algorithm in another file as i said, and update (download and replace) that unique file whenever you improve it.
I haven't tried this, yet, but wouldn't it be as easy as querying a server, getting back a string, then parsing that into the database?
That might not violate Apples policy, since it wouldn't be executable code, just delimited text.
You could probably do more complicated stuff that way too. It wouldn't be a whole lot different than DropBox downloading files to your phone so you can view them. But instead of a document file, it would be a 3D object.
I think 3.3.2 clausule is to prevent that anyone can download/buy from appStore an engine like Love2D for iPhone, create games/apps in Lua, download it on the iPhone via web and execute with this engine, because it means develop and deploy apps on iPhone using an intermediate SDK instead of the official SDK, and of course, without paying anything to Apple.
Think about it, you can create your own App Store with this system and that is what Apple wants to prevent. but i think Apple doesn't take care of this type of downloads, where you want to update your own apps logic or levels.

Resources