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.
Related
I want to see the code of an iOS app.
The app I downloaded is .deb.
First question: Is it possible to install .deb file on iOS or I downloaded a wrong file?
After unpacking the .deb file, I got some files, including .nib, .storyboard and some other files.
My main question is, How to decompile these .nib files?
I tried to decompile these files using NibToXibConverter, but I didn't succeed.
Answer to your first question:
I think you downloaded the wrong file. .deb files for iOS are common for jailbreak community and not for apps, I think all of the Cydia stuffs are packed into .deb's. If your app is especially made for the jailbreak scene then you may try to install it using Cydia's auto install feature on a jailbroken device.
Answer to your main question:
This is general info about decompiling and modifying iOS apps (not specific for nibs, but you may still find it useful).
iOS apps are distibuted in .ipa archives, which are ordinary zip archives. They contain, usually one executable in the form of Mach-O file, and resources like .plist, sounds, images - every resource you include in your xcode project. Decompiling the executable file is only possible on jailbroken iDevice, because it is encrypted especially for the current device and the magic key to decrypt the binary is burned inside the device CPU and as far as I know there is no software way to read that key. The encryption system here is called FairPlay.
Briefly described, one way to decrypt that binary is to have the app installed on a jailbroken device, and launch it from command line using a debugger (gdb) which you can download from Cydia. You have to set a breakpoint somewhere, and when your code execution pauses at the breakpoint, you are doing a memory dump of the device ram - and that is your decrypted bin.
So when you have the decrypted binary, you can run one tool called "class-dump", and get the information for declared classes and their methods if the app is written in Objective C. Once you know this information you can alter the implementation of given method from some class used in your app using "Cydia Subtstrate" a.k.a "Mobile Substrate". In fact that is the way all of the jailbroken iOS tweaks are made. Basically you are hooking a method call, and when that method get invoked, it uses your implementation. Furthermore your implementation can call the original implementation, and that is really useful if you want to make some small code addition.
I am not sure whether those things possible in Swift, but if you are dealing with a Hybrid app like the ones done with cordova, phonegap, etc., then you can see all of its javascript source because it is persisted as a resource inside the "ipa" file. In addition you can alter that javascript code directly if you have a jailbroken device and find where the app is installed on file system (usually /var/containers/Bundle/Application/uuid_for_your_app/). However, I think there is no way to get that patched version and redistribute it (correct me if I'm wrong).
In my iOS app I am downloading a bunch of image files and saving them on disk in Library/Caches. Do I need to delete those files given iOS automatically clears them when its running low on disk space.
It depends where you save them. Read the File System Programming Guide for detailed discussion.
In Summary, If you are saving the files to:
Temp: You don't need to worry about cleanup, but you need to be aware that these files will not persist between app launches
Library/Caches Generally iOS won't delete these files but can clear them when running on low disk space. So developer has to make sure these files can be regenerated when required.
All other folders yes, you need to make sure the files are properly cleaned up when they are no longer needed.
UPDATE: Now that you have specified that you are saving to Library/Caches, From Apple Docs about Caches directory:
Use this directory to write any app-specific support files that your app can re-create easily. Your app is generally responsible for managing the contents of this directory and for adding and deleting files as needed.
In iOS 2.2 and later, the contents of this directory are not backed up by iTunes. In addition, iTunes removes files in this directory during a full restoration of the device.
On iOS 5.0 and later, the system may delete the Caches directory on rare occasions when the system is very low on disk space. This will never occur while an app is running. However, you should be aware that iTunes restore is not necessarily the only condition under which the Caches directory can be erased.
To be specific Your app is generally responsible ... for adding and deleting files as needed., You should always clean up after yourself. If you know you are done with the files, keeping them on disk and waiting for the device to run on low disk space so that the OS deletes them is a bad idea.
btw, if you are downloading files from the internet, why don't you use an already build library (so that you don't have to worry about these things).
If you are developing for iOS 8.0+ and using Swift, you could use AlamofireImage as an embedded framework. It comes with a very good caching system. I think you can use it on iOS 7 as well by copying the Swift files.
If you are using Objective C, you could use SDWebImage which comes with its own caching system. You could also use AFNetworking and enable basic caching, this blog post should get you started.
I created magazine reader app that uses png images as pages. When user downloads magazine, all png images are downloaded and stored in Caches folder.
Problem with Caches is that files in there can be apparently deleted anytime. Since app is designed to be used in offline mode as well, re-downloading of missing pages is impossible.
I tried to save it into Documents folder but my app got rejected, this apparently is not proper place for them.
So my question is, where can I put them to make that iOS won't delete them? I don't need them to be backed up to itunes or synced or anything like that, I just need them to stay there until I remove them.
I tried looking into the documentation but I could not find a category that would fit my needs, am I missing something trivial?
EDIT: I need to support iOS 4 as well
http://developer.apple.com/library/mac/#documentation/FileManagement/Conceptual/FileSystemProgrammingGUide/FileSystemOverview/FileSystemOverview.html
Put it in the Libary Folder
Handle support files
—files your application downloads or generates and can recreate as needed—in one of two ways:
In iOS 5.0 and earlier, put support files in the /Library/Caches directory to prevent them from being backed up
In iOS 5.0.1 and later, put support files in the /Library/Application Support directory and apply the com.apple.MobileBackup extended attribute to them. This attribute prevents the files from being backed up to iTunes or iCloud. If you have a large number of support files, you may store them in a custom subdirectory and apply the extended attribute to just the directory.
Apple has a tech note that addresses this at http://developer.apple.com/library/ios/#qa/qa1719/_index.html
It shows sample code for setting a no-backup attribute on files.
I have a general question regarding bundles, libraries and custom frameworks on the iOS. I've seen many topics about this on SO and searched far and wide on the net, but I still can't come to an answer without finding another site or post contradicting or confusing me some more. If someone could give me a solid answer to the below questions regarding what is allowed on the iOS or what would get rejected I would be really grateful.
I've seen posts and sites say that you cannot create bundles on the iOS. Does this also apply to bundles with only images in them?
Is it possible to create a library with .xib files in them? If not then how would one go about including one if custom frameworks are not allowed?
Does using a xCode dynamic library put my application for grounds of rejection (ex. libxml2.dylib)?
Apologies if this is too general or mentioned multiple times, but this whole library and what is allowed and what isn't allowed just doesn't seem to be very clear for me. What I am trying to do is to create some apps and perhaps include some controls that I frequently use in some sort of library or bundle, but I would like to know my limitations before moving further.
1.: No, you cannot create any framework even if it contains images only, as you can't write to the root partition of the iOS filesystem (the part where /System/Library/Frameworks resides).
Of course, if jailbreaking is an option, then all this stuff becomes invalid. You do what you want with a jailbroken phone, so you can create frameworks, add libraries to the filesystem etc.
2.: Yes, it is possible to create a library with XIB/NIB files with it, but then you'll need to share both the source or a static library built from the sources AND the XIB files and guide the other developers to do so in order iOS to correctly handle your library and be able to build the UI from the InterfaceBuilder files.
3.: No, because those libraries are already on the iPhone, you don't have to hack it to get them on the filesystem. libxml2, libsqlite3, etc. are allowed and can be used in any AppStore app.
I have an nascent iPad application, which stores "documents" internally on the device in the file system as a series of distinct files in a folder.
I'd like to try incorporating an import/export function through iTunes, using the features for OS 3.2 for this. I want to put all the document pieces that I keep internally into one container file for export.
So, smart folks of Stack Overflow: What's the simplest solution that will put a file hierarchy (or could be flat list in a pinch) into one file? There will not in theory need to be manipulation of the "archive"/container outside the app-- so random access isn't super important here, although it would be a bonus of course.
A tar file type thing springs to mind immediately. Roll my own? Any other thoughts or gotchas? (And if anyone can point me to code that reads/writes from a tar file, I'm all ears.)
Thanks!
Update: Made community wiki, since there's no single right answer here.
Try libarchive which is a friendly licensed, BSD derived (easier for iPhone OS) library for handling archive files.