diff --git a/iOS/issue-tracker.xcodeproj/project.pbxproj b/iOS/issue-tracker.xcodeproj/project.pbxproj index baecc4008..140d1064e 100644 --- a/iOS/issue-tracker.xcodeproj/project.pbxproj +++ b/iOS/issue-tracker.xcodeproj/project.pbxproj @@ -44,6 +44,7 @@ B0783E742681E1830031C2FD /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0783E732681E1830031C2FD /* Color.swift */; }; B0783E772681E1DB0031C2FD /* Milestone.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0783E762681E1DB0031C2FD /* Milestone.swift */; }; B0783E7A2681E21F0031C2FD /* Issue.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0783E792681E21F0031C2FD /* Issue.swift */; }; + B0783E7D2684648C0031C2FD /* ImageResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0783E7C2684648C0031C2FD /* ImageResponse.swift */; }; BCCEBE1E1668EC814AFFBE24 /* Pods_issue_tracker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 906455FA7C42AB9BB530CE77 /* Pods_issue_tracker.framework */; }; /* End PBXBuildFile section */ @@ -91,6 +92,7 @@ B0783E732681E1830031C2FD /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; B0783E762681E1DB0031C2FD /* Milestone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Milestone.swift; sourceTree = ""; }; B0783E792681E21F0031C2FD /* Issue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Issue.swift; sourceTree = ""; }; + B0783E7C2684648C0031C2FD /* ImageResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageResponse.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -278,6 +280,7 @@ B0783E732681E1830031C2FD /* Color.swift */, B0783E762681E1DB0031C2FD /* Milestone.swift */, B0783E792681E21F0031C2FD /* Issue.swift */, + B0783E7C2684648C0031C2FD /* ImageResponse.swift */, ); path = Model; sourceTree = ""; @@ -434,6 +437,7 @@ B0783E772681E1DB0031C2FD /* Milestone.swift in Sources */, 10D55EDE2670D46E007587C4 /* AdditionalTableViewCell.swift in Sources */, B0783E742681E1830031C2FD /* Color.swift in Sources */, + B0783E7D2684648C0031C2FD /* ImageResponse.swift in Sources */, 10BDE6B52670C324007B38AF /* IssueEditViewController.swift in Sources */, 1029609E2673401E00669988 /* StoryBoardName.swift in Sources */, 10D4258526709D4800AE119C /* UIViewController+Instantiate.swift in Sources */, diff --git a/iOS/issue-tracker/IssueList/IssueListViewController.swift b/iOS/issue-tracker/IssueList/IssueListViewController.swift index 669eed69d..f11bd4b6b 100644 --- a/iOS/issue-tracker/IssueList/IssueListViewController.swift +++ b/iOS/issue-tracker/IssueList/IssueListViewController.swift @@ -17,26 +17,15 @@ class IssueListViewController: UIViewController, ReuseIdentity { coordinator?.pushEditView() } @IBAction func testGETAction(_ sender: Any) { -// getUser() + getUser() getLabel() getMilestone() getIssues() } @IBAction func testPostAction(_ sender: Any) { - NetworkService.shared.postLabel() - .subscribe(onNext: { responseLabel in - print(responseLabel) - }, - onError: { error in - print(error) - }, - onCompleted: { - print("comple") - }, - onDisposed: { - print("dispose") - }) +// postLabel() + postImage() } func getUser() { @@ -99,6 +88,48 @@ class IssueListViewController: UIViewController, ReuseIdentity { .disposed(by: disposeBag) } + func postLabel() { + let input = Label.init(id: "",name: "testDowneyName3", description: "testDowneyDescription0", colors: Color.init(backgroundColor: "#FFFFFF", textColor: "#000000")) + let observer: Observable = NetworkService.shared.post(input: input, target: .labels) + + observer + .subscribe(onNext: { responseLabel in + print(responseLabel) + }, + onError: { error in + print(error) + }, + onCompleted: { + print("comple") + }, + onDisposed: { + print("dispose") + }) + .disposed(by: disposeBag) + } + + func postImage() { + + let testInput = UIImage.init(named: "githubIcon")! + let testInput2 = UIImage.init(named: "testJPG")! + + let observer: Observable = NetworkService.shared.uploadImage(input: testInput2) + + observer.subscribe(onNext: { response in + print(response) + }, + onError: { error in + print(error) + }, + onCompleted: { + print("comple") + }, + onDisposed: { + print("disposed") + }) + .disposed(by: disposeBag) + } + override func viewDidLoad() { super.viewDidLoad() diff --git a/iOS/issue-tracker/Model/ImageResponse.swift b/iOS/issue-tracker/Model/ImageResponse.swift new file mode 100644 index 000000000..48899342a --- /dev/null +++ b/iOS/issue-tracker/Model/ImageResponse.swift @@ -0,0 +1,16 @@ +// +// ImageResponse.swift +// issue-tracker +// +// Created by 이다훈 on 2021/06/24. +// + +import Foundation + +struct ImageResponse: Codable { + let image: InnerImageResponse +} + +struct InnerImageResponse: Codable { + let url: String +} diff --git a/iOS/issue-tracker/Model/Issue.swift b/iOS/issue-tracker/Model/Issue.swift index b53c0805c..55a4f87bf 100644 --- a/iOS/issue-tracker/Model/Issue.swift +++ b/iOS/issue-tracker/Model/Issue.swift @@ -21,28 +21,20 @@ struct Issues: Codable { struct Issue: Codable { let id: Int - let author: UserForIssue? + let author: User? let title: String? let createdAt: String? let labels: [Label]? - let assignees: [UserForIssue]? + let assignees: [User]? let milestone: Milestone? let comments: [Comment] let open: Bool } -struct UserForIssue: Codable { - let id: String - let nickName: String? - let imageUrl: String? - let githubId: String? - let appleId: String? -} - struct Comment: Codable { let id: String let issueId: Int - let author: UserForIssue + let author: User let createdAt: String let content: String } diff --git a/iOS/issue-tracker/Model/User.swift b/iOS/issue-tracker/Model/User.swift index 9c3832513..cf906e271 100644 --- a/iOS/issue-tracker/Model/User.swift +++ b/iOS/issue-tracker/Model/User.swift @@ -15,4 +15,6 @@ struct User: Codable { let id: String let nickName: String? let imageUrl: String? + let githubId: String? + let appleId: String? } diff --git a/iOS/issue-tracker/Network/EndPoint.swift b/iOS/issue-tracker/Network/EndPoint.swift index eaf4587a2..944619bcf 100644 --- a/iOS/issue-tracker/Network/EndPoint.swift +++ b/iOS/issue-tracker/Network/EndPoint.swift @@ -23,6 +23,7 @@ enum APIPath: String, CustomStringConvertible { case milestones = "api/milestones" case comments = "api/comments" case issues = "api/issues" + case images = "api/images" } struct LoginEndPoint: URLConvertible { diff --git a/iOS/issue-tracker/Network/NetworkRequester.swift b/iOS/issue-tracker/Network/NetworkRequester.swift index 7ebfea6d1..4dd7b6d99 100644 --- a/iOS/issue-tracker/Network/NetworkRequester.swift +++ b/iOS/issue-tracker/Network/NetworkRequester.swift @@ -13,6 +13,8 @@ protocol NetworkRequesting { func get(endPoint: EndPoint, token: String?, parameters: [String: Codable]?) -> Observable func post(endPoint: EndPoint, token: String?, body: T) -> Observable + + func uploadImage(endPoint: EndPoint, token: String?, body: UIImage) -> Observable } class NetworkRequester: NetworkRequesting { @@ -77,4 +79,41 @@ class NetworkRequester: NetworkRequesting { } + func uploadImage(endPoint: EndPoint, token: String?, body: UIImage) -> Observable { + + let url = endPoint.urlFromEndPoint() + let accessToken = token != nil ? token! : "" + let header: HTTPHeaders = [ + .authorization(bearerToken: accessToken), + .contentType("multipart/form-data") + ] + let data = body.jpegData(compressionQuality: 0.2) + + return Observable.create({ observer in + + let uploader = AF.upload( + multipartFormData: { multipartFormData in + multipartFormData.append(data!,withName: "image",fileName: "image-downey" ,mimeType: "image/jpg") + }, + to: url, + usingThreshold: UInt64.init(), + method: .post, + headers: header) + .responseData(completionHandler: { response in + switch response.result { + case .success(let data): + let decoded = try? JSONDecoder().decode(T.self, from: data) + observer.onNext(decoded!) + case .failure(let error): + observer.onError(error) + } + }) + + return Disposables.create { + uploader.cancel() + } + + }) + } + } diff --git a/iOS/issue-tracker/Network/NetworkService.swift b/iOS/issue-tracker/Network/NetworkService.swift index 292d6cebe..1cd0d68c8 100644 --- a/iOS/issue-tracker/Network/NetworkService.swift +++ b/iOS/issue-tracker/Network/NetworkService.swift @@ -31,10 +31,15 @@ class NetworkService { return requester.get(endPoint: endPoint, token: loginToken, parameters: nil) } - func postLabel() -> Observable { - let endPoint = EndPoint.init(path: .labels, method: .post) - let input = Label.init(id: "",name: "testDowneyName3", description: "testDowneyDescription0", colors: Color.init(backgroundColor: "#FFFFFF", textColor: "#000000")) + func post(input: T, target: APIPath) -> Observable { + let endPoint = EndPoint.init(path: target, method: .post) return requester.post(endPoint: endPoint, token: loginToken, body: input) } + + func uploadImage(input: UIImage) -> Observable { + let endPoint = EndPoint.init(path: .images, method: .post) + + return requester.uploadImage(endPoint: endPoint, token: loginToken, body: input) + } } diff --git a/iOS/issue-tracker/Supporting/Assets.xcassets/testJPG.imageset/Contents.json b/iOS/issue-tracker/Supporting/Assets.xcassets/testJPG.imageset/Contents.json new file mode 100644 index 000000000..bd4a6bdb4 --- /dev/null +++ b/iOS/issue-tracker/Supporting/Assets.xcassets/testJPG.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "testJPG.jpg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/issue-tracker/Supporting/Assets.xcassets/testJPG.imageset/testJPG.jpg b/iOS/issue-tracker/Supporting/Assets.xcassets/testJPG.imageset/testJPG.jpg new file mode 100644 index 000000000..3a52a95df Binary files /dev/null and b/iOS/issue-tracker/Supporting/Assets.xcassets/testJPG.imageset/testJPG.jpg differ