How to automate the creation of bundles for an iOS application? - ios

My iOS app uses data that is packaged by theme into theme bundles. For example theme_math.bundle, theme_history.bundle, etc. A theme bundle contains a .sqlite file and images. The idea would be that those bundles can be downloaded when necessary by the app (theme_x.bundle.zip).
There are hundreds of themes that are stored in a database, and I'd like to automate the process of creating a bundle for every theme with the appropriate name.
Is this approach fine to deliver application content to an iOS app?
If using bundles is fine, how can I automate that process?

This would appear to be a fine idea. You can automate this by creating a shell program file, or use some other scripting language (python, ruby, etc).
A bundle is really just a folder that gets special treatment. It can have an icon when viewed in the Finder, etc. So your high level program will create a bundle (mkdir Name.bundle), then copy whatever resources you want into that directory - Name.bundle. When you're done zip the bundle up, and put it where it can be downloaded.
Bundles often have a plist inside with special flags set (as an executable on OSX does), but don't think you need this.
Its possible that you may need to set some special bits on the bundle for iOS to recognize it - I really don't know for sure. If so see this thread.

Related

Pre-load content into Documents or Library directories from XCode

I am building an iPhone app that requires preloaded content. This content is presented so that it tests the user's knowledge, but is not modified by the user. The content consists of proprietary image files and pdf files.
From what I understand, the best practice would be to store this in the app's Library or Documents directories (please inform if this assumption is not correct). In a future version of the app I might want to upload additional (not replacement) content via API, but this is not part of the initial version.
I have seen many posts and tutorials regarding obtaining paths to the Documents and Library directories of an app, and reading/writing to them. This is all good and useful, but not what I am looking for here.
I would like to preload the content into the Documents and/or Library directories, for the simulator initially, to test app in simulator; and ultimately to the release version. I would have thought this would be possible to do from XCode without writing code.
I have not been able to find a solution to this on Stack Overflow or other places on the net. Any pointers, links, solutions are welcome. I am using XCode 10.3 with Swift 4.2.
See the File System Programming Guide: File System Basics, which shows us:
The “data container” (including the Documents and the various Library folders) is for content generated/saved by the app. When, in Xcode, you mark resources as being part of the target, that becomes part of the bundle, and your app can retrieve it from there at runtime.
Theoretically, yes, you could copy data from the bundle to the Documents and/or Library folders, but, yes, you would have do that programmatically. It seems a bit wasteful to have two copies of these resources on the device, but you can do whatever you want. Generally, though, resources included in the bundle would just be be opened directly from there at runtime, not copying it to the data container (except for those cases where you would need to change it, because bundle contents are read-only).
FYI, for additional information regarding the file system, see the iOS Storage Best Practices video.

Providing default population to "Library/Application support" folder

I'm writing an iOS app which needs a ~60MB resource file to work correctly. I would like to provide this file with the app itself, so it can work straight after installing it from the store without downloading extra data at the first launch.
I also want to be able to update such file by downloading a new version of it from a specific URL. I thought the most appropriate folder to store this file would be "Library/Application support", as specified in the guidelines provided by Apple itself.
My problem is that I can't find a way to provide the "Library/Application support" folder with a default population using xcode 9. I don't want to have multiple copies of this file around to avoid wasting space, and I want the possibility to update this file to a newer version, overwriting / replacing the old one.
This might be a newbie question (I'm a newbie of iOS development) but I really couldn't find anything related to pre-populating that folder.
You cannot delete anything from your distribution bundle. It's just not allowed.
So you options are:
Distribute the resource with the app, and create a copy in "Library/Application support".
Don't include the resource with the app, and download it on first run.
You didn't say what the resource is, so I don't know if this would be an option, but... Include only a portion of the resource with the app, copy it into "Library/Application support" and "update it" on first run.

Updating .stringsdict localization files over-the-air

I'm looking for a way to update stringsdict localization files over-the-air without having to release a new version in the appStore. So ideally I want my stringdict files on a webserver, and the iOS app should download these files from the website and update the local strings.
After doing some research, I realized that we cannot update files in the bundle it was shipped in however I found some reports saying we could store/load localizations in/from the application support folder.
source #1
source #2
source #3
Can this also be applied to stringsdict files because I'm trying but no success so far.
Basically you need to create a .bundle with your new strings and make your app download it. After that, I think it's possible to create a NSBundle object using your freshly downloaded translations and swizzle a couple of methods from the main NSBundle currently used by the system.
I've tried something similar, but found out that it's much easier to integrate an existing service such as Smartling or Lokalise. They already have an SDK that allows you to update your translation over the air.
Also I found it's much easier to manage all my translations there.

Is application bundle fully replaced on upgrade from App Store?

The following use case:
create a strings file (not localized) and deploy the application to your test device
localize the file (en.lproj or similar), make some changes to the new file and remove the original file
deploy the application on the device
What I noticed that very often (always?) the application will still use the old non-localized file. The reason is that apparently the file is still in somewhere the application bundle, even though it has been removed from the project. iOS's logic is that if a file of a specific type is looked up, it first checks in the root of the bundle for the non-localized version, and only if it doesn't find it does it go deeper into the localized folders. (Is it just me, or is this logic kind of backwards? I'm used to first looking for language specific file, and then falling back to some defaults, but it might be my Java background.)
Sometimes (always?) removing the app from the device completely doesn't help either. What does in this case is a CMD+SHIFT+K, which cleans the build folder, and after the app is built and deployed again, the correct file is used.
A worse problem would be if such a thing leads to an app crash, like some strange issues with Nibs or whatever - I have seen those as well...
The question is: what would happen if the first version of my app in the apple store had the non-localized file, and the second version localized it? When the user upgrades the app, would they get the same behavior as me during development (i.e. outdated, non-localized file used)?
I can't imagine because I think this would be a cause of a lot of grieving and bug requests, but I can't tell for sure as I haven't yet published any iOS app.
If the behavior is correct when upgrading from the store, why is it? What is so different? Are the files stored locally on my computer somewhere and used when I deploy?
Can anybody share their experiences?

FlashDevelop - Loading external swfs on iOS

My application needs to load external swfs with ABC. I checked that this feature is available in AIR 3.7 and later. I managed to get the new SDK - 3.8 with the latest version of FD (4.4.3).
Now I am following this link: http://blogs.adobe.com/airodynamics/2013/03/08/external-hosting-of-secondary-swfs-for-air-apps-on-ios/
According to this post, "During IPA packaging, ADT extracts the ABC code from all child SWFs, adds it to the final executable and generates stripped SWFs in the “externalStrippedSwfs” folder created in the current working directory. The directory structure within the “externalStrippedSwfs” folder remains the same as specified within the text file. The generated stripped SWF’s should then be externally hosted on a web server of developer’s choice."
However, firstly, I could not find any such folder called "externalStrippedSwfs".
Secondly, even if this works, this means that everytime I have a new external swf to load, I will have to get it stripped off the code, put it in the main swf, and then upload the stripped swf (with assets). So everytime I do this, I need to "reupload" my app to Apple.
Are these assumptions right? My app architecture will need to be modified accordingly.
Yes, your assumptions are correct: You can't load an external .swf containing AS3 and have the app execute the byte code.
If we ignore the fact that it would most likely not be approved by Apple it can't technically work. The reason is because the Adobe AIR app doesn't contain a virtual machine capable of interpreting the byte code in the .swf:
When you build your application for iOS, there is no interpreted code
and no runtime in your final binary. Your application is truly a
native iOS app.
Source: http://www.adobe.com/devnet/logged_in/abansod_iphone.html.
You can do it! :) You just need to upgrade to AIR SDK3.8+ and follow the painful process.
The only limitation is that each external swif that you will be loading at run time, must be stripped by your ADT.
But you are right: you will need to update your app everytime your external content needs to be updated.
"externalStrippedSwfs" is arbitrary (name it as you wish I believe), you have to create that folder in your bin and run the command line from there.
Looks like Apple is not ready to lose the leash yet...

Resources