Skip to content

Commit

Permalink
Hotfix: fix project.pbxproj to able to build xcframeworks
Browse files Browse the repository at this point in the history
  • Loading branch information
Alejandro Arjonilla committed Dec 11, 2024
1 parent 32cfe9e commit 7e8d3b5
Show file tree
Hide file tree
Showing 78 changed files with 6,552 additions and 438 deletions.
896 changes: 458 additions & 438 deletions AppliverySDK.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions AppliverySDK/API/APIClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//
// APIClient.swift
// Applivery
//
// Created by Fran Alarza on 27/11/24.
//

import Foundation

protocol APIClientProtocol {
func fetch<T: Decodable>(endpoint: Endpoint) async throws -> T
func uploadVideo(localFileURL: URL, to destinationURL: URL) async throws
}

final class APIClient: APIClientProtocol {
private let session: URLSession

private lazy var decoder: JSONDecoder = {
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .millisecondsSince1970
return jsonDecoder
}()

init(session: URLSession = .shared) {
self.session = session
}

func fetch<T: Decodable>(endpoint: Endpoint) async throws -> T {
let request = try endpoint.getURLRequest()
let (data, response) = try await session.data(for: request)

guard let httpResponse = response as? HTTPURLResponse else {
throw APIError.invalidResponse
}

logInfo("STATUS CODE: \(httpResponse.statusCode)")
data.prettyPrintedJSON()

switch httpResponse.statusCode {
case 200...299:
return try decoder.decode(T.self, from: data)
default:
throw APIError.statusCode(httpResponse.statusCode)
}
}

func uploadVideo(localFileURL: URL, to destinationURL: URL) async throws {
var request = URLRequest(url: destinationURL)
request.httpMethod = "PUT"
request.setValue("video/mp4", forHTTPHeaderField: "Content-Type")

let (data, response) = try await session.upload(for: request, fromFile: localFileURL)

guard let httpResponse = response as? HTTPURLResponse else {
throw APIError.invalidResponse
}

switch httpResponse.statusCode {
case 200...299:
logInfo("Video uploaded successfully")
default:
throw APIError.statusCode(httpResponse.statusCode)
}

logInfo("STATUS CODE: \(httpResponse.statusCode)")
data.prettyPrintedJSON()
}
}

extension Data {
func prettyPrintedJSON() {
if let jsonObject = try? JSONSerialization.jsonObject(with: self, options: []),
let prettyPrintedData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted),
let prettyJSONString = String(data: prettyPrintedData, encoding: .utf8) {
logInfo("- RESPONSE: \n \(prettyJSONString)")
} else {
logInfo(String(data: self, encoding: .utf8) ?? "")
}
}
}
19 changes: 19 additions & 0 deletions AppliverySDK/API/APIError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// APIError.swift
// Applivery
//
// Created by Fran Alarza on 27/11/24.
//

import Foundation

enum APIError: Error {
case networkError(Error)
case decoding
case invalidURL
case invalidResponse
case unathorizedResponse
case statusCode(Int)
case ottCheckTimeout
case apiErrorResponse(APIErrorResponse)
}
17 changes: 17 additions & 0 deletions AppliverySDK/API/APIErrorResponse.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// APIErrorResponse.swift
// Applivery
//
// Created by Fran Alarza on 28/11/24.
//


struct APIErrorResponse: Decodable {
let status: Bool
let error: APIErrorDetail
}

struct APIErrorDetail: Decodable {
let message: String
let code: Int
}
109 changes: 109 additions & 0 deletions AppliverySDK/API/AppliveryEndpoint.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//
// AppliveryEndpoint.swift
// Applivery
//
// Created by Fran Alarza on 27/11/24.
//

import Foundation


enum AppliveryEndpoint {
case config
case login(LoginData)
case bind(User)
case download(String)
case feedback(FeedbackData)
case redirect
}

extension AppliveryEndpoint: Endpoint {

var host: String {
switch self {
case .config: return GlobalConfig().host
case .login: return GlobalConfig().host
case .bind: return GlobalConfig().host
case .download: return GlobalConfig().host
case .feedback: return GlobalConfig().host
case .redirect: return GlobalConfig().host
}
}

var headers: [String : String]? {
let appToken = "Bearer \(GlobalConfig.shared.appToken)"
let app = GlobalConfig.shared.app
let device = GlobalConfig.shared.device
let version = app.getSDKVersion()

var headers: [String: String] = [
"Content-Type": "application/json",
"Accept-Language": app.getLanguage(),
"Authorization": appToken,
"x-installation-token": device.vendorId(),
"x-sdk-version": "IOS_\(version)",
"x-app-version": app.getVersionName(),
"x-os-version": device.systemVersion(),
"x-os-name": device.systemName(),
"x-device-vendor": "Apple",
"x-device-model": device.model(),
"x-device-type": device.type(),
"x-package-name": app.bundleId(),
"x-package-version": app.getVersion()
]

if let authToken = GlobalConfig.shared.accessToken?.token {
headers["x-sdk-auth-token"] = authToken
}

return headers
}

var path: String {
switch self {
case .config:
return "/v1/app"
case .login:
return "/v1/auth/login"
case .bind:
return "/v1/auth/customLogin"
case .download(let buildId):
return "/v1/build/\(buildId)/downloadToken"
case .feedback:
return "/v1/feedback"
case .redirect:
return "/v1/auth/redirect"
}
}

var method: HTTPMethod {
switch self {
case .config, .download, .redirect:
return .get
case .login, .bind, .feedback:
return .post
}
}

var body: [String : Any]? {
switch self {
case .config, .download, .redirect:
return nil
case .login(let loginData):
return loginData.dictionary
case .bind(let user):
return user.dictionary
case .feedback(let feedback):
return feedback.dictionary
}
}
}

extension Encodable {
var dictionary: [String: Any]? {
guard let data = try? JSONEncoder().encode(self) else { return nil }
return (try? JSONSerialization
.jsonObject(with: data, options: .allowFragments))
.flatMap { $0 as? [String: Any] }
}
}
65 changes: 65 additions & 0 deletions AppliverySDK/API/Endpoint.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// File.swift
// Applivery
//
// Created by Fran Alarza on 27/11/24.
//

import Foundation

protocol Endpoint {
var host: String { get }
var path: String { get }
var method: HTTPMethod { get }
var body: [String: Any]? { get }
var headers: [String: String]? { get }
}

extension Endpoint {
func getURLRequest() throws -> URLRequest {
let url = try makeURL(from: self)
var request = URLRequest(url: url)
request.httpMethod = self.method.rawValue
request.httpBody = makeBody(from: self.body)

if let headers = self.headers {
for (key, value) in headers {
request.setValue(value, forHTTPHeaderField: key)
}
}

request.debug()
return request
}

private func makeBody(from params: [String: Any]?) -> Data? {
guard let params, !params.isEmpty else { return nil }

return try? JSONSerialization.data(withJSONObject: params)
}

private func makeURL(from endpoint: Endpoint) throws -> URL {
var components = URLComponents()
components.scheme = "https"
components.host = endpoint.host
components.path = endpoint.path

guard let url = components.url else {
throw APIError.invalidURL
}
return url
}
}

extension URLRequest {
func debug() {
print("""
- METHOD: \(self.httpMethod ?? "")
- URL: \(String(describing: self.url))
- HEADERS: \(self.allHTTPHeaderFields ?? ["": ""])
- BODY: \(String(data: self.httpBody ?? Data(), encoding: .utf8) ?? "")
""")
}
}


15 changes: 15 additions & 0 deletions AppliverySDK/API/HTTPMethod.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// HTTPMethod.swift
// Applivery
//
// Created by Fran Alarza on 27/11/24.
//

import Foundation

enum HTTPMethod: String {
case get = "GET"
case post = "POST"
case put = "PUT"
case delete = "DELETE"
}
Loading

0 comments on commit 7e8d3b5

Please sign in to comment.