ucladevx / Bruin-Bite-iOS

Mozilla Public License 2.0
8 stars 1 forks source link

Enable profile picture upload/download support #128

Closed HirdayGupta closed 5 years ago

HirdayGupta commented 5 years ago

Overview

This is going to be tackled in three steps:

  1. Add the endpoints to Moya
  2. Create a new ProfilePictureAPI with two methods - one for upload and one for download.
  3. Dive into the view controllers and make the upload/download calls and display their results as necessary.

Let's go into more detail for each of these steps:

Step 1: Adding endpoints to Moya

Two new Moya requests, uploadProfilePicture(image: Data) and getProfilePicture(forUserID: Int).

  1. For uploadProfilePicture, @keshpr's code is expecting the following params: user_id - the currently logged in user who is uploading their own profile picture - can be found in UserManager.shared.getUID() and profile_picture - a byte stream.

  2. For downloadProfilePicture, it will be a simple GET request. The response will be handled in the API defined below.

Note that both these endpoints need bearer token authorization, so choose the header accordingly.

Step 2: Creating the new API

In a new file ProfilePictureAPI define two new methods (upload and download) and the related protocols, as always.

  1. For the upload method, accept one param image of type UIImage - this will be passed by the VC where image is chosen.

    • Since MultipartUpload requires a format of Data, get a Data object from UIImage using UIImage's jpegData method with a reasonable compression quality (~ 0.7), then send this data object to the Moya request, which expects a param of type Data
    • The ID param can be populated by the code inside Moya.swift by calling UserManager.shared.getUID()
  2. For the download method, accept user_id as a param and send the moya request created above with the provided param. If successful, the end point will return a JSON with the following format:

    {
    "user_id": <as in the request>
    "profile_picture": <a base64 encoded string>
    }

    Now, what you should do is take the base64 encoded string from Profile Picture, convert it to a Data object and then convert that data object to UIImage. See this code sample for hints on doing this (taken from this S/O answer):

    let dataDecoded:NSData = NSData(base64EncodedString: strBase64, options: NSDataBase64DecodingOptions(rawValue: 0))!
    let decodedimage:UIImage = UIImage(data: dataDecoded)!

    You can then return this UIImage to the ViewController who requested this info via the completion delegate.

Check the backend spec to see what error codes to look out for and see how you want handle (or not handle) them.

Step 3: View controller work

  1. Start with CreateProfileViewController from the sign-up flow.

    • When the user finishes picking an image from the UIPickerImageController, the callback func imagePickerController on line 111 of CreateProfileViewController.swift is called. The selected image is a UIImage stored in pickedImage.
    • Start the upload job and wait for the success callback before enabling the "next button" (you might have to create a reference to it from the storyboard).
    • notify the with a UIAlertController appropriately if an upload error occurs.