Its is well documented that UIImage imageNamed caches the images. And the trend with the newer version of iOS is to use Asset Files to simplify all the #2x and #3x images for all devices.
But to avoid caching the images and to make best use of memory with images, so far I would use methods like imageWithData. But these methods don't work with Asset files that has been my understanding so far. Cause I could not find methods like pathForResource on the bundle working properly for Asset images. Is this a drawback on iOS or is there a nice workaround or is it just plain n00b ness on my behalf?
On one of my projects I have noticed a large memory consumption only because some image used on some startup screen or so still being cached courtesy imageNamed:
How can one work around this i.e continue using the simplicity and ease of Asset set Images and yet avoid caching using imageNamed:
Thanks
Although UIImage's imageNamed caches the images, and some of the old forums continue to dole out that information. In earlier OS version, imageNamed had a memoryLeak, which has long been fixed.
When app receives memory warning, cache is cleared. So you can continue to use it.
Related
I am loading a remote PDF file and trying to turn it into an UIImage (for showing in an UIImageView), and am surprised that it doesn't seem to work. Even though local PDF files in the Asset Catalog work just fine, is PDF not supported outside of that?
Edit: I found https://developer.apple.com/library/archive/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/LoadingImages/LoadingImages.html which suggests that nope, PDF doesn't work. So that leaves me with the question: why/how does it work for local files in the Asset Catalog? Why or how is that different?
To answer your "Why or how is that different?" question...
When you add a PDF file to asset catalog, Xcode renders #1x, #2x and #3x versions at build-time.
You can select Preserve Vector Data to have the pdf "rendered on-the-fly." This generally works well, although if you have a lot of pdfs and you're doing a lot of manipulation with them, it may reduce performance.
I would like to know if we were to put our images in the xcode Assets.xcasset or an image file could be enough?
Thank you
https://developer.apple.com/videos/play/wwdc2018/219/
From WWDC 2018:
"...for artwork that comes with your application, we strongly encourage you to use image assets. And there are a number of reasons why."
Some of those reasons:
"Image assets are optimized for name based and trait-based lookup. It's faster to look up an image asset in the asset catalog, than it is to search for files on disk that have a certain naming scheme."
"managing buffer sizes"
"...per device thinning, which mean that your application only downloads image resources that are relevant to the device that it's going to run on and vector artwork."
Vector artwork optimization: "...if your image gets rendered in an image view that is larger or smaller than the native size of the image it doesn't get blurry. The image is, actually, re-rasterized from the vector artwork... The asset catalog compiler has, actually, already produced a pre-rasterized version of that image and stored it in the asset catalog. So, rather than doing the complicated math of rasterizing your vector artwork into a bitmap, we can just decode that image that's stored in the asset catalog and render it directly into the frame buffer."
This is not an exhaustive list, click the link for more. So to answer the question, using the asset catalog is certainly not required, but it would be foolish not to use it for artwork that is delivered with the application for the reasons mentioned.
No. It is not required to use .xcassets files. You can also just add images and other resources to your Xcode project.
However I would always use Asset Catalogs if possible, because it gives you powerful features, such as using different images for different devices/gamuts/etc.
When creating a NSAttributedString from an HTML string which contains an image link (https), somehow the downloaded image is cached. How did I came up with this fact?
Install app.
Open the app. Image is there.
Close the app (terminate). Go for Airplane mode.
Open the app. Image is still there.
Delete the app completely, and reinstall.
Open app while still in airplane mode. No image.
Caching the image is actually what I want. But I want to know deeper, how and where the image is cached. Since my app should work offline, I have to be sure that the image is cached or not. I dig into the docs and couldn't find anything. Can someone enlighten me? Thank you.
EDIT to clarify:
I am not using NSTextAttachment directly. I'm initializing NSAttributedString from a String, using UTF8 encoded data. Why I am talking about NSTextAttachment is I guess its automatically creating an NSTextAttachment for "img" tags in the HTML String.
As the docs don't state that the images will be cached, it's best to assume that there is no caching. Therefore, the best solution to your situation is to download the file with URLSession and store the file on disk, so when the device is offline, the image can be displayed.
Some digging into the simulator data proved that my image is really cached.
/Users/<username>/Library/Developer/CoreSimulator/Devices/<simulator-id>/data/Containers/Data/Application/<app-id>/Library/Caches/<app-bunle-identifier>/Cache.db file is a SQLite file holding the cache info. And there is my image, with its link and its data.
Its odd that Apple didn't documented this, and I still don't know how / when it caches.
So according to this, you have to use imageNamed for loading images now in iOS.
Unfortunately, CPTImage's constructors requires paths for loading images
So something like this:
[CPTImage imageForPNGFile:[[NSBundle mainBundle] pathForResource:#"plotsymbol" ofType:#"png"]]
These -pathForResource calls now fail because of asset catalogs.
So.. has anyone been able to do this? Did I miss something?
The CPTImage class will include an imageNamed method in a future release. It is available now on the release 2.0 branch. People are using the 2.0 code now but it is unfinished and subject to change in many areas before the final release.
To make a long story short, we have released an app that has hundreds of images stored in the application bundle. The file structure for the images is something like:
/var/mobile/Applications/.../ApplicationName.app/Images 1.0/0001.png
/var/mobile/Applications/.../ApplicationName.app/Images 1.0/0002.png
We want to release an update to the app that replaces all of these images with our 2.0 assets:
/var/mobile/Applications/.../ApplicationName.app/Images 2.0/0001.png
/var/mobile/Applications/.../ApplicationName.app/Images 2.0/0002.png
The tricky part is that the new images are not a strict one-to-one replacement of the old images — we have added a few and removed a few. Unfortunately, it appears that you are unable to remove file from the app bundle and the update itself does nothing to change them either.
The primary reason we want to remove the old resources is that they take up quite a bit of space on disk. It doesn't seem good to have these old, unused files hanging around.