What do ios apps do when they 'load?' - ios

Most apps I see have loading screens, presumably to prevent hiccups in the game and to pre-load all of the data needed later in the game. I am currently working on a game that skips every few frames, presumably because the image data for the objects being rendered to the screen are not being held in memory. What do programmers actually do to hold this data in memory throughout the time the app is running? I can think of using arrays, such as NSArray or NSMutableArray to hold the images, however I still struggle to see how that would improve the performance of the app. Perhaps I am totally going off on a tangent here. A word of advice from someone with experience in the area would be greatly appreciated.
EDIT:
For the person who voted to close the question, my question, more specifically, is this: What is a typical method in which an ios game loads its data into active memory to enable easy and low-overhead access during run time?

I have seen several application that downloads configuration and metadata on application load, some also download images and audio files.
Usually they store the data in the documents or cache folder, so the they will not have to wait for download during the game.
Another technique I encountered is downloading a zip file and expanding it in the cache directory. Most of these apps do not load the files the next time unless something new is needed.
Do not load the images to the memory, not inside an nsarray nor nsmutabearray. You do not have enough memory to cache images like this. You should just predownload them
Edit:
You can use the application loading stage to download more resources from your servers (images, audio, plist files) but after they are download and stored in the file system they should be treated like resources that exists in your IPA. They should be loaded into memory only when they are needed

Related

How to best move a huge .sqlite database to a new directory on an old, low memory iOS device?

For my latest app update, I have to move the user's Core Data .sqlite database from the Documents directory to the Application Support directory. I use the migratePersistentStore:toURL:options:withType:error: method. I am dealing with one user who somehow managed to save enough data in her database so that it is now a whopping 9G. On top of that, her device is an iPad Air 1 - which had memory issues around the time it came out five or six years ago, and now it is 2018 and she is running the latest iOS. The migratePersistentStore:toURL:options:withType:error: method keeps crashing the app with low memory. But I have no other way to get the .sqlite to the necessary location. Can anyone advise me on how to best approach this situation? Ideally, something I could do in my code - but I would even appreciate suggestions on other ways I could just help the user to manually move that massive database at this point!
I guess you use migratePersistentStore because its the official way to do it. Its a good way, but sometimes you have to make your hands dirty:
Manually-moving database at app-start before you load it
This post shows that CoreData may use more than one file which you have to move. You can list the files in the directory, use a regex find all the files which have to be moved, move them to the new location and then load CoreData as usual from the new location.
This however requires there to be the necessary infrastructure in place to do this. You‘ll figure it out if you want to go this path.
You can hide this behind a feature-flag, only with a code, only for a certain user or after crashing with low memory so it doesn‘t impact users who don‘t need it.

Upload photos with NSURLSession in background

I want to use NSURLSession to upload photos to cloud server(like OneDrive) and I hope the app can do works in background.
But NSURLSession just support "fromFile" not "fromData" in background mode, and I don't know how to get the NSURL of photos, so I write the photo's data into a file...
I think this is not a good way.
From the comments above, it seems like you'll be uploading several photos at a time and for that a "fromData" approach does not seem like a good idea.
Firstly, high resolution photos have several megabytes in size. If your loading a 5mb photo into memory, using NSData, you're probably fine. But loading 10 photos would then mean you'd need 50mb of memory to hold them all.
Secondly, uploading large chunks of data, such as photos, is also a computationally intensive task. You should most definitely not try to upload them all at the same time. This means you're going to have to build an upload queue that only starts uploading the next photo once the last one has finished. What happens then if internet connectivity is lost midway through the process? And what happens if the user closes the app all of the sudden?
Thus, I'd suggest you grab all the images' data and write them to a temporary folder somewhere. Then you start the upload process, which would find a file on the temporary folder, upload it, delete it once the upload finishes successfully and start over with the next file.
This way you're minimising your app's memory footprint, making it more resilient in the face of the many adversities an app may face (no internet connection, being prematurely closed by the user and so on) and also abiding by the APIs that are provided to you.

iOS - How to avoid memory leak when saving and loading images to display in UITableView?

So this is more of a conceptual architecture question. I'm making a messaging app in iOS. Devices can send image messages. I am saving custom Message objects (which include images) to disk using NSCoder protocol. I want to remove the messages from memory when I don't need them (i.e. when the user logs out and disappears from users list view). I am appropriately encoding that user's messages to disk, and loading them when the user re-appears. However, on the messaging view (a dynamic UITableView where each cell displays the message content), the image content of the messages are cached within the UIImageView subview.
So, I am essentially creating duplicates of the images when I load the messages from disk. Every time a user logs out and then in (i.e. disappearing and then reappearing), the associated messages are saved and then loaded from disk (recreated objects), and my memory usage creeps upward once I go to the private message view and scroll all the way up in order to display all messages.
Ultimately, I want to clean the cache of message images so that I can free up memory when a user is no longer around. I have a good reason for saving messages locally; my question is: what is the best design for saving messages/images to disk, removing them from cache memory, then reloading them when I need to populate a dynamic UITableView?
I'd advice you to use some ready caching library like: SDWebImage, FastImageCache or Haneke. All of them are both using disc and memory cache, what will improve the speed of your tableView and decrease number of download requests.
You can of course make your custom solution, but it won't work as well as something written during months and tested via many developers. However if you want to, I'd suggest to take a look into one of these libraries and start by considering what they've done to make everything 'speedy'.
This way you just save URL in your Message instead of full image. These libraries will check URL, understand that they already have the image in memory cache and load it. You don't have to store it in your array of objects nor download again or save by yourself on disc.
Keeping your message objects on the disc seems weird, as this is slow - better to use database - CoreData/Mantle/FBDB etc, however that's your decision :) Also storing on the disc makes your Messages very easy to reverse engineering attacks and isn't safe.

Best way to save video in iOS Application for offline viewing

I'm in state of confusion that "What would be the best way to store video?" locally downloaded from the server.
I have two versions of same app i.e online and other offline.
For offline mode I want to download all the videos locally for watching them offline in future.
I know that there are two ways of storing videos:
Feasible way would be storing it in document directory of the application and save the corresponding video file name in the sqlite database. But, there are around 200+ videos!
I just fear it might create memory problem, giving my application memory warning and make it to crash.
Storing it in NSData format in sqlite database, but it would make the database huge which I think would not be feasible as sqlite db is meant to be light weight.
Is there some other way that we can accomplish the task. (And as per the requirement videos should not be save in the gallery on the device).
Please help me!
Thanks!
As far as I know, the document directory is your only option. It should not effect the memory, however, please keep in mind that if you app gets deleted, this directory will be as well.
I have recently built an app that relied on saving videos to the Document directory and we ran in to no problems.
I would avoid storing large assets in a Database. You gain no benefit from this and these videos will still be lost if the app is deleted.
You can save any kind of files, anywhere in your application environment directories using...
[[NSFileManager defaultManager] moveItemAtPath:[/*Your current file path*/] toPath:/*Your destination path*/ error:/* &errorObj */];
OR
[[NSFileManager defaultManager] copyItemAtPath:[/*Your current file path*/] toPath:/*Your destination path*/ error:/* &errorObj */];
and for moving 200+ files... you can use a naming convention from which you can handle it using any kind of loops.
Note :
1. For any kind of large in size files, I always use this way, rather than saving in any kind of databases.
2. One should always use "move" operation while downloading the files.

Best way to store and retrieve thousands of places on iOS

My situation:
I have an app that needs to store 10,000 - 30,000 locations in some sort of storage method, which are then displayed on a MKMapView as individual pins. I also have a server that needs to be able to add to the database through pushing out changes.
Through grouping pins I've eliminated all issues with the MKMapView, my biggest focus is now on speed, storage and being able to add and replace the storage contents. What I'm currently doing is I have a text file of currently 1,000 locations as JSON-formatted, then they're just read as an array and sent to my custom map view (no issues there). My only issue is how I could update that text file (rather than downloading massive amounts of data), and store almost 30,000 locations.
Is this even feasible? It seems my current setup could scale pretty much perfectly, it's just this updating system that is causing me a headache.
Your current setup won't scale forever because you have to load the entire file into memory in one chunk. Eventually it will get to large to manage and will eat up to much memory. Unable to purge memory in the event of system low-memory, the system will shut your app down i.e. it won't be able to stay in the background but will have to reboot each time the user switches back to it.
To update, you will have to load in the entire file, parse the JSON, figure out how to update the resulting data structure, then write it all to file. One error anywhere in the process could corrupt the entire file.
You really need to look at using Core Data or even SQL. Core Data has a learning curve but once you master it, it makes implementing designs like your app trivial. You also get automatic scaling and efficient memory management.

Resources