Skip to content

Commit

Permalink
build: Adds network layer infra
Browse files Browse the repository at this point in the history
  • Loading branch information
sarvesh-sharma-yral committed Dec 11, 2024
1 parent 4cb8f8f commit 4040867
Showing 4 changed files with 215 additions and 0 deletions.
40 changes: 40 additions & 0 deletions iosApp/iosApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
@@ -24,6 +24,14 @@
AC6BECB42D09D541002E2021 /* GRPC in Frameworks */ = {isa = PBXBuildFile; productRef = AC6BECB32D09D541002E2021 /* GRPC */; };
AC6BECB62D09D541002E2021 /* GRPCReflectionService in Frameworks */ = {isa = PBXBuildFile; productRef = AC6BECB52D09D541002E2021 /* GRPCReflectionService */; };
AC6BECB82D09D55B002E2021 /* protoc-gen-grpc-swift in Frameworks */ = {isa = PBXBuildFile; productRef = AC6BECB72D09D55B002E2021 /* protoc-gen-grpc-swift */; };
AC6BECBC2D09F68C002E2021 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6BECBB2D09F685002E2021 /* Endpoint.swift */; };
AC6BECBD2D09F68C002E2021 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6BECBB2D09F685002E2021 /* Endpoint.swift */; };
AC6BECBF2D09F86C002E2021 /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6BECBE2D09F866002E2021 /* NetworkService.swift */; };
AC6BECC02D09F86C002E2021 /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6BECBE2D09F866002E2021 /* NetworkService.swift */; };
AC6BECC22D09F91C002E2021 /* HTTPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6BECC12D09F917002E2021 /* HTTPService.swift */; };
AC6BECC32D09F91C002E2021 /* HTTPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6BECC12D09F917002E2021 /* HTTPService.swift */; };
AC6BECC52D09FDA6002E2021 /* GRPCService.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6BECC42D09FD9B002E2021 /* GRPCService.swift */; };
AC6BECC62D09FDA6002E2021 /* GRPCService.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6BECC42D09FD9B002E2021 /* GRPCService.swift */; };
AC6CBA802CE46CA6002454F8 /* libyral_mobile_swift_binding.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AC09A9F72CDB78B9009A39A4 /* libyral_mobile_swift_binding.a */; };
ACB815372CF9D4FF00104B7B /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = ACB815342CF9CE0800104B7B /* GoogleService-Info.plist */; };
ACB815482CFA146800104B7B /* FirebaseCore in Frameworks */ = {isa = PBXBuildFile; productRef = ACB815472CFA146800104B7B /* FirebaseCore */; };
@@ -71,6 +79,10 @@
AC09A9F92CDB7A5D009A39A4 /* SwiftBindings+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftBindings+Extensions.swift"; sourceTree = "<group>"; };
AC09AA0A2CDB7F2A009A39A4 /* shared.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = shared.framework; path = "../shared/build/xcode-frameworks/Debug/iphoneos18.1/shared.framework"; sourceTree = "<group>"; };
AC09AA732CDD2107009A39A4 /* Data+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Extensions.swift"; sourceTree = "<group>"; };
AC6BECBB2D09F685002E2021 /* Endpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Endpoint.swift; sourceTree = "<group>"; };
AC6BECBE2D09F866002E2021 /* NetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkService.swift; sourceTree = "<group>"; };
AC6BECC12D09F917002E2021 /* HTTPService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPService.swift; sourceTree = "<group>"; };
AC6BECC42D09FD9B002E2021 /* GRPCService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GRPCService.swift; sourceTree = "<group>"; };
ACB815342CF9CE0800104B7B /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
ACD941B82CFF575C0038FCB6 /* iosAppStaging.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosAppStaging.app; sourceTree = BUILT_PRODUCTS_DIR; };
ACD941B92CFF575C0038FCB6 /* Info-Staging.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-Staging.plist"; path = "/Users/sarveshsharma/Desktop/yral-mobile/iosApp/Staging/Info-Staging.plist"; sourceTree = "<absolute>"; };
@@ -156,6 +168,7 @@
isa = PBXGroup;
children = (
ACF4EFC52D09CC0400086ADF /* grpc */,
AC6BECB92D09F0F0002E2021 /* Infrastructure */,
058557BA273AAA24004C7B11 /* Assets.xcassets */,
7555FF82242A565900829871 /* ContentView.swift */,
AC09AA1E2CDBB69B009A39A4 /* Extensions */,
@@ -202,6 +215,25 @@
path = Extensions;
sourceTree = "<group>";
};
AC6BECB92D09F0F0002E2021 /* Infrastructure */ = {
isa = PBXGroup;
children = (
AC6BECBA2D09F0FD002E2021 /* Network */,
);
path = Infrastructure;
sourceTree = "<group>";
};
AC6BECBA2D09F0FD002E2021 /* Network */ = {
isa = PBXGroup;
children = (
AC6BECBE2D09F866002E2021 /* NetworkService.swift */,
AC6BECBB2D09F685002E2021 /* Endpoint.swift */,
AC6BECC12D09F917002E2021 /* HTTPService.swift */,
AC6BECC42D09FD9B002E2021 /* GRPCService.swift */,
);
path = Network;
sourceTree = "<group>";
};
ACD941BC2CFF57A90038FCB6 /* Prod */ = {
isa = PBXGroup;
children = (
@@ -461,13 +493,17 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AC6BECC02D09F86C002E2021 /* NetworkService.swift in Sources */,
2152FB042600AC8F00CF470E /* IosApp.swift in Sources */,
AC09A9B22CDB775C009A39A4 /* yral-mobile-swift-binding.swift in Sources */,
AC6BECC62D09FDA6002E2021 /* GRPCService.swift in Sources */,
ACF4EFCA2D09D39400086ADF /* ml_feed.grpc.swift in Sources */,
ACF4EFCB2D09D39400086ADF /* ml_feed.pb.swift in Sources */,
AC6BECBD2D09F68C002E2021 /* Endpoint.swift in Sources */,
AC09A9B32CDB775C009A39A4 /* SwiftBridgeCore.swift in Sources */,
AC09AA742CDD210D009A39A4 /* Data+Extensions.swift in Sources */,
AC09A9FA2CDB7A5D009A39A4 /* SwiftBindings+Extensions.swift in Sources */,
AC6BECC22D09F91C002E2021 /* HTTPService.swift in Sources */,
7555FF83242A565900829871 /* ContentView.swift in Sources */,
ACF4EFC72D09CC0400086ADF /* ml_feed.proto in Sources */,
);
@@ -477,13 +513,17 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AC6BECBF2D09F86C002E2021 /* NetworkService.swift in Sources */,
ACD941872CFF575C0038FCB6 /* IosApp.swift in Sources */,
ACD941882CFF575C0038FCB6 /* yral-mobile-swift-binding.swift in Sources */,
AC6BECC52D09FDA6002E2021 /* GRPCService.swift in Sources */,
ACF4EFCC2D09D39400086ADF /* ml_feed.grpc.swift in Sources */,
ACF4EFCD2D09D39400086ADF /* ml_feed.pb.swift in Sources */,
AC6BECBC2D09F68C002E2021 /* Endpoint.swift in Sources */,
ACD941892CFF575C0038FCB6 /* SwiftBridgeCore.swift in Sources */,
ACD9418A2CFF575C0038FCB6 /* Data+Extensions.swift in Sources */,
ACD9418B2CFF575C0038FCB6 /* SwiftBindings+Extensions.swift in Sources */,
AC6BECC32D09F91C002E2021 /* HTTPService.swift in Sources */,
ACD9418C2CFF575C0038FCB6 /* ContentView.swift in Sources */,
ACF4EFC62D09CC0400086ADF /* ml_feed.proto in Sources */,
);
81 changes: 81 additions & 0 deletions iosApp/iosApp/Infrastructure/Network/Endpoint.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// Endpoint.swift
// iosApp
//
// Created by Sarvesh Sharma on 11/12/24.
// Copyright © 2024 orgName. All rights reserved.
//
import Foundation

enum Tranport {
case http
case grpc
}

enum HTTPMethod: String {
case get
case post
case put
case delete
}

struct Endpoint {
let transport: Tranport
let name: String

// HTTP fields
let baseURL: URL?
let path: String?
let httpMethod: HTTPMethod?
let headers: [String: String]?
let queryItems: [URLQueryItem]?
let httpBody: Data?

// grpc fields
let serviceName: String?
let methodName: String?
let grpcRequestData: Data?

// HTTP initializer
init(http name: String,
baseURL: URL,
path: String,
method: HTTPMethod,
queryItems: [URLQueryItem]? = nil,
headers: [String: String]? = nil,
body: Data? = nil) {
self.transport = .http
self.name = name
self.baseURL = baseURL
self.path = path
self.httpMethod = method
self.queryItems = queryItems
self.headers = headers
self.httpBody = body

// Unused for HTTP
self.serviceName = nil
self.methodName = nil
self.grpcRequestData = nil
}

// gRPC initializer
init(grpc name: String,
serviceName: String,
methodName: String,
requestData: Data) {
self.transport = .grpc
self.name = name
self.serviceName = serviceName
self.methodName = methodName
self.grpcRequestData = requestData

// Unused for gRPC
self.baseURL = nil
self.path = nil
self.httpMethod = nil
self.queryItems = nil
self.headers = nil
self.httpBody = nil
}
}
74 changes: 74 additions & 0 deletions iosApp/iosApp/Infrastructure/Network/HTTPService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// HTTPService.swift
// iosApp
//
// Created by Sarvesh Sharma on 11/12/24.
// Copyright © 2024 orgName. All rights reserved.
//

import UIKit

class HTTPService: NetworkService {
func performRequest(for endPoint: Endpoint) async throws -> Data {
guard endPoint.transport == .http,
let baseURL = endPoint.baseURL,
let path = endPoint.path,
let method = endPoint.httpMethod else {
throw NetworkError.invalidRequest
}
var urlComponents = URLComponents(url: baseURL.appendingPathComponent(path), resolvingAgainstBaseURL: false)
urlComponents?.queryItems = endPoint.queryItems
guard let finalURL = urlComponents?.url else {
throw NetworkError.invalidRequest
}

var request = URLRequest(url: finalURL)
request.httpMethod = method.rawValue
request.allHTTPHeaderFields = endPoint.headers
request.httpBody = endPoint.httpBody
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse else {
throw NetworkError.invalidResponse("")
}
guard HTTPResponse.from(statusCode: httpResponse.statusCode) == .success else {
throw NetworkError.invalidResponse(httpResponse.description)
}
return data
}

func performRequest<T>(for endPoint: Endpoint, decodeAs type: T.Type) async throws -> T where T: Decodable {
let data = try await performRequest(for: endPoint)
do {
let decoded = try JSONDecoder().decode(type, from: data)
return decoded
} catch {
throw NetworkError.decodingFailed(error)
}
}
}

enum HTTPResponse {
case success
case clientError
case serverError
case informational
case redirection
case unknown

static func from(statusCode: Int) -> HTTPResponse {
switch statusCode {
case 200...299:
return .success
case 400...499:
return .clientError
case 500...599:
return .serverError
case 100...199:
return .informational
case 300...399:
return .redirection
default:
return .unknown
}
}
}
20 changes: 20 additions & 0 deletions iosApp/iosApp/Infrastructure/Network/NetworkService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// NetworkService.swift
// iosApp
//
// Created by Sarvesh Sharma on 11/12/24.
// Copyright © 2024 orgName. All rights reserved.
//
import Foundation

protocol NetworkService {
func performRequest(for endPoint: Endpoint) async throws -> Data
func performRequest<T: Decodable>(for endPoint: Endpoint, decodeAs type: T.Type) async throws -> T
}

enum NetworkError: Error {
case invalidRequest
case invalidResponse(String)
case decodingFailed(Error)
case transportError(String)
}

0 comments on commit 4040867

Please sign in to comment.