Hi Pitt! Thank you for this elegant and simple solution 👏🏻However, sometimes images are now only partially displayed (the rest is gray). AsyncImage might call its content closure with AsyncImagePhase == success with the image only partially loaded when the view disappears and the download task is canceled (mostly happens in a list when scrolling).
Great Video, but 2 things bug my mind. 1-) why the app is taking so much memory? 2-) If we are going to use a search function in the list scroll paging method is not suitable. why not use a for loop? for i in 1...page{ let characters = try await service.fetchCharacters(page: i) self.characters.append(contentsOf: characters } so that we can search all characters.
Hi @erdem, for 1) we need to implement a LRU cache to optimize the memory. Check out my newsletter: www.getrevue.co/profile/swiftandtips/issues/swift-tips-issue-1-september-2021-733761 Not sure about 2), yeah, would be cool for searching in that screen, good update 👍. Thanks for sharing 😀
Hi Pitt! Thank you for the video, it worked great for me! The only thing I changed was the type of URL - I made it optional. I did not want to use Kingfisher for my small pet-project, and your solution is perfect. You could even make a Swift Package with your CacheAsyncImage, or I can do that if you don't mind.
@@swiftandtips Hello again. Guess what? I found a bug :) When I use your CacheAsyncImage and attach a .task modifier to the view with this image I get error: Error Domain=NSURLErrorDomain Code=-999. It happened because CacheAsyncImage leads to extra requests to the server and the first one is trying to get cancelled. I spent 3 hours trying to fix that until I just replaced CacheAsyncImage with AsyncImage. Now I do not have cache, but do not send extra requests to the server
My apologies for the inconvenience 😅. I will take a look to find the issue. Could you share a piece of code calling CacheAsyncImage? I would like to get the right idea on why this is happening. Thank you 😄
Do you think you could show us/me how to additionally add the other initializer of AsyncImage for this? (The one with the placeholder). I tried to add it to the existing code, but I'm running into several issues. Would really love to see it!
Hi @tehLilaQ, I would take back the work of that later adding more initializers and improving the cache system. What is your problem right now? Any compile issue?
@@swiftandtips Yea, it's telling me `cannot convert value of type 'some View' to closure result type 'Text'`, when I have e.g. the Image in the content closure, and a Text in the placeholder closure. Not sure where I'm going wrong :(
Hey there! I just saw your video on the base model Macbook Air M1 for coding and I wanted to ask you how it is holding up? I too, thought about getting a Pro with all the upgrades, but wanted to see how you are doing with your Air. Thank you!
Hi @Steven, answering your question, Macbook Air M1 still awesome! I work with this machine daily to code and generate my videos and I don't have any problem in terms of performance. Although, 256gb are not enough for content creation to be honest, if you can spend more on capacity is better than ram. However, Apple events are really close, I will suggest to wait until see the announcements before buying the right mac for you :)
@@swiftandtips First of all, nice video and explanation. Keep on that way! I have the same question. Should I store it with CoreData or there's a more elegant way? I'm new at SwiftUI
Hi @Halal, thank you for your comment. If you are talking about CacheAsyncImage, everything is in-memory. We will have to support persistency later. For AsyncImage the same, it doesn’t save anything at all. Is that answering your questions?
Hi just make an UIApplicationDelegateAdaptor and put the swift equivalent of this in your didFinishLaunching: NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity: * * diskCapacity: * * diskPath:nil]; [NSURLCache setSharedURLCache:URLCache];
@@indiekiduk Hi I've changed both URLCache.shared.memoryCapacity = 1024 * 1024 * 512 URLCache.shared.diskCapacity = 1024 * 1024 * 512 anyway still images are not caching so it's not due to memory capacity that is changed (I can see it with breakpoints)
You already caught me with the thumbnail haha. Great video!
Thank you Flo 🙌🏻
thank you very much im using your cachedSyncImage into my project effectively
Hi Pitt! Thank you for this elegant and simple solution 👏🏻However, sometimes images are now only partially displayed (the rest is gray).
AsyncImage might call its content closure with AsyncImagePhase == success with the image only partially loaded when the view disappears and the download task is canceled (mostly happens in a list when scrolling).
Amazing video! I really like the way you explained this! Would like to see more on persistent Image cache, but I guess that'll be for another video
Thanks for your comment! I would like to bring that topic later on! 😁
@@swiftandtips Awesome!!!
So elegant! Loved the video, learned a lot. Thanks a ton and keep it up :)
Great Video, but 2 things bug my mind. 1-) why the app is taking so much memory? 2-) If we are going to use a search function in the list scroll paging method is not suitable. why not use a for loop?
for i in 1...page{
let characters = try await service.fetchCharacters(page: i)
self.characters.append(contentsOf: characters
}
so that we can search all characters.
Hi @erdem, for 1) we need to implement a LRU cache to optimize the memory. Check out my newsletter: www.getrevue.co/profile/swiftandtips/issues/swift-tips-issue-1-september-2021-733761
Not sure about 2), yeah, would be cool for searching in that screen, good update 👍.
Thanks for sharing 😀
You just got a new subscriber, thanx😉
good good
Thank you it worked perfect for me
Hi Pitt! Thank you for the video, it worked great for me! The only thing I changed was the type of URL - I made it optional. I did not want to use Kingfisher for my small pet-project, and your solution is perfect. You could even make a Swift Package with your CacheAsyncImage, or I can do that if you don't mind.
Hi Oleg, thank you for your idea! Actually I wanted to make a video about Swift Packages. 👌😀
I’m glad you found this code useful ☺️
@@swiftandtips Hello again. Guess what? I found a bug :) When I use your CacheAsyncImage and attach a .task modifier to the view with this image I get error: Error Domain=NSURLErrorDomain Code=-999. It happened because CacheAsyncImage leads to extra requests to the server and the first one is trying to get cancelled.
I spent 3 hours trying to fix that until I just replaced CacheAsyncImage with AsyncImage.
Now I do not have cache, but do not send extra requests to the server
My apologies for the inconvenience 😅. I will take a look to find the issue. Could you share a piece of code calling CacheAsyncImage? I would like to get the right idea on why this is happening. Thank you 😄
Do you think you could show us/me how to additionally add the other initializer of AsyncImage for this? (The one with the placeholder).
I tried to add it to the existing code, but I'm running into several issues. Would really love to see it!
Hi @tehLilaQ, I would take back the work of that later adding more initializers and improving the cache system.
What is your problem right now? Any compile issue?
@@swiftandtips Yea, it's telling me `cannot convert value of type 'some View' to closure result type 'Text'`, when I have e.g. the Image in the content closure, and a Text in the placeholder closure. Not sure where I'm going wrong :(
@@LQ_LQ_LQ I could help you if you share a gist link with your code and see the actual problem.
Hey there! I just saw your video on the base model Macbook Air M1 for coding and I wanted to ask you how it is holding up? I too, thought about getting a Pro with all the upgrades, but wanted to see how you are doing with your Air.
Thank you!
Hi @Steven, answering your question, Macbook Air M1 still awesome! I work with this machine daily to code and generate my videos and I don't have any problem in terms of performance. Although, 256gb are not enough for content creation to be honest, if you can spend more on capacity is better than ram.
However, Apple events are really close, I will suggest to wait until see the announcements before buying the right mac for you :)
@@swiftandtips Thank you so much for taking the time to respond! Take care, sir! 💪🏻
Thanks for this great video! May I know how long does these images kept in cache for?
Hi Ryan, the cache has room for improvements. Right now is pretty basic and images will stay in memory the whole execution.
Thanks for the support!
@@swiftandtips wondering how can I remove it say after one week?
@@ryanchannel_HK Do you mean persisting the data for 1 week?
@@swiftandtips First of all, nice video and explanation. Keep on that way! I have the same question. Should I store it with CoreData or there's a more elegant way? I'm new at SwiftUI
really helpful tips!!
Thank you Jorge! 😃
Awesome tutorial!
Thank you Gelfer 😃!
Great video... can you please make a video on making request from user input with Combine
Thank you Jeff! 😃
I have a video about the basics of Combine: ruclips.net/video/IJinuMLaERE/видео.html
Let me know if it helps you.
How often does it get emptied out? If you force close the app, do you still have the images?
Hi @Halal, thank you for your comment. If you are talking about CacheAsyncImage, everything is in-memory. We will have to support persistency later. For AsyncImage the same, it doesn’t save anything at all. Is that answering your questions?
@@swiftandtips Thank you Mr. Tips, that answers my question! Great app by the way.
Is there a reason you didn't simply use the built-in URLCache with the shared URLSession that AsyncImage uses?
Hi indiekiduk, that’s the point of the video, it doesn’t work for AsyncImage yet 😅
Hi just make an UIApplicationDelegateAdaptor and put the swift equivalent of this in your didFinishLaunching: NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity: * * diskCapacity: * * diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
Interesting, I will try that. Thank you!!
@@indiekiduk Hi I've changed both URLCache.shared.memoryCapacity = 1024 * 1024 * 512
URLCache.shared.diskCapacity = 1024 * 1024 * 512
anyway still images are not caching so it's not due to memory capacity that is changed (I can see it with breakpoints)
Is there a way to cache my AsyncImage before it appears on screen?
Maybe using a regular Image.