URLSession의 요청이 많아지다보니 공통화를 하고싶어서 Generic에 손을 댔는데
생각지도 못한 오류 때문에 시간을 많이 잡아 먹었다.
해결책도 사실 근본적인 해결책이라고 볼 순 없지만.. 적어놓고 나중에 완전히 이해되면 다시 볼 생각으로 글을 적어보려고한다.
오류상황
현재 NetworkManager에 모든 URLSession 작업과 Encode, Decode 함수를 넣어놨는데
Decode 함수를 제네릭으로 만들고 request 함수에서 호출하려고 보니 오류가 발생했다.
처음으로 발생한 오류 : 일반 매개변수 T를 유추할 수 없습니다.
Generic parameter 'T' could not be inferred
private func decode<T: Decodable>(data: Data?) -> T? {
let decoder = JSONDecoder()
guard let data = data else { return nil }
do {
return try decoder.decode(T.self, from: data)
} catch {
print(error.localizedDescription)
}
return nil
}
private func request<T: Decodable>(requestType: RequestType,
url: URL,
data: Data? = nil,
completion: @escaping (T) -> Void) {
let request = makeRequest(requestType: requestType, url: url, data: data)
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Network Error: \(error.localizedDescription)")
return
}
guard let response = response as? HTTPURLResponse, (200 ..< 299) ~= response.statusCode else {
print("Error: HTTP request failed")
return
}
if let data = data,
let decodedData = self.decode(data: data) { // 오류발생 !
completion(decodedData)
}
}.resume()
}
그래서 생각한 해결책
if let data = data,
let decodedData = self.decode(data: data) {
completion(decodedData)
}
----->
if let data = data,
let decodedData = self.decode<T>(data: data) {
completion(decodedData)
}
오류 : 일반 함수를 명시적으로 특수화할 수 없습니다.
Cannot explicitly specialize a generic function
ㅇㅅㅇ?
if let data = data,
let decodedData = self.decode<T>(data: data) {
completion(decodedData)
}
if let data = data,
let decodedData = self.decode<User>(data: data) {
completion(decodedData)
}
if let data = data,
let decodedData = self.decode<User.self>(data: data) {
completion(decodedData)
}
if let data = data,
let decodedData = self.decode<User.Type>(data: data) {
completion(decodedData)
}
그래서 잠시 별짓을 다해봤는데 안돼서 열심히 구글링을 한 결과..
https://codegrepr.com/question/cannot-explicitly-specialize-a-generic-function/
Cannot explicitly specialize a generic function - Codegrepr
I have issue with following code: func generic1<T>(name : String){ } func generic2<T>(name : String){ generic1<T>(name) } the
codegrepr.com
여기서 설명과 해결책을 주었는데
최소한 매개변수나 반환값에 T를 사용하거나 타입을 명시해주어야한다..? 여서
매개변수에 type을 지정하게 해주니 오류가 사라졌다.
제네릭을 다시 상세하게 문서를 찾아봐야겠다..
private func decode<T: Decodable>(data: Data?, type: T.Type) -> T? {
let decoder = JSONDecoder()
guard let data = data else { return nil }
do {
return try decoder.decode(T.self, from: data)
} catch {
print(error.localizedDescription)
}
return nil
}
private func request<T: Decodable>(genericType: T.Type,
requestType: RequestType,
url: URL,
data: Data? = nil,
completion: @escaping (T) -> Void) {
let request = makeRequest(requestType: requestType, url: url, data: data)
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Network Error: \(error.localizedDescription)")
return
}
guard let response = response as? HTTPURLResponse, (200 ..< 299) ~= response.statusCode else {
print("Error: HTTP request failed")
return
}
if let data = data,
let decodedData = self.decode(data: data, type: T.self) {
completion(decodedData)
}
}.resume()
}
'iOS > STUDY' 카테고리의 다른 글
Figma-export로 color, icon, image, typography를 자동으로 export 해보기 (4) | 2023.02.16 |
---|---|
[iOS] NSCache (0) | 2022.12.04 |
[iOS] UITabBarController, UITabBar (0) | 2022.09.01 |
[iOS] Static, Dynamic Library, Framework (0) | 2022.06.20 |
[iOS] Compositional Layout 에 관하여 (2) | 2022.06.03 |