티스토리 뷰
기존의 비동기 처리 방식을
(escaping completion 을 RxSwift single로 리팩토링 이후 해당 Single 함수를 Fetch 함수 내부에서 사용)
async await 비동기 처리 방식으로 refactoring 하는 과정입니다.
- 기존 코드 (escaping completion + RxSwift single)
Data - Repository - Search - Search User List API 의 일부
// Data - Repository - Search - search user list 함수 예시
private func lookUpRequest(userId: String,
keyword: String,
page: Int32 = 1,
capacity: Int32 = 30,
completion: @escaping (Result<Search_V1_LookUpResponse, Error>) -> Void){
var request = Search_V1_LookUpRequest()
request.userID = userId
request.word = keyword
request.page = page
request.limit = capacity
request.notCompleted = false
let method = lookUp
gRPCRequest.fetch(method: method, reqeust: request)
}
//위의 @escaping completion 비동기 처리를 RxSwift Single로 처리해준 모습
func lookUpRequestRxSingle(userId: String,
keyword: String) -> Single<Search_V1_LookUpResponse> {
return Single<Search_V1_LookUpResponse>.create { single in
self.lookUpRequest(userId: userId, keyword: keyword) { result in
switch result {
case let .success(data):
single(.success(data))
case let .failure(error):
single(.failure(error))
}
}
return Disposables.create()
}
.subscribe(on: ConcurrentDispatchQueueScheduler(qos: .default))
.observe(on: MainScheduler.instance)
}
변경 된 코드 (async await로 refactoring)
// Data - Repository - Search - search user list 함수 예시
func lookUpRequest(userId: String,
keyword: String,
page: Int32 = 1,
capacity: Int32 = 30) async throws -> Search_V1_LookUpResponse{
var request = Search_V1_LookUpRequest()
request.userID = userId
request.word = keyword
request.page = page
request.limit = capacity
request.notCompleted = false
let method = lookUp
let res = try await gRPCRequest.fetch(method: method, reqeust: request)
return res
}
+ 추가적인 gRPCRequest.fetch 함수 정의 입니다.
class grpcRequestUtil {
static let shared = grpcRequestUtil()
private init() { }
static func fetch<T,R,C>(method: (T,C?) -> UnaryCall<T,R>, reqeust: T, completion: @escaping (Result<R, Error>) -> Void) {
let call = method(reqeust, nil)
do{
// let startTime = CFAbsoluteTimeGetCurrent()
// print("grpc req success: \\(type(of: T.self)) : \\(reqeust)")
let res = try call.response.wait()
// print("grpc res success: \\(type(of: R.self)) : \\(res)")
// let durationTime = CFAbsoluteTimeGetCurrent() - startTime
// print("grpc duration time \\(type(of: R.self)) : \\(durationTime)")
completion(.success(res))
}catch {
// print("grpc res failure: \\(type(of: R.self))")
completion(.failure(error))
}
}
모든 gRPC 통신 API 함수가
let res = method(request,nil).response.wait() 가 이루어지는데 (method, request - 변하는 값)
모든 함수의 비동기 처리 시간 측정을 제어하고자 추론 타입 함수(Generic func type)으로 구현
위에서 정의한
Data - Repository의 Search API를
ViewModel 에서 함수를 사용할때 코드 입니다
기존 코드 (ViewModel)
// search user list
func fetchSearchUserList(userId: String, keyword: String) {
let searchProto = searchProto(channel: self.channel)
searchProto.lookUpRequestRxSingle(userId: userId, keyword: keyword)
.subscribe { [unowned self] res in
self.input.searchUserList.onNext(res.format.users)
} onFailure: { err in
debugPrint("🔵fetchSearchUserList err : \\(err)")
self.input.searchUserList.onNext([])
} onDisposed: {
// print("disposed: searchProto Channel Closed")
}
.disposed(by: disposeBag)
}
변경된 코드 (ViewModel)
// search user list
func fetchSearchUserList(userId: String, keyword: String) async {
let searchProto = SearchProto(channel: self.channel)
do {
let res = try await searchProto.lookUpRequest(userId: userId, keyword: keyword)
input.searchUserList.onNext(res.format.users)
} catch {
debugPrint("🔵fetchSearchUserList err : \\(error)")
}
}
특이사항 - ARC관련해서 self capture 불필요 (self.input.searchUserList → input.searchUserList)
escaping completion 내부 변수 접근 메모리 할당 관련해서
비동기 호출 리턴이 완료되면 클로져 자동 해제 → 따로 weak self 처럼 순환 참조 처리x
async await 의 weak self 관련 참조
https://stackoverflow.com/questions/71728943/async-await-task-and-weak-self
+ 추가적으로
Task 문법을 사용하여 비동기 함수들을 동기로 처리하기가 쉽다.
Task {
let a = await 비동기함수1()
let b = await 비동기함수2(a)
let c = await 비동기함수3(b)
return c
}
간단하게 작성하자면 이런식으로 비동기 함수를 동기형태로 처리 가능하다. (기존에는 콜백의 콜백 형태로 구현)
- Total
- Today
- Yesterday
- chatgpt rag llm
- rag 기반 llm
- llm csv
- rag llm pdf
- swift urlsession refactoring
- swift excel read
- swift urlcomponent encode
- swift filemanager get excel
- swift network module
- 엔디소프트 레이세이
- rag 기반 llm 챗봇
- readysay
- swift urlsession module
- swift queryitem encode
- swift 엑셀 가져오기
- swift network refactoring
- swift 엑셀 읽기
- swift 자간
- swift 네트워크 모듈화
- swift get excel
- llm pdf rag
- deep timer
- swift network 공통화
- swift urlsession 공통화
- swift filemanager excel
- swift urlsession network module
- focus timer 어플
- 레디세이 어플
- filemanager excel read
- 레디세이
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |