iOS Swift App with More Photos: Performance and Storage Suggestions

iOS Swift App with more photos: Performance and Storage suggestions

You can do it next way:

1) Upload file to firebase storage and get download url for it:

static func upload(_ image: UIImage,
completion: @escaping (_ hasFinished: Bool, _ url: String) -> Void) {
let data: Data = UIImageJPEGRepresentation(image, 1.0)!

// ref should be like this
let ref = FIRStorage.storage().reference(withPath: "media/" + userId + "/" + unicIdGeneratedLikeYouWant)
ref.put(data, metadata: nil,
completion: { (meta , error) in
if error == nil {
// return url
completion(true, (meta?.downloadURL()?.absoluteString)!)
} else {
completion(false, "")
}
})

Then save url of the uploaded photo to user node with FIRDatabase. It will look like:

Sample Image

But it will be posts ids for example instead of mediaRef10 and mediaRef700

So, you will have in user node links to photos and you can easy get them with good perfomance.

Two apps in one device and the image uploaded from first app will appear in the second app

Yes you can share some data within groups of app as per new updates in iOS 8.0 and above.

Just you need to create apps group and share your data among that groups app.

Below are few steps to enable app groups.

Step1: Enable App group from Target Setting -> Capabilities -> App Group

Sample Group name : groups.companyname or groups.appgroupname

Sample Image

Note: Every app which you want in this group must have same group name
in this section.

Step 2: Get General sharing folder where you can store shared data like images DB.

for that you need to get path of that shared folder as mention below

Objective-C :

- (NSString *)getSharedGroupFolderPath:(NSString*)aAppGroupName {
NSURL *aContainerPathURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:aAppGroupName];
return [aContainerPathURL relativePath];
}

Swift:

static func appGroupContainerURL() -> URL? {
// 1
let fileManager = FileManager.default
guard let groupURL = fileManager
.containerURL(forSecurityApplicationGroupIdentifier: <APP_GROUP_NAME>) else {
return nil
}

let storagePathUrl = groupURL.appendingPathComponent("File Provider Storage")
let storagePath = storagePathUrl.path
// 2
if !fileManager.fileExists(atPath: storagePath) {
do {
try fileManager.createDirectory(atPath: storagePath,
withIntermediateDirectories: false,
attributes: nil)
} catch let error {
print("error creating filepath: \(error)")
return nil
}
}
// 3
return storagePathUrl

}

By above method you can get Group container folder path now save your data here which you need to share among multiple Apps.

Step3:

Store your image of file on container path like below

guard let destinationURL = TestFileViewController.fileUrlForDocumentNamed("FileName") else {
return
}

let image = UIImage.init(named: "tests")

if !FileManager.default.fileExists(atPath: destinationURL.path) {

do {
try UIImageJPEGRepresentation(image!, 1.0)!.write(to: destinationURL)
print("file saved")
} catch {
print("error saving file")
}
} else {
print("file already exists")
}

Use below supported method for getting file path :

// Returns the file URL for the file to be saved at
static func fileUrlForDocumentNamed(_ name: String) -> URL? {
guard let baseURL = appGroupContainerURL() else { return nil }

let protectedName: String
if name.isEmpty {
protectedName = "Untitled"
} else {
protectedName = name
}

return baseURL.appendingPathComponent(protectedName)
.appendingPathExtension("your file extension")
}

Hope this will helps you to achieve your requirements.

iOS integrate photos app

Facebook doesn't use the native photos app. It has built its own toolkit for that and have even open sourced their toolkit - Three20. It does have support for creating photo galleries for content based on the net so I imagine this will suit your use case. You can get started off by looking at tutorials already available on the net along with their documentation. Specifically look at this.

Finding optimum image dimensions and reducing memory usage for an iOS app

The assets catalog is going to be the most efficient way to have different assets for different devices, while enjoying "app thinning" which can allow a device to only download the assets needed for that particular device (keeping app downloads as small as possible).

For example, if you have a 200x200 image view, if you want to be most memory efficient for different types of devices, you'd have a 1x (i.e. 200x200), 2x (i.e. 400x400), and 3x (i.e. 600x600) rendition of that asset, and through the efficiency of assets catalogs, the device would download and use the asset of the appropriate scale for that device.

If, on the other hand, you only supply only a 1x image (e.g. a 200x200 image in our above example), it will look pixelated on a retina device, which will put off many users. Or you can supply only a 3x image (e.g. a 600x600 image), it will look sharp on all devices, but you'll be taking up more memory than needed on non-retina devices (or, if you do just-in-time resizing, you can offset the memory impact, but at the cost of performance).

So, if you want the best looking and most responsive UI that works on well on devices of multiple scale resolution, you'd supply all three resolutions. And if you use an asset catalog, it makes the selection of the asset at runtime easier, and you open up the possibility of app thinning.

Core Data performance issue with images

Finally I figured out a way... (thanks for all your suggestions).

This was my situation.

  1. User can upload any photo to display on their profile
  2. User must be able to view his profile whenever he wants and the
    photo should be displayed all the time.
  3. It took around 1 ~ 5 sec to retrieve user's profile image from core
    data, depending on size of image.

This is what I did

  1. Provided user to crop the image before saving it for the first time.
  2. I saved both the cropped and the actual image in core data.
  3. Showed the cropped smaller sized image when user viewed his profile.
  4. Showed the original image only when the user tried to edit his image (so that he can resize again).

Below is the code to edit image. Set imagePicker.allowsEditing = YES to show move and scale frame.

- (IBAction)myProfileImageEditButton:(id)sender
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.delegate = self;
imagePicker.allowsEditing = YES;

[self presentViewController:imagePicker animated:YES completion:nil];
[self finishAndUpdateImage];
}

// This method is called when an image has been chosen from the library or taken from the camera.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//this line moves your original image into image.
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
//this line moves your original image into editedImage.
UIImage *editedImage = [info valueForKey:UIImagePickerControllerEditedImage];

//create an NSMutable array myImage and store both original and edited images for later use.
[self.myImages addObject:image];
[self.myImages addObject:editedImage];
[self dismissViewControllerAnimated:YES completion:NULL];
//declare your own updateImage method. Store both image and editedImage in core data (in my case, this is what I wanted. Change it based on your requirement). Retrieve only the smaller sized editedImage when user tries to view again.
[self updateImage];
}


Related Topics



Leave a reply



Submit