Skip to content

Commit

Permalink
#28 #115 #170 #189 feat: 다이어리 작성하여 서버에 업로드 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
LEEYOONJONG committed Dec 8, 2022
1 parent b8ffcc1 commit 8732f6d
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 54 deletions.
12 changes: 12 additions & 0 deletions Segno/Segno.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
9825F41D29377ACF005F2163 /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9825F41C29377ACF005F2163 /* SettingsRepository.swift */; };
982A2A472924AE74006F6ACD /* UserDefaultsKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982A2A462924AE74006F6ACD /* UserDefaultsKey.swift */; };
982A3699292C905300FDC6CF /* DiaryDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982A3698292C905300FDC6CF /* DiaryDetailViewController.swift */; };
982A4FBF2941F1CA005AEB1D /* NewDiaryDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982A4FBE2941F1CA005AEB1D /* NewDiaryDetail.swift */; };
982A4FC12941F481005AEB1D /* NewDiaryPostEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982A4FC02941F481005AEB1D /* NewDiaryPostEndpoint.swift */; };
982A4FC32941F580005AEB1D /* NewDiaryDetailDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982A4FC22941F580005AEB1D /* NewDiaryDetailDTO.swift */; };
982B3B7F292E68FB0077A44B /* DiaryDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982B3B7E292E68FB0077A44B /* DiaryDetailViewModel.swift */; };
9838443E29387C0A00BCCEE2 /* ChangeNicknameEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9838443D29387C0A00BCCEE2 /* ChangeNicknameEndpoint.swift */; };
983AE9D22934F041006547BD /* NicknameCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 983AE9D12934F041006547BD /* NicknameCell.swift */; };
Expand Down Expand Up @@ -186,6 +189,9 @@
9825F41C29377ACF005F2163 /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = "<group>"; };
982A2A462924AE74006F6ACD /* UserDefaultsKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsKey.swift; sourceTree = "<group>"; };
982A3698292C905300FDC6CF /* DiaryDetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiaryDetailViewController.swift; sourceTree = "<group>"; };
982A4FBE2941F1CA005AEB1D /* NewDiaryDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewDiaryDetail.swift; sourceTree = "<group>"; };
982A4FC02941F481005AEB1D /* NewDiaryPostEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewDiaryPostEndpoint.swift; sourceTree = "<group>"; };
982A4FC22941F580005AEB1D /* NewDiaryDetailDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewDiaryDetailDTO.swift; sourceTree = "<group>"; };
982B3B7E292E68FB0077A44B /* DiaryDetailViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiaryDetailViewModel.swift; sourceTree = "<group>"; };
9838443D29387C0A00BCCEE2 /* ChangeNicknameEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeNicknameEndpoint.swift; sourceTree = "<group>"; };
983AE9D12934F041006547BD /* NicknameCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NicknameCell.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -302,6 +308,7 @@
children = (
4FEBFAAA291CF30E00E78139 /* DiaryListItem.swift */,
4FEBFAAC291CF62E00E78139 /* DiaryDetail.swift */,
982A4FBE2941F1CA005AEB1D /* NewDiaryDetail.swift */,
4FEBFAAE291CF9F300E78139 /* MusicInfo.swift */,
4F6F74B0292C9BF3007E7AC1 /* UserInfo.swift */,
98FDF8A0292F56580083FA05 /* Location.swift */,
Expand Down Expand Up @@ -466,6 +473,7 @@
4FA324252923600C00DB04D5 /* DiaryListDTO.swift */,
4F4E0D73292521D0005ABA8F /* UserInfoDTO.swift */,
7940FB2E292E063100276EFC /* DiaryDetailDTO.swift */,
982A4FC22941F580005AEB1D /* NewDiaryDetailDTO.swift */,
4F4E0D7A29252526005ABA8F /* TokenDTO.swift */,
66A8CF6A2937947A00C17F84 /* UserDetailDTO.swift */,
791529DB29332CF2005A8DDB /* ImageDTO.swift */,
Expand All @@ -480,6 +488,7 @@
4FA3242A2923646F00DB04D5 /* DiaryListItemEndpoint.swift */,
7940FB30292E065100276EFC /* DiaryDetailEndpoint.swift */,
791529DF293344E8005A8DDB /* DiaryPostEndpoint.swift */,
982A4FC02941F481005AEB1D /* NewDiaryPostEndpoint.swift */,
79767E63293E2A1200E489DD /* DiaryDeleteEndpoint.swift */,
4F4E0D7529252236005ABA8F /* LoginEndpoint.swift */,
66A8CF6C29379A9900C17F84 /* UserDetailEndpoint.swift */,
Expand Down Expand Up @@ -633,6 +642,7 @@
9825F41D29377ACF005F2163 /* SettingsRepository.swift in Sources */,
66F0D7EE2925FF8B0074872E /* DiaryCell.swift in Sources */,
79767E64293E2A1200E489DD /* DiaryDeleteEndpoint.swift in Sources */,
982A4FC32941F580005AEB1D /* NewDiaryDetailDTO.swift in Sources */,
4F307A482938832900FA36A0 /* MusicSession.swift in Sources */,
4F9A00202922337F007D9057 /* LoginViewController.swift in Sources */,
982A2A472924AE74006F6ACD /* UserDefaultsKey.swift in Sources */,
Expand All @@ -648,6 +658,7 @@
98003E0E293F20F6009FBC35 /* DarkModeManager.swift in Sources */,
66A8CF692937945300C17F84 /* UserDetailUseCase.swift in Sources */,
988414AE2922235B007C9132 /* LocalUtilityRepository.swift in Sources */,
982A4FC12941F481005AEB1D /* NewDiaryPostEndpoint.swift in Sources */,
66A8CF612935F44100C17F84 /* MyPageViewModel.swift in Sources */,
98138D4D2940F53F00D2CEDF /* LocationUseCase.swift in Sources */,
988414D929235345007C9132 /* DiaryCollectionViewModel.swift in Sources */,
Expand Down Expand Up @@ -707,6 +718,7 @@
4F4E0D7629252236005ABA8F /* LoginEndpoint.swift in Sources */,
791529D82932F364005A8DDB /* DiaryEditUseCase.swift in Sources */,
4FA324262923600C00DB04D5 /* DiaryListDTO.swift in Sources */,
982A4FBF2941F1CA005AEB1D /* NewDiaryDetail.swift in Sources */,
666E6F87291CF4B400CECD4B /* DiaryCoordinator.swift in Sources */,
4F31777F291BE4710019BDFC /* SceneDelegate.swift in Sources */,
4F307A4629387C1100FA36A0 /* ShazamSession.swift in Sources */,
Expand Down
31 changes: 31 additions & 0 deletions Segno/Segno/Data/Network/Endpoints/NewDiaryPostEndpoint.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// NewDiaryPostEndpoint.swift
// Segno
//
// Created by YOONJONG on 2022/12/08.
//

import Foundation

enum NewDiaryPostEndpoint: Endpoint {
case item(NewDiaryDetail)

var baseURL: URL? {
return URL(string: BaseURL.urlString)
}

var httpMethod: HTTPMethod {
return .POST
}

var path: String {
return "diary"
}

var parameters: HTTPRequestParameter? {
switch self {
case .item(let diary):
return HTTPRequestParameter.body(diary)
}
}
}
1 change: 1 addition & 0 deletions Segno/Segno/Data/Network/NetworkManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct NetworkManager {
observer(.success(data))
} else {
// TODO: 서버에서 설정하는 에러 코드에 따라 에러 메시지 다르게 설정
print(httpResponse.statusCode)
observer(.failure(NetworkError.invalidNetworkStatusCode))
}
}
Expand Down
26 changes: 26 additions & 0 deletions Segno/Segno/Data/Repository/DTO/NewDiaryDetailDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// NewDiaryDetailDTO.swift
// Segno
//
// Created by YOONJONG on 2022/12/08.
//

struct NewDiaryDetailDTO: Decodable {
let token: String
let title: String
let tags: [String]
let imagePath: String
let bodyText: String?
let musicInfo: MusicInfo?
let location: Location?

init(title: String, tags: [String], imagePath: String, bodyText: String?, musicInfo: MusicInfo?, location: Location?, token: String) {
self.title = title
self.tags = tags
self.imagePath = imagePath
self.bodyText = bodyText
self.musicInfo = musicInfo
self.location = location
self.token = token
}
}
33 changes: 7 additions & 26 deletions Segno/Segno/Data/Repository/DiaryRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import RxSwift
protocol DiaryRepository {
func getDiaryListItem() -> Single<DiaryListDTO>
func getDiary(id: String) -> Single<DiaryDetailDTO>
func postDiary(_ diary: DiaryDetail, image: Data) -> Single<DiaryDetailDTO>
func postDiary(_ newDiary: NewDiaryDetail) -> Single<NewDiaryDetailDTO>
func deleteDiary(id: String) -> Single<Bool>
}

Expand All @@ -25,7 +25,7 @@ final class DiaryRepositoryImpl: DiaryRepository {
let diaryListItemDTO = try JSONDecoder().decode(DiaryListDTO.self, from: $0)
return diaryListItemDTO
}
//

// // TODO: 추후에 NetworkManager로 변경
// return Single.create { observer -> Disposable in
// let dto = DiaryListDTO.example
Expand All @@ -51,31 +51,12 @@ final class DiaryRepositoryImpl: DiaryRepository {
// }
}

func postDiary(_ diary: DiaryDetail, image: Data) -> Single<DiaryDetailDTO> {
// Dummy endpoint
func postDiary(_ newDiary: NewDiaryDetail) -> Single<NewDiaryDetailDTO> {
let newDiaryDetailEndpoint = NewDiaryPostEndpoint.item(newDiary)
print("========= repository -> ", newDiary)

let imageEndpoint = ImageEndpoint.item(image)

let single = NetworkManager.shared.call(imageEndpoint)
.compactMap {
// image 전송 후 이름 받아오기
let imageDTO = try JSONDecoder().decode(ImageDTO.self, from: $0)
return imageDTO.filename
}.map { imagePath in
// diary에 imagePath넣어 전달
return DiaryDetail(diary, imagePath: imagePath)
}.flatMap { diaryDetail in
// diary를 다시 서버에 전달
// TODO: - token 넣어야됩니당
let testDiaryDetail = DiaryDetail(diaryDetail, token: "0KjV78s0YPKbrlVP3QeAwUJcjohs2h2ysdWDLWg")

let diaryDetailEndpoint = DiaryPostEndpoint.item(testDiaryDetail)

return NetworkManager.shared.call(diaryDetailEndpoint)
.map { try JSONDecoder().decode(DiaryDetailDTO.self, from: $0) }
.asObservable()
.asMaybe()
}
let single = NetworkManager.shared.call(newDiaryDetailEndpoint)
.map { try JSONDecoder().decode(NewDiaryDetailDTO.self, from: $0) }
.asObservable()
.asSingle()

Expand Down
2 changes: 0 additions & 2 deletions Segno/Segno/Data/Repository/LocationRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ extension LocationRepositoryImpl: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
debugPrint("didUpdateLocations")
if let cllocation = locations.first {
print("위도 : \(cllocation.coordinate.latitude)")
print("경도 : \(cllocation.coordinate.longitude)")
let location = Location(latitude: cllocation.coordinate.latitude, longitude: cllocation.coordinate.longitude)
getAddress(location: cllocation)
locationSubject.onNext(location)
Expand Down
21 changes: 12 additions & 9 deletions Segno/Segno/Domain/UseCase/DiaryEditUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,30 @@ import Foundation
import RxSwift

protocol DiaryEditUseCase {
func postDiary(_ diary: DiaryDetail, image: Data) -> Single<DiaryDetail>
func postDiary(_ newDiary: NewDiaryDetail) -> Single<NewDiaryDetail>
}

final class DiaryEditUseCaseImpl: DiaryEditUseCase {
let repository: DiaryRepository
let diaryRepository: DiaryRepository
let imageRepository: ImageRepository
private let disposeBag = DisposeBag()

init(repository: DiaryRepository = DiaryRepositoryImpl()) {
self.repository = repository
init(diaryRepository: DiaryRepository = DiaryRepositoryImpl(),
imageRepository: ImageRepository = ImageRepositoryImpl()) {
self.diaryRepository = diaryRepository
self.imageRepository = imageRepository
}

func postDiary(_ diary: DiaryDetail, image: Data) -> Single<DiaryDetail> {
return repository.postDiary(diary, image: image).map { dto in
DiaryDetail(
identifier: dto.id,
func postDiary(_ newDiary: NewDiaryDetail) -> Single<NewDiaryDetail> {
return diaryRepository.postDiary(newDiary).map { dto in
NewDiaryDetail(
title: dto.title,
tags: dto.tags,
imagePath: dto.imagePath,
bodyText: dto.bodyText,
musicInfo: dto.musicInfo,
location: dto.location
location: dto.location,
token: "A1lmMjb2pgNWg6ZzAaPYgMcqRv/8BOyO4U/ui6i/Ic4="
)
}
}
Expand Down
26 changes: 26 additions & 0 deletions Segno/Segno/Entity/NewDiaryDetail.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// NewDiaryDetail.swift
// Segno
//
// Created by YOONJONG on 2022/12/08.
//

struct NewDiaryDetail: Encodable {
let title: String
let tags: [String]
let imagePath: String
let bodyText: String?
let musicInfo: MusicInfo?
let location: Location?
let token: String

init(title: String, tags: [String], imagePath: String, bodyText: String?, musicInfo: MusicInfo?, location: Location?, token: String) {
self.title = title
self.tags = tags
self.imagePath = imagePath
self.bodyText = bodyText
self.musicInfo = musicInfo
self.location = location
self.token = token
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,10 @@ extension DiaryEditViewController {
dateFormatter.locale = Locale(identifier: "ko_KR")
title = dateFormatter.string(from: Date())
}
guard let bodyText = bodyTextView.text else { return }

var bodyText: String?
if bodyTextView.text == Metric.bodyPlaceholder || bodyTextView.text.isEmpty {
bodyText = nil
}
viewModel.saveDiary(title: title, body: bodyText, tags: tags, imageData: imageData)
}
}
Expand Down
52 changes: 37 additions & 15 deletions Segno/Segno/Presentation/ViewModel/DiaryEditViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ final class DiaryEditViewModel {
var diaryDetail: DiaryDetail?
// 에딧 화면에 들어갈 여러 요소들

let diaryEditUseCase: DiaryEditUseCase
let diaryDetailUseCase: DiaryDetailUseCase
let searchMusicUseCase: SearchMusicUseCase
let locationUseCase: LocationUseCase
Expand All @@ -26,10 +27,12 @@ final class DiaryEditViewModel {
var isReceivingLocation = BehaviorSubject(value: false)
var musicInfo = BehaviorSubject<MusicInfoResult?>(value: nil)

init(diaryDetailUseCase: DiaryDetailUseCase = DiaryDetailUseCaseImpl(),
init(diaryEditUseCase: DiaryEditUseCase = DiaryEditUseCaseImpl(),
diaryDetailUseCase: DiaryDetailUseCase = DiaryDetailUseCaseImpl(),
searchMusicUseCase: SearchMusicUseCase = SearchMusicUseCaseImpl(),
locationUseCase: LocationUseCase = LocationUseCaseImpl(),
imageUseCase: ImageUseCase = ImageUseCaseImpl()) {
self.diaryEditUseCase = diaryEditUseCase
self.diaryDetailUseCase = diaryDetailUseCase
self.searchMusicUseCase = searchMusicUseCase
self.locationUseCase = locationUseCase
Expand Down Expand Up @@ -89,31 +92,50 @@ final class DiaryEditViewModel {
searchMusicUseCase.stopSearching()
}


func toggleLocation() {
guard let value = try? isReceivingLocation.value() else { return }
isReceivingLocation.onNext(!value)
}

func saveDiary(title: String, body: String, tags: [String], imageData: Data) {
func saveDiary(title: String, body: String?, tags: [String], imageData: Data) {
imageUseCase.uploadImage(data: imageData)
.subscribe(onSuccess: { [weak self] imageInfo in
guard let imageName = imageInfo.filename else { return }
debugPrint(imageName)
guard let location = try? self?.locationSubject.value() else { return }
guard let musicInfoResult = try? self?.musicInfo.value() else { return }
switch musicInfoResult {
case .success(let musicInfo):
debugPrint(musicInfo)
self?.saveDiary(title: title, body: body, tags: tags, imageName: imageName, musicInfo: musicInfo, location: location)
case .failure(let error):
debugPrint(error)
}
debugPrint("이미지 이름 : ", imageName)
self?.saveDiary(title: title, body: body, tags: tags, imageName: imageName)
})
.disposed(by: disposeBag)
}

func saveDiary(title: String, body: String, tags: [String], imageName: String, musicInfo: MusicInfo, location: Location) {
debugPrint("저장할 프로퍼티 : \(title), \(body), \(tags), \(imageName), \(musicInfo), \(location)")
func saveDiary(title: String, body: String?, tags: [String], imageName: String) {
let location = try? locationSubject.value()
var newDiary: NewDiaryDetail
// music data가 있는 경우
if let musicInfoResult = try? musicInfo.value(),
let musicInfo = try? musicInfoResult.get() {
newDiary = NewDiaryDetail(title: title,
tags: tags,
imagePath: imageName,
bodyText: body,
musicInfo: musicInfo,
location: location,
token: "A1lmMjb2pgNWg6ZzAaPYgMcqRv/8BOyO4U/ui6i/Ic4=")
}
// music data가 없는 경우
else {
newDiary = NewDiaryDetail(title: title,
tags: tags,
imagePath: imageName,
bodyText: body,
musicInfo: nil,
location: location,
token: "A1lmMjb2pgNWg6ZzAaPYgMcqRv/8BOyO4U/ui6i/Ic4=")
}

diaryEditUseCase.postDiary(newDiary)
.subscribe(onSuccess: { newDiaryDetail in
debugPrint("전송 성공, 결과 : ", newDiaryDetail)
})
.disposed(by: disposeBag)
}
}

0 comments on commit 8732f6d

Please sign in to comment.