Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 클린 코드
- ios
- rxswift
- swiftUI
- tableView
- 리펙토링
- Clean Code
- clean architecture
- 리팩토링
- collectionview
- SWIFT
- UICollectionView
- 애니메이션
- Human interface guide
- Observable
- HIG
- swift documentation
- Xcode
- uitableview
- combine
- 스위프트
- Protocol
- map
- ribs
- UITextView
- uiscrollview
- RxCocoa
- MVVM
- Refactoring
- 리펙터링
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 4. Alamofire 사용 방법 - 로그 Log (EventMonitor) 본문
iOS 응용 (swift)
[iOS - swift] 4. Alamofire 사용 방법 - 로그 Log (EventMonitor)
jake-kim 2021. 10. 16. 16:111. Alamofire 사용 방법 - Network Layer 구현 (Moya 프레임워크처럼 사용하는 방법)
2. Alamofire 사용 방법 - 토큰 갱신 방법1 (Interceptor, adapt, retry)
3. Alamofire 사용 방법 - 토큰 갱신 방법2 (AuthenticationCredential, Authenticator, AuthenticationInterceptor)
4. Alamofire 사용 방법 - 로그 Log (EventMonitor)
EventMonitor
- request, response 시점에 불리는 메소드가 들어있는 프로토콜
- 구현해야할 주된 프로퍼티, 메소드는 3가지
queue 프로퍼티
/// The `DispatchQueue` onto which Alamofire's root `CompositeEventMonitor` will dispatch events. `.main` by default.
var queue: DispatchQueue { get }
- 순서대로 로깅이 이루어질 수 있도록 모든 이벤트를 queue에 담기위해 queue프로퍼티 필요
class APIEventLogger: EventMonitor {
let queue = DispatchQueue(label: "myNetworkLogger")
}
requestDidFinish(_:) 메서드
/// Event called when a `Request` finishes and response serializers are being called.
func requestDidFinish(_ request: Request)
- request가 끝나고 response가 시작될때 호출
class APIEventLogger: EventMonitor {
...
func requestDidFinish(_ request: Request) {
print("🛰 NETWORK Reqeust LOG")
print(request.description)
print(
"URL: " + (request.request?.url?.absoluteString ?? "") + "\n"
+ "Method: " + (request.request?.httpMethod ?? "") + "\n"
+ "Headers: " + "\(request.request?.allHTTPHeaderFields ?? [:])" + "\n"
)
print("Authorization: " + (request.request?.headers["Authorization"] ?? ""))
print("Body: " + (request.request?.httpBody?.toPrettyPrintedString ?? ""))
}
}
request<Value>(_:didParseResponse:)
/// Event called when a `DataRequest` calls a `ResponseSerializer` and creates a generic `DataResponse<Value, AFError>`.
func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value, AFError>)
- 응답을 받은 경우 호출
class APIEventLogger: EventMonitor {
...
func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value, AFError>) {
print("🛰 NETWORK Response LOG")
print(
"URL: " + (request.request?.url?.absoluteString ?? "") + "\n"
+ "Result: " + "\(response.result)" + "\n"
+ "StatusCode: " + "\(response.response?.statusCode ?? 0)" + "\n"
+ "Data: \(response.data?.toPrettyPrintedString ?? "")"
)
}
}
- APIEventLogger 전체 코드
import Alamofire
class APIEventLogger: EventMonitor {
let queue = DispatchQueue(label: "myNetworkLogger")
func requestDidFinish(_ request: Request) {
print("🛰 NETWORK Reqeust LOG")
print(request.description)
print(
"URL: " + (request.request?.url?.absoluteString ?? "") + "\n"
+ "Method: " + (request.request?.httpMethod ?? "") + "\n"
+ "Headers: " + "\(request.request?.allHTTPHeaderFields ?? [:])" + "\n"
)
print("Authorization: " + (request.request?.headers["Authorization"] ?? ""))
print("Body: " + (request.request?.httpBody?.toPrettyPrintedString ?? ""))
}
func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value, AFError>) {
print("🛰 NETWORK Response LOG")
print(
"URL: " + (request.request?.url?.absoluteString ?? "") + "\n"
+ "Result: " + "\(response.result)" + "\n"
+ "StatusCode: " + "\(response.response?.statusCode ?? 0)" + "\n"
+ "Data: \(response.data?.toPrettyPrintedString ?? "")"
)
}
}
extension Data {
var toPrettyPrintedString: String? {
guard let object = try? JSONSerialization.jsonObject(with: self, options: []),
let data = try? JSONSerialization.data(withJSONObject: object, options: [.prettyPrinted]),
let prettyPrintedString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else { return nil }
return prettyPrintedString as String
}
}
Session을 새로 생성
- session객체를 만들때 eventMonitors 객체를 주입해주기 위해서 session객체를 새로 생성
- request를 요청할 땐 보통 AF.request()로 사용하지만, session객체를 이용
- 기존의 AF는 Session.default를 보고있는 형태이므로 session을 새로만들어서 사용해도 무방
- Session생성
class API {
static let session: Session = {
let configuration = URLSessionConfiguration.af.default
let apiLogger = APIEventLogger()
return Session(configuration: configuration, eventMonitors: [apiLogger])
}()
}
- API호출 정의: AF.request가 아닌 위에서 정의한 API.session.request()로 접근
// PredictAgeAPI.swift
/// 이름과 패스워드로 로그인 + EventLogger 이용
static func predictWithEventLogger(request: PredictAgeRequest, completion: @escaping (_ succeed: Person?, _ failed: Error?) -> Void) {
API.session.request(PredictAgeTarget.predict(request), interceptor: MyRequestInterceptor())
.responseDecodable { (response: AFDataResponse<PredictAgeResponse>) in
switch response.result {
case .success(let response):
completion(response.toDomain, nil)
case .failure(let error):
completion(nil, error)
}
}
}
사용
@IBAction func didTapCallAPIButton(_ sender: Any) {
let request = PredictAgeRequest(name: textField.text ?? "")
PredictAgeAPI.predictWithEventLogger(request: request) { [weak self] succeed, failed in
guard let succeed = succeed else { return }
self?.label.text = "\(succeed.name)이름, 예측 = \(succeed.age)살"
}
}
- API호출 시 로그 결과
* 전체 소스 코드
https://github.com/JK0369/ExAlamofire
* 참고
https://alamofire.github.io/Alamofire/Protocols/EventMonitor.html
'iOS 응용 (swift)' 카테고리의 다른 글
Comments