Skip to content
This repository has been archived by the owner on Apr 27, 2024. It is now read-only.

Commit

Permalink
Implemented application attachment upload
Browse files Browse the repository at this point in the history
  • Loading branch information
carlobortolan committed Sep 12, 2023
1 parent 006f4f7 commit 3bb3c16
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 16 deletions.
Binary file added .DS_Store
Binary file not shown.
6 changes: 3 additions & 3 deletions mobile/Controllers/ApplicationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ class ApplicationManager: ObservableObject {
}
}

func submitApplication(iteration: Int, jobId: Int, userId: Int, message: String) {
func submitApplication(iteration: Int, jobId: Int, userId: Int, message: String, cv: Data?) {
print("Iteration \(iteration)")
let application = Application(jobId: jobId, userId: userId, createdAt: "", updatedAt: "", status: "0", applicationText: message, applicationDocuments: nil, response: nil)
if let accessToken = authenticationManager.getAccessToken() {
APIManager.createApplication(accessToken: accessToken, application: application) { tokenResponse in
APIManager.createApplication(accessToken: accessToken, application: application, cv: cv) { tokenResponse in
switch tokenResponse {
case .success(let apiResponse):
DispatchQueue.main.async {
Expand All @@ -158,7 +158,7 @@ class ApplicationManager: ObservableObject {
// Refresh the access token and retry the request
self.authenticationManager.requestAccessToken() { accessTokenSuccess in
if accessTokenSuccess{
self.submitApplication(iteration: 1, jobId: jobId, userId: userId, message: message)
self.submitApplication(iteration: 1, jobId: jobId, userId: userId, message: message, cv: cv)
} else {
self.errorHandlingManager.errorMessage = error.localizedDescription
}
Expand Down
19 changes: 7 additions & 12 deletions mobile/Networking/APIManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -167,19 +167,14 @@ class APIManager {
/// - Parameters:
/// - accessToken: The user's access token for authentication.
/// - completion: A closure that receives a `Result` with a `APIResponse` or an `APIError`.
static func createApplication(accessToken: String, application: Application, completion: @escaping (Result<APIResponse, APIError>) -> Void) {
ApplicationHandler.createApplication(accessToken: accessToken, application: application, completion: completion)
static func createApplication(accessToken: String, application: Application, cv: Data?, completion: @escaping (Result<APIResponse, APIError>) -> Void) {
if let data = cv {
ApplicationHandler.createAttachmentApplication(accessToken: accessToken, application: application, attachment: data, completion: completion)
} else {
ApplicationHandler.createNormalApplication(accessToken: accessToken, application: application, completion: completion)
}
}

/// Delegates the accepting of an applicant's applications to ApplicationHandler.
///
/// - Parameters:
/// - accessToken: The user's access token for authentication.
/// - completion: A closure that receives a `Result` with a `APIResponse` or an `APIError`.
static func acceptApplication(accessToken: String, message: String?, application: Application, completion: @escaping (Result<APIResponse, APIError>) -> Void) {
ApplicationHandler.acceptApplication(accessToken: accessToken, message: message, application: application, completion: completion)
}


/// Delegates the rejecting of an applicant's applications to ApplicationHandler.
///
/// - Parameters:
Expand Down
94 changes: 93 additions & 1 deletion mobile/Networking/ApplicationHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ApplicationHandler {
RequestHandler.performRequest(url: url, httpMethod: HTTPMethod.GET, accessToken: accessToken, responseType: ApplicationsResponse.self, completion: completion)
}

static func createApplication(accessToken: String, application: Application, completion: @escaping (Result<APIResponse, APIError>) -> Void) {
static func createNormalApplication(accessToken: String, application: Application, completion: @escaping (Result<APIResponse, APIError>) -> Void) {
print("Started creating application with: \naccess_token: \(accessToken)")
guard let urlComponents = URLComponents(string: Routes.ROOT_URL + Routes.JOBS_PATH + "/\(application.jobId)" + Routes.APPLICATIONS_PATH) else {
completion(.failure(APIError.invalidURL))
Expand Down Expand Up @@ -103,6 +103,98 @@ class ApplicationHandler {
}
}

static func createAttachmentApplication(accessToken: String, application: Application, attachment: Data, completion: @escaping (Result<APIResponse, APIError>) -> Void) {
print("Started creating application with: \naccess_token: \(accessToken)\njobId: \(application.jobId)\nuserId: \(application.userId)")

// Create a unique boundary string
// let boundary = "Boundary-\(UUID().uuidString)"

// Create the URLRequest
guard let urlComponents = URLComponents(string: Routes.ROOT_URL + Routes.JOBS_PATH + "/\(application.jobId)" + Routes.APPLICATIONS_PATH) else {
completion(.failure(APIError.invalidURL))
return
}

guard let url = urlComponents.url else {
completion(.failure(APIError.invalidURL))
return
}


var request = URLRequest(url: url)
request.httpMethod = "POST"

let boundary = UUID().uuidString
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.setValue(accessToken, forHTTPHeaderField: "access_token")

var body = Data()
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"application_text\"\r\n\r\n".data(using: .utf8)!)
body.append("\(application.applicationText)\r\n".data(using: .utf8)!)

body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"application_attachment\"; filename=\"\(application.jobId)_\(application.userId)_cv.pdf\"\r\n".data(using: .utf8)!)
body.append("Content-Type: application/pdf\r\n\r\n".data(using: .utf8)!)

// Append the file data here
body.append(attachment)

body.append("\r\n".data(using: .utf8)!)
body.append("--\(boundary)--\r\n".data(using: .utf8)!)

request.httpBody = body

URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Error fetching data: \(error)")
completion(.failure(APIError.networkError(error)))
return
}

if let httpResponse = response as? HTTPURLResponse {
let statusCode = httpResponse.statusCode
print("HTTP Response Code: \(statusCode)")
print("HTTP Response: \(response.debugDescription)")

RequestHandler.handleApiErrorsNew(data: data, statusCode: statusCode, completion: completion)
switch statusCode {
case 204:
completion(.failure(APIError.noContent(String(describing: ImageResponse.self))))
case 200:
if let data = data {
do {
if let responseString = String(data: data, encoding: .utf8) {
print("Data as String: \(responseString)")
} else {
print("Failed to convert data to string")
}
let responseData = try JSONDecoder().decode(APIResponse.self, from: data)
completion(.success(responseData))
} catch {
print("JSON Error: \(error)")
completion(.failure(APIError.jsonParsingError(error)))
}
} else {
completion(.failure(APIError.unknownError))
}
default:
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print("Error JSON = \(json)")
} catch {
completion(.failure(APIError.jsonParsingError(error)))
}
} else {
completion(.failure(APIError.unknownError))
}
}
}
}.resume()
}


static func rejectApplication(accessToken: String, message: String?, application: Application, completion: @escaping (Result<APIResponse, APIError>) -> Void) {
print("Started rejecting application with: \naccess_token: \(accessToken)\njobId: \(application.jobId)\nuserId: \(application.userId)")
guard let urlComponents = URLComponents(string: Routes.ROOT_URL + Routes.JOBS_PATH + "/\(application.jobId)" + Routes.APPLICATIONS_PATH + "/\(application.userId)" + Routes.REJECT_PATH) else {
Expand Down

0 comments on commit 3bb3c16

Please sign in to comment.