Large amounts of images in Firebase - ios

I am currently developing an iOS App for a photographer. The main attraction of the App is going to be a gallery of their work, so about 300MB of Images.
My plan until now was to include lower resolution versions of the Images on the App itself and have the full resolution Images pulled from a FirebaseDatabase to replace the low-res versions.
Now I am doubting myself though, since pulling 300MB worth of Images from Firebase for every user seems like it would get rather costly. Would it be a better bet for me to just accept the bigger download and include all of the Images in the App? Considering that would also save the users time and give them a smoother experience it seems like the better option. But I am not sure if there are issues with this that I am not aware of.
How do people usually deal with this sort of a thing?

Related

How to copy adjustments made in Photos to another photo using PhotoKit

I’ve been trying to figure out a way to copy adjustments made in the native Photos app on macOS to a different photo using PhotoKit or Swift.
My DSLR sends lower quality versions of every photo it takes right to my phone as it takes them, but when I get around to importing the high res copies from the SD card, I’d like to be able to easily copy the favourited status and any edits I may have made to the high res versions.
Copying the isFavourite status and removing the duplicate files was easy, but I can’t figure out a way to copy edits over to the higher quality file. I figured since it’s an easy copy/paste in Photos that it shouldn’t be too difficult with code.
Has anyone managed to pull this off?

Best practice for storing and updating images in Xcode project

I am building my flash card iOS app for reviewing my learning Japanese using SwiftUI language.
The problem is how to storing and updating my images(>500 images). Please help me, any suggestion is appreciated, thanks for reading my post.
I think you're asking about how to manage 500+ images in an Xcode project. You could just add all the images to your project and load them as you would any image. You could use asset catalogs, which have the advantage that they let you store different versions of a resource for use on different devices, and only the ones needed for the device the app runs on will actually be installed on the device. See How Many Images Can/Should you Store in xcassets in Xcode? and Asset Catalog Format Reference for more information about asset catalogs. But any way you slice it, managing 500+ images is going to be cumbersome. There's probably a better way...
Managing all those images in your app isn't just a problem for you as the developer; building them into the app will also create problems for the user. Even if each image is relatively small, having hundreds of them in the app will probably make the app huge. That means it'll take a long time to install, and the app will use a lot of storage on the device. Every time you release a new version of the app, with more words, or even just to fix a few small bugs, the user will have to download all that data all over again.
Instead, you should consider building an app that can fetch the data it needs from a server. Ideally, you could apply that approach to all your app's data, not just the images. Maybe you'll organize your flash cards into sets of a few dozen, so that you can fetch a set of cards and the associated images pretty quickly, and sets that the user hasn't used for a while can be removed to free up space on the device. You'll be able to update a set of flash cards without having to update the app, and when you do update the app your users won't have to download all the data all over again.
You've said that you're a beginner, so this approach might seems very difficult. That's OK, you can start with a simpler approach and then improve as you go along. For example, you might just put all the images on a server and fetch them one at a time as you need them. Your flash card data file could contain just a dictionary with words and the URLs associated with those words. There are lots of examples of loading an image from an URL here on SO and elsewhere, so I'm not going to provide code for that, but it won't be hard to find. The earlier you start thinking about how to design your app so that it can scale as you add more and more words, the easier it will be to maintain the app later.
500 images can have a huge size. Applications that published on Appstore have size limit and Apple does not recommend to make big apps.
Store them on server and load needed images on fly. Also you will get possibility to update your images, remove add new.
If you don't have a backend, you can use something easy and free (Firebase storage for example) or with minimal code writing on AWS.
If you need to keep them on device - store them as files in the Documents or another apps folder, do not use CoreData for it (you can keep only the list of names/urls in database).
After loading image to be displayed for user, you can prefetch next bunch of images.
Use Alamofire, or SDWebImage to load images from network (I prefer last). These frameworks can do many useful things with images.
To load images:
you can have a list of your images (just list of the names and urls)
or
you can know only path and names pattern and generate links dynamically (like https://myserver/imageXXX.png.

Generating Thumbnails on Client

My team and I are building an iOS application. We allow technicians in the field to upload images for certain issues they are resolving on technical equipment. It will be important to zoom in (so keep quality relatively high) when these images are uploaded to S3.
Recently we decided to add thumbnails because it will be much faster when others browse the iOS app, rather than downloading a 1.5-2.5mb image.
My co-worker decided the best way to handle this is to generate a 200-500kb thumbnail in iOS then upload the image and the thumbnail to s3.
I voiced my concern that some of our technicians may be in some parts of the world where internet is slow and data usage is limited. So doing all this additional work on the device and uploading makes no sense to me. However the team considers this a good solution and will move forward. I've shown them easy examples of how to generate thumbnails from S3 and Lambda automatically on the server... allowing us to either upload higher fidelity images with the additional bandwith or just increase the speed of the app by uploading much less. Sometimes a user may upload as many as 100 images... meaning an additional 20-50mb...
Anyways I wanted to hear some answers about how you guys think the best way to handle this is, mainly for my own sanity check.
I don't completely comprehend the intricacies of your project, but from experience, I have one word for you - Cloudinary. As opposed to S3, which a general purpose Cloud storage solution, cloudinary is designed to handle images.
We have a 200,000 hits a day online classified app that handles tens of thousands of photos daily. And cloudinary provides an extremely mean solution for all our needs. We have uploads by users from their mobile and desktop devices, bookmarking of those images, CDN based serving, and thumbnail generation.
Did I mention they have thumbnail generation built in? They have lots of other features as well, including
Resize and Crop
Optimized JPEG Custom Crop
Face Thumbnail
Rotated Circular Thumbnail
Zoom Effects and Zoom Image Overlay
Watermark Image
Optimized WebP
Overlay, Border, Shadow Text Overlay, Border, Shadow etc.
The admin console is pretty kickass too, with all of the above features available for you to configure over the cloud. And it fits well with pretty much any application (we use it in our internal Ruby, Go, NodeJS services, our Web Application and our iOS and Android apps as well).
I'm not paid to sell Cloudinary to you, but I can vouch that if it is image based services I needed, I would go for Cloudinary any day over S3. Major players like EBay and TED etc. use it for their image requirements.

Downloading and displaying big images: possible approaches

I'm developing a game where the main element of gameplay is an image of 2400x1600 pixels. So we are having some discussion about what's the best approach we could follow and confirm that we are not missing anything in order to download the image from the server and get it displayed on the device. So we thought about the different approaches and see what everyone else's thoughts are. I would really appreciate if you can list another approach you can think of. Before getting into the approaches themselves, some things that we need to take for granted:
User experience since gameplay started should be smooth. This made us get rid of one possible approach that was to implement it like Google Maps i.e. downloading tiles from the server as the user pans/zooms the map since there will be for sure some delay until the tile is finally displayed.
Images cannot be shipped within the binary file since they will be updated frequently.
All the tiles of each image weight around 6MB
So possible solutions we see so far:
Download and tiling the images in a background process/task all at once as they get updated. The big loading time here will be the first time the user launches the app. Images don't get updated together neither very frequently - one day minimum.
From the moment the user gets to the screen to select the image to play, start the process of downloading and tiling. User can select between 2 pictures only.
If user is on WiFi, use solution 1. If user is over cellular network then use solution 2.
Thanks in advance.
Use SDWebImage. It provides a ton of features for caching images, downloading in background, and much more.
The NSURLSession class in iOS 7 is well-suited for your needs. It allows for background downloads, resuming and pausing downloads, and is heavily customisable.
Now, I know this is a little vague, so here are some great references to start with :
Apple's NSURLSession Documentation
Mobile.TutsPlus NSURLSession Tutorials

Make changes to database in Rails without having to reset the whole thing

I'm new to Rails and coding, so this may be a very basic question...
This evening I was working on an app and changed the image uploader so that it saves two different sizes of images to the database - one smaller to show on the page, and one larger version for using in a lightbox (colorbox).
The issue I ran into was that users already existed in the database both in development and in production. Luckily, I created these users using the Faker gem, and in production it was just me posting things to check out how it looks in production.
So, for images that were already in the database, they were only saved as the smaller version thereby making it so that the lightbox displays a broken image (because the larger version doesn't exist).
Because I could do so without losing anything important, I reset the database and in development I ran the Faker rake again, and in production I just signed back up and uploaded some of my own photos over again. (I am pretty much absolutely positive this is not best practices... but I am really just getting into the second month of learning...)
My question is this: Is there a way to redo the database so that those images that were originally in there get to stay, and are just re-saved to the database with both versions.
Or alternatively, is there a way to need only one version of the image saved and the lightbox/colorbox can manipulate the original size image to render in the size I want?
For example, maybe it would be that when the user uploads an image, the image saves to the database in the larger version and then for the "thumbnail" I code it so that it just shrinks the photo down to the size I want displayed on the page??
For reference, here is a link to the Heroku deployment of the app:
http://desolate-waters-6166.herokuapp.com/
I am using this app as my own sample app for trying out different things and learning how to do things on something without much consequence.
Thanks in advance! Let me know if I need to provide more info. I can also link the github repository for this app.
Nice, the site looks pretty cool. To answer your question, I don't there is an easy way, nor worth the task, of taking all your user's images and attempting to transform them into high quality. I think the best option would be to add a column for high res thumbnails, and make sure thumbnails get saved as high res going forward. I do believe, to answer your second question, if you store a high quality image, then shrinking it will not hurt the quality, only going beyond the size of the resolution, if that makes sense. So maybe deprecate storing low quality images, and just store them high res going forward.
I would suggest to take a look at the carrierwave gem. It uses ImageMagick for image resizing and stores the image location in the database (instead of the image itself). This way you can store the image files at cheaper of free locations , like S3 of Amazon. The other advantage is size versioning, which is made very smooth.

Resources