What would be the best way to include a lot of images in the bundle? I have an index of (game) items thus about 4000-5000 image files (total 27mb so not that big). Just include the whole map in the bundle or maybe first write a script that converts them to NSData? I could imagine there would be a smart way to do this so the app wouldn't have to look through all images individually to find a single one. Would love to hear your thoughts.
27mb isn't a huge amount to download so the easiest option would be to put them in an asset catalog, as Ryan Heitner mentioned in his comment this will allow App Thinning to take place in iOS 9.
I'm not sure what you mean by this:
I could imagine there would be a smart way to do this so the app wouldn't have to look through all images individually to find a single one
Each image will need to have a unique name (this is true regardless of the number of assets you have) and your code references the images by that name so it won't have to "look through all images individually to find a single one".
Alternatively if you really want to reduce the initial download size you could use On Demand Resources (another upcoming iOS 9 feature) to store them on Apple servers and loaded on demand in your code. Presumably you won't be targeting only iOS 9 though so in this case you would need to host the resources yourself and load them using standard techniques (see here, here, here, or use a library.
You should pack them in a texture atlas.
Then, the texture atlas files should be imported in your bundled via a folder reference (blue folder icon) and not a group (yellow folder icon).
Images imported in bundle in folder reference won't be optimized be Xcode on packaging. So you can make your own file optimization using imageOptim. It can compress a lot more than what Xcode can do on JPEG and PNG images.
Related
I'm working on a watchOS app with a modular large face complication. The Assets.xcassets file in the WatchKit Extension includes a Complication folder with one image set each for Circular, Extra Large, Modular and Utilitarian, but in my case I have multiple possible assets for the Modular type, which I will choose from programmatically (called Bottlefed, Breastfed and Pump). I was able to rename the Modular image set to Bottlefed, and then added the other two image sets to the Complication folder and populated them with images:
But doing this ends up showing the following warning in Xcode:
I can't find any documentation or examples of people using multiple images for assets to show me if I'm doing this the intended way or not.
Note that my approach does actually work, as far as adding multiple assets to the asset catalog and selecting from them programmatically. But the warning in Xcode is irritating, and makes me think I'm not doing this the correct way. Any thoughts?
In the end, turns out the easiest thing to do is to simply not use the Complication folder in the WatchKit Extension's asset catalog. Just putting the assets in the top level of the asset catalog and ignoring the Complication folder still loads the images into the complication, and avoids the Xcode warnings. (Shoutout to the maker of CARROT weather for helping me out with this one!)
I can put files into Assets.xcassets or I can put files into folder references (the blue folders). When would I choose one over the other?
You should probably use asset catalogs as that's what Apple wants you to use going forward (the tools will reflect that) and they bring many advantages:
App thinning
Setting asset properties without code, e.g., rendering mode or slicing
You don't have to remember naming conventions like #2x, ~ipad, -568 etc to get device-specific assets automatically
Asset catalogs will point out missing assets if you tick the right boxes for the versions and devices you support, and they provide a nice overview
You should get used to them as some platforms (e.g., watchOS) require you to use asset catalogs
There are a few caveats:
If you deploy back to iOS 6, some features don't work as expected – asset catalogs still help to organize your assets, but the runtime features won't work as Xcode will just dump plain image files into your bundle.
If you deploy to iOS 7 or later, Xcode will compile all assets into one .car file (that's the whole idea). However, this can be harder to debug because you cannot look into the compiled file, and it also means you cannot simply get a file URL from a single asset. To create a file URL, you always have to load the asset (by its name) and write it to disk first. *
The last point also implies that you cannot use the NSBundle (in Swift 3.0: Bundle) APIs to retrieve URLs or paths to image files. In order to load assets from a bundle other than the main bundle, you rely on Apple to provide an API, which they do since iOS 8.0. If you organize shared code in resource bundles and deploy to iOS 7 or earlier, you shouldn't use asset catalogs. This is probably mostly relevant if you intend to develop a framework.
* E.g., the CoreSpotlight API allows you to set a thumbnailURL, but if your image is within an asset catalog, you must either write it to disk separately yourself, or use the thumbnailData property. If you had a file URL to begin with, you'd never have to load the asset into memory. I'm not sure if Spotlight could access file URLs from within your app bundle. It's just an example.
You should use Assets. Many benefits the folder references can't do
1) Change color of image without any code
2) Support vector, pdf better.
3) Support Slicing image.
4) Manage resource easier for autolayout. If your resources has 1x, 2x, 3x and ipad image size != iphone image size, you can add 6 files into 1 asset item.
You can read more here
http://krakendev.io/blog/4-xcode-asset-catalog-secrets-you-need-to-know
I am a newbie on iOS development and am developing my first serious app (Objective C).
I am using an external API and have gotten to a point where I need to download an image from said API to keep offline as cache.
Now, if I understood correctly I can add images to my app on XCode using the asset catalog. For example, if I add an image with image#1X.png, image#2X.png and image#3X.png versions, in order to use them later I only need to provide the "image" part to iOS and it will automatically return the version appropriate for the currently used device.
I cannot however add images to the asset catalog on runtime - I must create an NSData from the image URL and save it to the Documents folder.
The thing is, this API gives me a bunch of URL's for different versions of the image I need to download and among them are the #2X, #3X etc versions of the image, so I need to download all versions and use the asset catalog feature of retrieving the appropriate one for the device.
How can I achieve this?
Thank you very much in advance for your help and please correct me if I got something wrong.
so I need to download all versions and use the asset catalog feature of retrieving the appropriate one for the device.
You don't need to. We add 2x and 3x images to our asset catalog because we don't know on what device our app is running. But in your case, you need to know this at runtime, so you already know what's the device.
To get the scale factor for your device you can do:
UIScreen.mainScreen().scale
So, for 2x this will return 2 and for 3x it will return 3.
From this, you can know what's the proper image you need to download from your API instead of downloading them all which would add unneeded overhead.
You can check the document on the UIImageAsset if it helps in your requirement
Also as you say you are newer to iOS development you can check file system document also which helps you in understanding and managing file in better way
File System basics
Edit: as mentioned by sateesh and patchdiaz, it will be better solution to download only single resolution images for the particular device instead of downloading all resolution images for a device
I have really large number of images just in Images folder of my project (just #1x and #2x.png files). It's time to support #3x displays and I've decided to move to assets catalog. Are there any tools/scripts to automate this?
Normally you already have an Asset Catalog because of your AppIcon. If not, choose File:New:File ... and then select iOS Resource:Asset Catalog.
The images you want to import should be named properly: image.png, image#2x.png. If you target both devices: image~iphone.png, image#2x~iphone.png, image~ipad.png, image#2x~ipad.png.
Then select Asset Catalog and press +. Choose the folder with the images you want to import.
Like that it´s very simple to import large numbers of pictures and you can have the same folder structure in your Asset Catalog, as you had before.
You can try iMigrate, that I created recently. So it wasn't properly tested and you can use it own risk.
You can make one of your own using Apple Automator. It is an automating script maker tool provided by Apple with the Mac OS. You can find plenty of online tutorials for it if you Google it up. Here's an example. Click here
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.