-
Notifications
You must be signed in to change notification settings - Fork 0
[Add] #35 - Auth Endpoint, Token 관리 로직 및 타입 구현 #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
6de59de
9aca394
e412f09
52c11c6
26ba2d5
5f9055d
a764ecd
124b33f
2648007
65d030b
3d2ac2d
7203103
e7f39a9
e3eb7f5
f24095a
81d02e6
e04872b
3fbccad
01c7a52
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| // | ||
| // Multipart.swift | ||
| // Neki-iOS | ||
| // | ||
| // Created by SwainYun on 1/14/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| fileprivate extension Data { | ||
| mutating func append(_ string: String) throws { | ||
| guard let data = string.data(using: .utf8) else { throw MultipartError.unsupportedValueType } | ||
| append(data) | ||
| } | ||
| } | ||
|
|
||
| public protocol MultipartItem { | ||
| func append(to builder: inout MultipartItemBuilder) throws | ||
| } | ||
|
|
||
| public enum MultipartError: Error { | ||
| case unsupportedValueType | ||
| case invalidBody | ||
| } | ||
|
|
||
| /// 단순한 키-값 파라미터 멀티파트 아이템 | ||
| public struct MultipartFormField: MultipartItem { | ||
| let name: String | ||
| let value: Any | ||
|
|
||
| public func append(to builder: inout MultipartItemBuilder) throws { | ||
| let stringValue: String | ||
|
|
||
| switch value { | ||
| case let string as String: stringValue = string | ||
| case let int as Int: stringValue = String(int) | ||
| case let bool as Bool: stringValue = bool ? "true" : "false" | ||
| case let double as Double: stringValue = String(double) | ||
| // TODO: Date 등 다양한 타입 지원이 필요하면 이곳에 케이스 추가 | ||
| default: throw MultipartError.unsupportedValueType | ||
| } | ||
|
|
||
| try builder.append(value: stringValue, name: name) | ||
| } | ||
| } | ||
|
Comment on lines
+27
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. public struct의 프로퍼티에 public 접근자가 누락되었습니다.
🔧 수정 제안 /// 단순한 키-값 파라미터 멀티파트 아이템
public struct MultipartFormField: MultipartItem {
- let name: String
- let value: Any
+ public let name: String
+ public let value: Any
+
+ public init(name: String, value: Any) {
+ self.name = name
+ self.value = value
+ }
public func append(to builder: inout MultipartItemBuilder) throws {🧰 Tools🪛 SwiftLint (0.57.0)[Warning] 39-39: TODOs should be resolved (Date 등 다양한 타입 지원이 필요하면 이곳에 케이스...) (todo) 🤖 Prompt for AI Agents |
||
|
|
||
| /// 파일 데이터 멀티파트 아이템 | ||
| public struct MultipartFile: MultipartItem { | ||
| let name: String | ||
| let data: Data | ||
| let fileName: String | ||
| let mimeType: String | ||
|
|
||
| public func append(to builder: inout MultipartItemBuilder) throws { | ||
| try builder.append(data: data, name: name, fileName: fileName, mimeType: mimeType) | ||
| } | ||
| } | ||
|
Comment on lines
+48
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 동일한 접근자 누락 문제
🔧 수정 제안 /// 파일 데이터 멀티파트 아이템
public struct MultipartFile: MultipartItem {
- let name: String
- let data: Data
- let fileName: String
- let mimeType: String
+ public let name: String
+ public let data: Data
+ public let fileName: String
+ public let mimeType: String
+
+ public init(name: String, data: Data, fileName: String, mimeType: String) {
+ self.name = name
+ self.data = data
+ self.fileName = fileName
+ self.mimeType = mimeType
+ }
public func append(to builder: inout MultipartItemBuilder) throws {🤖 Prompt for AI Agents |
||
|
|
||
| public struct MultipartItemBuilder { | ||
| private let boundary: String | ||
| private var body = Data() | ||
|
|
||
| public init(boundary: String) { self.boundary = boundary } | ||
|
|
||
| /// 일반 텍스트 파라미터 추가 | ||
| public mutating func append(value: String, name: String) throws { | ||
| try body.append("--\(boundary)\r\n") | ||
| try body.append("Content-Disposition: form-data; name=\"\(name)\"\r\n") | ||
| try body.append("\r\n") // 헤더와 본문 사이 공백 | ||
| try body.append(value) | ||
| try body.append("\r\n") | ||
| } | ||
|
|
||
| /// 파일 데이터(이미지 등) 추가 | ||
| public mutating func append(data: Data, name: String, fileName: String, mimeType: String) throws { | ||
| try body.append("--\(boundary)\r\n") | ||
| try body.append("Content-Disposition: form-data; name=\"\(name)\"; filename=\"\(fileName)\"\r\n") | ||
| try body.append("Content-Type: \(mimeType)\r\n") | ||
| try body.append("\r\n") // 헤더와 본문 사이 공백 | ||
| body.append(data) | ||
| try body.append("\r\n") | ||
| } | ||
|
|
||
| /// 최종 Body 데이터 생성 (Closing Boundary 추가) | ||
| public func finalize() throws -> Data { | ||
| var finalBody = body | ||
| try finalBody.append("--\(boundary)--\r\n") // 끝을 알리는 -- 추가 | ||
| return finalBody | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // | ||
| // TokenRefresher.swift | ||
| // Neki-iOS | ||
| // | ||
| // Created by SwainYun on 1/12/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| public protocol TokenRefresher: Sendable { | ||
| var destination: Endpoint { get } | ||
|
|
||
| func refresh(provider: NetworkProvider) async throws(NetworkError) -> AuthTokens | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // | ||
| // TokenStorage.swift | ||
| // Neki-iOS | ||
| // | ||
| // Created by SwainYun on 1/12/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| public protocol TokenStorage { | ||
| typealias Query = [String: Any] | ||
|
|
||
| func store(_ tokens: AuthTokens) throws(TokenStorageError) | ||
| func fetch() throws(TokenStorageError) -> AuthTokens | ||
| func delete() throws(TokenStorageError) | ||
| } | ||
|
|
||
| public enum TokenStorageError: Error { | ||
| case unknown | ||
| case notFound | ||
| case conversionFailed | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p3
아직 API 연결한 게 없어서 변수명 자체를 바꿔도 상관없었을 것 같긴한데 코딩키를 활용하셨군여
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resultCode-status는 크게 상관이 없지만 success 필드는 false도 들어올 수 있는 Bool 타입이라서
isSuccess라는 Swift식 네이밍을 선택했습니다.