The iOS app I'm working on handles very large files (largest being 2.7 gig in size), and some sqlite tables, after downloading the large I'm getting console messages like this one :
Aug 24 14:50:28 unknown TheAppName[1407] <Warning>: Error opening database: 14 unable to open database file
Also other issues that happen, loading a view (which has already been loaded and presented) will cause a crash saying "nib cannot be located".
The app can run without the large file just fine, but it is very useful to have. The question I have is this : Is the large file causing some sort of memory issue, or is there some sort of limit that iOS places on files? I've looked around at other places and I've been unable to find anything specific to this.
Does it work in the Simulator or do you also have the same issue there?
I suggest you run your app using Instruments with the ObjectAlloc tool. Its likely you have some leaks in the way you are managing the download. Or, is there free space on the device for this file?
Others have had success with downloading huge files as long as sufficient space exists on the flash. You can test for this - there are a few functions floating around that tell you how to determine free disk space.
Another idea: write your file to the disk with the "F_NOCACHE" (fcntl) flag set on the file descriptor. This will cause the writes to bypass the "uniform buffer queue", which is used to cache disk blocks and for other memory uses, and will greatly reduce stress on the system itself.
An iOS app's max size limit is 2GB, this is limit is causing all the errors and is why your app is crashing. I would recommend you upload your large size files to a file hosting site and stream them into the app when you need them.
Related
From current list of "Realm Limitations":
Any single Realm file cannot be larger than the amount of memory your
application would be allowed to map in iOS
Does this mean that if I check ProcessInfo.processInfo.physicalMemory and it is smaller than FileManager.default.attributesOfItem(atPath:realmPath)[FileAttributeKey.size] (plus a variable amount to account for fragmentation etc), I should not try to open the Realm?
If the Realm file is too big for mmap to map the file, you should get a Swift error. So all you really need to do is to try opening the Realm and catch any Realm.Error.addressSpaceExhausted errors.
The bigger problem is what to do once you know the file is too big. Our compaction on launch feature requires that the file be openable first, which rules it out (and is why we recommend that compact on launch be used to pre-empt this issue). We're working on ways to mitigate this problem.
mmap shouldn't depend upon the amount of free physical RAM you have (although some amount of RAM is required to map the file), nor is the limit that iOS imposes anywhere near the theoretical maximum. Finally, virtual memory limits operate on a per-process basis, meaning that the size of a Realm file you can open depends both on what other files have been mapped by that process and by how much memory that process is using for other things.
My app has to make sure that there is always a minimum amount (maybe 5-10 MB) of free disk space available, for it to operate correctly. I have to save important data to file, otherwise everything is going to be corrupted.
The main problem is: What if the user downloads my app and he had EXACTLY that amount of disk space free that he needed for the app (without my on first startup created data)
When he's now starting the app I try to do some initial setup stuff - here I have to write around 2-3 MB to file and this space must be free.
What can I do to achieve this?
You can do two things:
First, when your application starts, you can find out the available space using NSFileManager.attributesForFilesystemofPath:. If the amount of space is low (and 5 MB free is really low, you can warn the user and maybe even refuse to start actions in your app that require this available space.
Second, you could create a scratch file. If you know you need 5MB storage, then maybe you can allocate a 5MB file and use that file for your storage.
You don't specify what you need to store on disk but if it were for example one file then you could write this data over your 5MB scratch file instead of opening a new file.
This requires some extra bookkeeping, but you do get guaranteed space for your data.
In short, you can't. You will need to write your code to have an initial startup that checks to see if there is enough disk space to do your initial setup, and display an error if not. I haven't tried to do this on iOS before so I'm not sure what the sandbox allows you to do off the top of my head. I'd have to go read up in the iOS file system docs. That's what I suggest you do.
I have got an iPhone application where I archive permanent data in the documents folder of the application (arrays, dictionaries). I read/write from and to the documents folder quite frequently and I would like to know whether this is considered a bad habit. Wouldn't it be better if I had a singleton class, read and write to arrays there and then, only when the application quits, write this data to the documents folder ? I do not see/feel any performance issues right now on my iPhone 5, but I wanted to know whether this is a bad practise.
FLASH memory has limited write capability - a long time ago it was rated in some increment of thousands. Not sure where it is today.
That said, if your app is using the standard file system APIs, then the system is using the file cache, and you might open a file, read it then change it many times without the file system ever writing to flash. The system may sync to flash occasionally, but that process is opaque - no way to really know when or why iOS does it.
The UNIX APIs allow for syncing the file system cache to the storage system (iOS this is FLASH), but if you are not using that then you are probably not doing much I/O at all given what you say above.
Given the lack of Apple discouraging developers from writing to the file system, I for sure would not worry about this.
But, if you said you were writing gigabytes of image data every few minutes - well - that might be a problem.
I am working on an iOS app in Xcode. Earlier I got it to start and run, up to a limited level of functionality. Then there were compilation failures claiming untouched boilerplate generated code had syntax errors. Copying the source code into a new project gets a different problem.
Right now, I can compile and start running, but it states before even the launch image shows up that the application was closed due to memory pressure. The total visual assets is around 272M, which could be optimized some without hurting graphical richness, and is so far the only area of the program expected to be large. (The assets may or may not be kept in memory; for instance every current loading image is populated and my code never accesses any loading image programmatically.) And it crashes before the loading image has itself loaded.
How can I address this memory issue? I may be able to slim down the way images are handled, but I suspect there is another root cause. Or is this excessive memory consumption?
Thanks,
Review the Performance Tuning section of Apple's iOS Programming documentation. Use Apple's Instruments application to determine how, when, and how much memory your app is using.
One approach you should consider is to disconnect the graphics resources from your application, and add them back one-by-one once you feel they meet the requirements and limitations of iOS.
Now, this part of my answer is opinion: it sounds like your app is a high risk for being rejected from the App Store, in case that is your intended destination for this app.
I am making a some complex app, in which every detail is imp. i have some questions
1. how much storage limit we have, if we plan to save big files on core data/cache.
2. Whats the RAM limit on iphone? Actually searching for some table that can give detailed info about IOS devices on this. Because i need to handle memory warnings and defend App crashes.
3. Its better to save images in cache or core data, assume you have a lot of images approx. 200-250.
Thanks
1) I am not aware of any storage limit. Obviously, you will never get 64GB or more - since no device is larger ;-). My wife's facebook app consumes >5GB at the moment... I suppose they did something wrong. The only important point is to fail gracefully (show a dialog, clean some space, ...) if the storage is full.
2) The RAM limit varies depending on the iPhone model and the currently running applications. Also there are some iPods with less memory in market. 30MB should be pretty safe. Total physical memory of the device can be retrieved as described here while retrival of the available RAM can be derived from that question.
3) Maybe this is a good starting point. I would always write image data to the file system and just store the file name inside the database, as suggested here.