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
Related
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
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.
As Apple introduced the PDF support for the Xcode Image Asset Catalog I was wondering if it's also possible to add PDFs at runtime?
What I want is to download my PDF-Assets and use them similar to JPGs or PNGs in my App with the difference that I only need one instead of 3 resolutions.
use this link it will help you
http://alldonegoodbye.tumblr.com/post/97647217699/xcode-6-vector-image-support-pdf
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'm in the process of making my iPhone application compatible with the iPad. I want to include larger image files for higher resolution artwork for the iPad version that I don't want included in the iPhone version (don't want the binary to become huge). Is there a way to accomplish this, or am I pretty much stuck with having to include the iPad art work with the iPhone version and vice versa?
You have to include both for a universal app, but as of iOS7 and when you use an Asset Catalog, the user won't have to download any unnecessary images. Apple takes care of this for you.
Asset Catalog Help
Quote:
For projects with a deployment target of iOS 7, Xcode compiles your asset catalogs into a runtime binary file format that reduces the download time for your app.
If you want to have one version in the store, it must include both. But if you want to have separate iPad and iPhone versions, then they each only need the images for that version. Just have two separate targets in the Xcode project for each, and make sure that you only have the assets included for the versions that need them.