Home Feed Image Caching
Instagram Firebase
We're now ready to start rendering our shared posts inside of our application. In this lesson, let's lay out foundation of the home feed by creating the Post Cell and registering it inside our HomeController. This is a rather easy process given our easy anchoring extension from an earlier lesson. At the end of the video, we will look at the inefficiencies of how we fetch our images by take a look at the Network tab. This reveals that data is being fetched unnecessarily while scrolling the list. I'll go through a very basic Image Caching implementation to make sure this doesn't happen.

Comments (34)
weare99
6 years ago
Hi Brian, when upload you the next videos:)?best regards
Brian Voong
6 years ago
Vartis
6 years ago
Hi Brian, Will you also show how to work with videos ? Thanks.
Brian Voong
6 years ago
Vartis
6 years ago
It would be really great if you can include as many features as possible!
Hen Shabat
6 years ago
We prefer a long course with all the feature you can show us :) Or you can do another advanced course. This is very interesting and also useful to see how you work and implement it.
Fred van Rijswijk
6 years ago
A long course and a lots off detail sounds great, because you can see many detail and problem solving and what it take to make a app really great. I think many courses are not in depth enough to really understand how much is involved to make it work
Brian Voong
6 years ago
Brian Voong
6 years ago
GeminixClown
6 years ago
I really vote for the long courses, many courses teach something like instagram, but no one can give a great feature, or really good implementation like yours, please make this courses more detailed... i wanna learn more and more Brian
dkress
6 years ago
I agree that longer, more in depth, and more advanced courses would be great! I think your channel/website/teaching style is awesome and has drawn in a broad audience. Many of your courses explain in great detail beginner topics (tables, anchors, collections...) and how to start a project but the deeper you dig into the tougher topics the more I would be drawn in and I would be willing to pay for this knowledge as Im sure others would agree.
fahad
6 years ago
Longer always beneficial and informative. Thanks for the great time and effort.
omari
6 years ago
Hey Brian. We would definitely prefer it, because the course is structured very well and easy to follow. I know you can't show us everything in detail but some points are necessary to build a good copy and have a goo UX. I understand that you omit stuff like the chat feature because we saw it in the firebase chat tutorial. But we never talked about some necessary stuff in other tutorials so please as you promised Brian implement following : --> User forgets password (Send email etc.) --> User tries to login or register and has wrong credentials. Notify the user about his mistakes like email is not valid etc (maybe with red color =) --> How can you block a user in our Instagram app and how can you make reports --> If you create the app the home feed is empty. It would be nice to have some suggestion based on the location or etc. who a user could possibly follow --> How can you edit your profile --> iOS notifications if someone liked you post or commented on your post or tries to follow you --> The most important feature for this app is the hashtag feature and searching for hashtags. This is what made Instagram so successful and is also part of other applications. Please as you promised implement these into the Instagram app. This would help us all. Otherwise our apps wouldn't be completely and this would be sad to build such great apps but missing key concepts. Thanks Brian
Brian Voong
6 years ago
Razzor Owa
6 years ago
I'm loving all that :D
Ashim Dahal
5 years ago
Definitely would prefer the course with more episode. As with each episode, there is a ​great thing to learn.
weare99
6 years ago
Hi Brian, Instead of viewDidLoad on the HomeController is it not better to use viewWillAppear? Best regards
weare99
6 years ago
I think there is one other bug. We must also delete the imagecache because if I start the app again the old picture are double or more in the homeController are in the Cache :).
weare99
6 years ago
Sorry I think my simulator was wrong
Brian Voong
6 years ago
johnrm9
6 years ago
I noticed that we need the following to hide the status bar in HomeController like we have done in other controllers override var prefersStatusBarHidden: Bool { return true }
Manuel García Urreta
6 years ago
You are awwesome!
juliolocoh
6 years ago
Brian after instangram can you show us how to build spotify please
Brian Voong
6 years ago
juliolocoh
6 years ago
spotify please
Fred van Rijswijk
6 years ago
Yelp ;-) with maps and geofire (firebase)
Fabrício Beltran
6 years ago
Yelp with maps and geofire! please!
Brandon Jacobi
6 years ago
Yelp would be awesome
josephlausf
6 years ago
i vote yelp
victor
6 years ago
Heja Brian, either of these great examples will be really good, even an Uber app perhaps :) One thing I found challenging working on a Yelp app was the networking part with oAuth2 authentication. Perhaps we could explore Alamofire & SwiftyJSON some time too? Some of my friends working on production-ready apps swear by it... Thanks!!
edward
6 years ago
Spotify would be awesome
Apto Comunicación Digital
6 years ago
spotify :D
Henry Agyei
6 years ago
Hi Brian, Can you show us also how to paginate the Home Feed with Firebase and use pull to refresh at the top of the screen to get the latest posts please
Brian Voong
6 years ago
omari
6 years ago
Hi Brian, Why are you using an UICollectionView instead of an UITableView for the HomeFeed ? The home feed has one column. I thought using a collectionView makes sense when you have more than one column. Could you also use a Uicollectionview inside of a tableview ? Im a little bit confused and would like to know when to use which controller. Thanks
Brian Voong
6 years ago
AlfieLBTA
5 years ago
What about swiping gestures for item deletion?, Can those be implemented on collection views? or then you need to use a table view in order to use those ?
Jesus Adolfo
6 years ago
it is weird you keep saying these properties should be defaulted but you didn't add them to our CustomImageView
Brian Voong
6 years ago
Krubel Habteyes
6 years ago
I keep getting a red screen for HomeController. The yellow colored cells are not showing up I even copied your exact code into X code and it is still not working. Please help.
Brian Voong
6 years ago
rdmension
6 years ago
Hey Brian I am wondering why you don't add the content to the collection view cells inside their contentView property. Is there any particular reason you just add the subviews to the cell view itself?
Brian Voong
6 years ago
Casey West
6 years ago
can't wait for pagination :)
Brian Voong
6 years ago
endodoug
6 years ago
Brian - Why do you set UICollectionViewDelegateFlowLayout as a protocol vs extending HomeController? I've seen it done both ways, but never heard much of an explanation as to why.
Brian Voong
6 years ago
stonypig1
6 years ago
this method is invoked right before the tableview reuseable cell is returned, so can i use it for my table view cell to remove the photo that cell has scrolled away, so the corrected new image can load to renew cell, to prevent that wrong photo load to the text content if user scroll up and down so fast. can anyone tell me if this is ok or redundant to use it? or there is other way to do it ? (i use sd_webimage to load the images for my tableview ) thanks very much. override func prepareForReuse() { super.prepareForreuse() mypostImage.image = nil }
Brian Voong
6 years ago
jalong4
6 years ago
I'm using YapImageManager which does the caching automatically. It uses a SQL lite DB under the covers so the images persist on app startup as long as they haven't expired. They support CocoaPods so it easy to install. Love the course.
Brian Voong
6 years ago
Daalruag
6 years ago
hey Brian, Thanks for the course, I'm developing a similar application, but the fee layout is only as instagram stories present full post may be image or video, I solved with a collectionView and load the images or video with alamofire and works well, however I need start to fill the progress bar when the post already was loaded not before when Cell is visible and waiting for download, each cell take his respective time if is photo 10 seconds, if is video time of the video, I hope same way as instagram, change to next CELL when time is finish (progress bar is full), and begin the same again. I use the notification center to notify that images is download but is async work so not always the notification correspond to the current CELL, hence start to fill the progressbar and the current cell not finished to load, beacuse post the notification that already downloaded one image of other cell (almost the next cell) , this make that the current cell start his progress bar and change to next cell, and dont display the current post or a bit of real time if load when progressbar started. Recently I found IGListKIt, but is not clear to me the implmentation and if could help to me, I hope be clear with the problem, thanks in advance.
Brian Voong
5 years ago
鄭飛
5 years ago
hey. Brian, how can i implement cached image via URLCache, I've tried to do this but here is what I got error code Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSURLCache 0x600000011850> valueForUndefinedKey:]: this class is not key value coding-compliant for the key https://firebasestorage.googleapis.com/v0/b/instragramfirebase-66bba.appspot.com/o/posts%2F13D17DF1-D785-4C99-A577-904A150C933A?alt=media&token=1d21a8db-c76d-415c-bff6-1da79e9802ef.' I follow https://stackoverflow.com/questions/32577207/caching-images-in-collectionviewcell-in-swift/41872124#41872124, and still get confused how to use this class
Brian Voong
5 years ago
鄭飛
5 years ago
hey Brian, I watched your video and in the vary end you put some code like let cache = URLCache( memoryCapacity: 500 * 1024 * 1024, diskCapacity: 500 * 1024 * 1024, diskPath: nil ) URLCache.shared = cache and I put these code inside didFinishLaunchingWithOptions of appDelegate. It turn out that my app didn't crash again, but it still load up within internet. thank you for your helping
Talia
5 years ago
Hi,Brian, 你好! 我在做自己的app准备作为第一个自己的完整项目当作结业项目,因为图片太多,全都存在Xcode中编译速度特别慢,所以我就直接在Firebase的Storage里上传了全部图片,希望在app中获取到并且显示出来,我想通过文件名称获得指定的图片,你在课程里用的是图片的URL获取,不知道用图片文件名应该怎么去封装一个function。你能帮帮我吗?目前封装的代码是这样的,应该怎么改? let imageCache = NSCache<AnyObject, AnyObject>() extension UIImageView { func loadImageUsingCacheWithUrlString(urlString: String) { if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage { self.image = cachedImage return } let url = NSURL(string: urlString) URLSession.shared.dataTask(with: url! as URL, completionHandler: { (data, response, error) in if error != nil { print(error ?? "There is an Error.") return } DispatchQueue.main.async { if let downloadedImage = UIImage(data: data!) { imageCache.setObject(downloadedImage, forKey: urlString as AnyObject) self.image = downloadedImage }
Brian Voong
5 years ago
Talia
5 years ago
非常感谢,你说的对,SDWebImage的确更适合我项目的需要。太谢谢了!
rehan1531
5 years ago
The best way of Image cache :-) :-)
MT
5 years ago
To anyone struggling with proper post order on the home screen, here's a solution: Dictionaries by their nature are unordered, so as soon as the snapshot's value is converted to a dictionary its order is lost. The below creates an array of keys from the snapshot dictionary, sorts them, and then adds the dictionaries to the posts array in the order they appear in the keys array. fileprivate func fetchPosts() { guard let uid = Auth.auth().currentUser?.uid else { return } let userPostsDatabaseReference = Database.database().reference().child("posts").child(uid) userPostsDatabaseReference.observeSingleEvent(of: .value, with: { (dataSnapshot) in guard let snapshotDictionary = dataSnapshot.value as? [String: Any] else { return } var snapshotKeys = [String]() for key in snapshotDictionary.keys { snapshotKeys.append(key) } snapshotKeys.sort() for snapshotKey in snapshotKeys { guard let postDictionary = snapshotDictionary[snapshotKey] as? [String: Any] else { return } let post = Post(postDictionary: postDictionary) self.posts.insert(post, at: 0) } self.collectionView?.reloadData() }) { (error) in print(error.localizedDescription) } }
ngsison
4 years ago
Hi @MT, thanks for showing this solution. However, if we have to do it manually like this, it makes the queryOrdered method from Firebase useless, right? Is there any way we can retrieve the result of queryOrdered in other form than dictionary? @Brian, please share your thoughts as well. :)
AlfieLBTA
5 years ago
Hello Community Can some one explain the use SELF in this line of code : collectionView?.register(UICollectionViewCell.SELF, forCellWithReuseIdentifier: cellId)
Krubel Habteyes
5 years ago
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return posts.count //return 5 } posts.count is not returining anything.
dcheung93
5 years ago
I faced a similar issue. Is there any one who solved it?
atran
5 years ago
Have you called collectionView.reloadData() after fetching data?
antodevo67
5 years ago
Hi Brian, Thank you for your course. It is very pleasant and very helpful. I'm trying to put multiple images in the home cell like in instagram. I'm using a CollectionView but I have an issue. I can't see the first image. Everything works fine because I also use it in the userProfile and I use exactly the same file for cell. It's just in the Home menu that I can't see the first image. I can see it only if I scroll too far on the right. Thank you in advance for your help.
zhuang43
5 years ago
Hi Brian, I really need your help I'm building my own project but encountering a problem. I'm currently using NSAttributedString to store posts that has image and texts combined. (Images inside texts) Is there a better way to achieve this? I realize that I can not access the image(tap to view) inside the AttributedString. What can I do? How should I structure my app?
river
5 years ago
Hi Brian. I am considering purchasing the lesson video now. Because I am not watching your lesson video, I want to ask you a question. Is there a function to delete a user's post in this lesson video? Also, do you use SDWebImage in this lesson video?
petar7
5 years ago
Hi Brian I accidentally added image cache array inside the CustomImageView class and image cache doesn't seem to work, btw. I needed to add self in front of the array but when I put array outside the class as you did caching worked out. How that "self" and array inside the class changes operation of caching?
Brian Voong
5 years ago
petar7
5 years ago
Aha, thank you master Brian :))
Noodledew
4 years ago
Biran I really look forward, going through this course on my vacation next week!
BP4
4 years ago
Hi Brian, excellent course. I need to create a video player in addition to the image view. I've tried multiple pods, but i cant achieve this requirement.
Brian Voong
4 years ago
BP4
4 years ago
Thanks Brian, I will try!
Russel Aboo
4 years ago
HI Brian, I am trying to build a chat app with an approach of keeping a local coredata db and syncing it with the firebase database. I purchased this video for the reference. But i can see that you are directly working against the firebase db. Can you please suggest a way to keep a local db, other than the offline feature of firebase? I just dont feel the firebase offline feature that manageable. Thanks, Russel
Brian Voong
4 years ago
mao
4 years ago
Hi Brain, What should I write if I want to fetch specific users' posts instead of the users I followed? Thanks.
BTol Mohammad
4 years ago
Hi Brain, I get an error when I go from the user profile tab to the home feed this is what it tells me: Will attempt to recover by breaking constraint <NSLayoutConstraint:0x600003241e00 'UISV-canvas-connection' UIStackView:0x7fdffe4a9810.top == UIButton:0x7fdffe4a7ff0.top (active)> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. Then the posts in the home feed become like user profile page but not all of them I can share screenshots with you if you want. Thanks.
Brian Voong
4 years ago
BTol Mohammad
4 years ago
normal homepage: https://ibb.co/YchNf3b user profile: https://ibb.co/6WGr4zs homepage after going to the user profile page: https://ibb.co/NpKcjyY
Brian Voong
4 years ago
BTol Mohammad
4 years ago
I actually have a fresh UICollectionViewFlowLayout() for each collection view controller
Robby
4 years ago
Hi Brain, I'm so happy with the course. I learned a lot from you and I was never able to enjoy coding but thanks to you know everything is so awesome. My app is working good the only small bug I can't fix is how to stop the calling twice of fetchPostWithUsers. In the console prints 13 times the "loading image", when I only have 4 posts from user and followers. Any suggestion how to fix the bug or maybe clean the code? Thank you!
Dino32
4 years ago
Hi Brain! I can't switching between the icons on tabbar from home to profile logo. Can't find an issue. I recheck the code in MainTabbarController and everything is match with your code. Please help me
Brian Voong
4 years ago
Dino32
4 years ago
so fast)) No, just not working errors does not comes up
Dino32
4 years ago
The plus button works correctly.
Brian Voong
4 years ago
Dino32
4 years ago
I tried to remove home button but it doesn't help.
Dino32
4 years ago
Thanks, I found one mistake in code)
Brian Voong
4 years ago
Ajay Choudhary
3 years ago
Hi Brian, Your course is awesome and I am enjoying it a lot I have a problem, In the home feed I am having my images to flicker and change while scrolling through collectionView. Can you help me with that? Thanks
HELP & SUPPORT