Skip to content

Commit

Permalink
Merge pull request #315 from boostcampwm2023/iOS/feat#299
Browse files Browse the repository at this point in the history
feat: 프로필 뷰에서 업로드 중인 영상 로딩 처리, 각종 버그 수정
  • Loading branch information
loinsir authored Dec 13, 2023
2 parents 355f972 + 36b3bfb commit dfc5027
Show file tree
Hide file tree
Showing 23 changed files with 213 additions and 86 deletions.
1 change: 1 addition & 0 deletions iOS/Layover/Layover/Models/Board.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ struct Board {
let videoURL: URL?
let latitude: Double
let longitude: Double
let status: BoardStatus
}
25 changes: 24 additions & 1 deletion iOS/Layover/Layover/Network/DTOs/BoardDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,34 @@ struct BoardDTO: Decodable {
let videoThumbnailURL: String
let latitude, longitude: Double
let title, content: String
let status: BoardStatus

enum CodingKeys: String, CodingKey {
case id
case encodedVideoURL = "encoded_video_url"
case videoThumbnailURL = "video_thumbnail_url"
case latitude, longitude, title, content
case status
}
}

enum BoardStatus: String, Decodable {
case running
case waiting
case failure
case complete
case deleted
case inactive

init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawValue = try container.decode(String.self)

if let value = BoardStatus(rawValue: rawValue.lowercased()) {
self = value
} else {
self = .inactive
}
}
}

Expand All @@ -32,7 +54,8 @@ extension BoardDTO {
thumbnailImageURL: URL(string: videoThumbnailURL),
videoURL: URL(string: encodedVideoURL),
latitude: latitude,
longitude: longitude
longitude: longitude,
status: status
)
}
}
15 changes: 10 additions & 5 deletions iOS/Layover/Layover/Network/Mock/MockData/PostList.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"longitude" : 37.0532156213,
"latitude" : 127.060123123,
"title" : "최강 아이돌",
"content" : "게시글 설명"
"content" : "게시글 설명",
"status": "COMPLETE"
},
"tag" : ["나도몰라요", "너도몰라요"]
},
Expand All @@ -34,7 +35,8 @@
"longitude" : 37.0532156213,
"latitude" : 127.060123123,
"title" : "프로듀스 101",
"content" : "게시글 설명"
"content" : "게시글 설명",
"status": "COMPLETE"
},
"tag" : ["해시태그", "해시태그2"]
},
Expand All @@ -52,7 +54,8 @@
"longitude" : 37.0532156213,
"latitude" : 127.060123123,
"title" : "프로미스 나인",
"content" : "게시글 설명"
"content" : "게시글 설명",
"status": "COMPLETE"
},
"tag" : ["해시태그1", "해시태그2"]
},
Expand All @@ -70,7 +73,8 @@
"longitude" : 37.0532156213,
"latitude" : 127.060123123,
"title" : "아이즈원",
"content" : "게시글 설명2"
"content" : "게시글 설명2",
"status": "COMPLETE"
},
"tag" : ["해시태그1", "해시태그6"]
},
Expand All @@ -88,7 +92,8 @@
"longitude" : 37.0532156213,
"latitude" : 127.060123123,
"title" : "아이즈원",
"content" : "게시글 설명2"
"content" : "게시글 설명2",
"status": "COMPLETE"
},
"tag" : ["해시태그1", "해시태그6"]
}
Expand Down
12 changes: 8 additions & 4 deletions iOS/Layover/Layover/Network/Mock/MockData/PostListMore.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"longitude" : 37.0532156213,
"latitude" : 127.060123123,
"title" : "최강 아이돌",
"content" : "게시글 설명"
"content" : "게시글 설명",
"status": "COMPLETE"
},
"tag" : ["나도몰라요", "너도몰라요"]
},
Expand All @@ -34,7 +35,8 @@
"longitude" : 37.0532156213,
"latitude" : 127.060123123,
"title" : "프로듀스 101",
"content" : "게시글 설명"
"content" : "게시글 설명",
"status": "COMPLETE"
},
"tag" : ["해시태그", "해시태그2"]
},
Expand All @@ -52,7 +54,8 @@
"longitude" : 37.0532156213,
"latitude" : 127.060123123,
"title" : "프로미스 나인",
"content" : "게시글 설명"
"content" : "게시글 설명",
"status": "COMPLETE"
},
"tag" : ["해시태그1", "해시태그2"]
},
Expand All @@ -70,7 +73,8 @@
"longitude" : 37.0532156213,
"latitude" : 127.060123123,
"title" : "아이즈원",
"content" : "게시글 설명2"
"content" : "게시글 설명2",
"status": "COMPLETE"
},
"tag" : ["해시태그1", "해시태그6"]
}
Expand Down
32 changes: 17 additions & 15 deletions iOS/Layover/Layover/Scenes/EditProfile/EditProfileInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,22 +141,24 @@ final class EditProfileInteractor: EditProfileBusinessLogic, EditProfileDataStor
return false
}

// 이미지 변경 시도
if let profileImageData = request.profileImageData, let profileImageExtension = request.profileImageExtension {
guard await profileImageEditRequest(into: profileImageData, fileExtension: profileImageExtension) else {
await MainActor.run {
presenter?.presentProfile(with: Models.EditProfile.Response(isSuccess: false))
// 이미지 변경 요청
if request.changeProfileImageNeeded {
if let profileImageData = request.profileImageData, let profileImageExtension = request.profileImageExtension {
guard await profileImageEditRequest(into: profileImageData, fileExtension: profileImageExtension) else {
await MainActor.run {
presenter?.presentProfile(with: Models.EditProfile.Response(isSuccess: false))
}
return false
}
return false
}
} else { // 이미지 변경이 없는 경우 이미지 삭제 시도
guard await userWorker?.setProfileImageDefault() == true else {
await MainActor.run {
presenter?.presentProfile(with: Models.EditProfile.Response(isSuccess: false))
} else { // 이미지 데이터 없는 경우 이미지 삭제 시도
guard await userWorker?.setProfileImageDefault() == true else {
await MainActor.run {
presenter?.presentProfile(with: Models.EditProfile.Response(isSuccess: false))
}
return false
}
return false
profileImageData = nil
}
profileImageData = nil
}

await MainActor.run {
Expand All @@ -168,7 +170,7 @@ final class EditProfileInteractor: EditProfileBusinessLogic, EditProfileDataStor

private func nicknameEditRequest(into nickname: String) async -> Bool {
if self.nickname != nickname {
guard let response = await userWorker?.modifyNickname(to: nickname) else {
guard await userWorker?.modifyNickname(to: nickname) != nil else {
os_log(.error, log: .data, "Edit Profile Error")
return false
}
Expand All @@ -178,7 +180,7 @@ final class EditProfileInteractor: EditProfileBusinessLogic, EditProfileDataStor
}

private func introduceEditRequest(into introduce: String?) async -> Bool {
guard let modifyIntroduceResponse = await userWorker?.modifyIntroduce(to: introduce ?? "") else {
guard await userWorker?.modifyIntroduce(to: introduce ?? "") != nil else {
os_log(.error, log: .data, "Edit Profile Error")
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ enum EditProfileModels {
struct Request {
let nickname: String
let introduce: String?
let changeProfileImageNeeded: Bool
let profileImageData: Data?
let profileImageExtension: String?
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ final class EditProfileViewController: BaseViewController {
guard let self else { return }
self.changedProfileImageData = nil
self.changedProfileImageExtension = nil
self.changeProfileImageNeeded = true
self.profileImageView.image = UIImage.profile
self.profileImageDataChanged()
}
Expand All @@ -114,6 +115,7 @@ final class EditProfileViewController: BaseViewController {
var interactor: EditProfileBusinessLogic?

private var isValidNickname = true
private var changeProfileImageNeeded = false
private var changedProfileImageData: Data?
private var changedProfileImageExtension: String?

Expand Down Expand Up @@ -223,6 +225,7 @@ final class EditProfileViewController: BaseViewController {

let request = Models.EditProfile.Request(nickname: nickname,
introduce: introduce,
changeProfileImageNeeded: changeProfileImageNeeded,
profileImageData: changedProfileImageData,
profileImageExtension: changedProfileImageExtension)
showLoading()
Expand Down Expand Up @@ -252,6 +255,7 @@ extension EditProfileViewController: PHPickerViewControllerDelegate {
self.profileImageView.image = UIImage(contentsOfFile: temporaryCopyFileURL.path())
self.changedProfileImageExtension = pathExtension
self.changedProfileImageData = try? Data(contentsOf: temporaryCopyFileURL)
self.changeProfileImageNeeded = true
self.profileImageDataChanged()
}
try FileManager.default.removeItem(at: temporaryCopyFileURL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ final class ProfileConfigurator: Configurator {
func configure(_ viewController: ViewController) {
let viewController = viewController
let interactor = ProfileInteractor()
// let worker = MockUserWorker()
let worker = UserWorker()
let presenter = ProfilePresenter()
let router = ProfileRouter()
Expand Down
15 changes: 8 additions & 7 deletions iOS/Layover/Layover/Scenes/Profile/ProfileInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ final class ProfileInteractor: ProfileBusinessLogic, ProfileDataStore {
func fetchProfile(with request: ProfileModels.FetchProfile.Request) -> Task<Bool, Never> {
fetchPostsPage = 1
canFetchMorePosts = true
posts = []

return Task {
guard let userProfile = await userWorker?.fetchProfile(by: profileId) else {
return false
}
posts = []
nickname = userProfile.username
introduce = userProfile.introduce

Expand All @@ -76,7 +77,7 @@ final class ProfileInteractor: ProfileBusinessLogic, ProfileDataStore {
let response = Models.FetchProfile.Response(userProfile: ProfileModels.Profile(username: userProfile.username,
introduce: userProfile.introduce,
profileImageData: imageData),
posts: posts)
displayedPosts: posts)
await MainActor.run {
presenter?.presentProfile(with: response)
}
Expand All @@ -96,7 +97,7 @@ final class ProfileInteractor: ProfileBusinessLogic, ProfileDataStore {
return false
}

let response = Models.FetchMorePosts.Response(posts: fetchedPosts)
let response = Models.FetchMorePosts.Response(displayedPosts: fetchedPosts)

await MainActor.run {
presenter?.presentMorePosts(with: response)
Expand All @@ -106,22 +107,22 @@ final class ProfileInteractor: ProfileBusinessLogic, ProfileDataStore {
}
}

private func fetchPosts() async -> [Models.Post] {
private func fetchPosts() async -> [Models.DisplayedPost] {
guard let fetchedPosts = await userWorker?.fetchPosts(at: fetchPostsPage, of: profileId),
fetchedPosts.count > 0 else {
return []
}
posts += fetchedPosts

var responsePosts = [Models.Post]()
var responsePosts = [Models.DisplayedPost]()
for post in fetchedPosts {
guard let thumbnailURL = post.board.thumbnailImageURL,
let profileImageData = await userWorker?.fetchImageData(with: thumbnailURL) else {
responsePosts.append(.init(id: post.board.identifier, thumbnailImageData: nil))
responsePosts.append(.init(id: post.board.identifier, thumbnailImageData: nil, status: post.board.status))
continue
}

responsePosts.append(Models.Post(id: post.board.identifier, thumbnailImageData: profileImageData))
responsePosts.append(Models.DisplayedPost(id: post.board.identifier, thumbnailImageData: profileImageData, status: post.board.status))
}

return responsePosts
Expand Down
11 changes: 6 additions & 5 deletions iOS/Layover/Layover/Scenes/Profile/ProfileModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ enum ProfileModels {
let profileImageData: Data?
}

struct Post: Hashable {
struct DisplayedPost: Hashable {
let id: Int
let thumbnailImageData: Data?
let status: BoardStatus
}

enum FetchProfile {
Expand All @@ -28,12 +29,12 @@ enum ProfileModels {

struct Response {
let userProfile: Profile
let posts: [Post]
let displayedPosts: [DisplayedPost]
}

struct ViewModel {
let userProfile: Profile
let posts: [Post]
let displayedPosts: [DisplayedPost]
}
}

Expand All @@ -42,11 +43,11 @@ enum ProfileModels {
}

struct Response {
let posts: [Post]
let displayedPosts: [DisplayedPost]
}

struct ViewModel {
let posts: [Post]
let displayedPosts: [DisplayedPost]
}
}

Expand Down
4 changes: 2 additions & 2 deletions iOS/Layover/Layover/Scenes/Profile/ProfilePresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ final class ProfilePresenter: ProfilePresentationLogic {

func presentProfile(with response: Models.FetchProfile.Response) {
let viewModel = Models.FetchProfile.ViewModel(userProfile: response.userProfile,
posts: response.posts)
displayedPosts: response.displayedPosts)
viewController?.displayProfile(viewModel: viewModel)
}

func presentMorePosts(with response: ProfileModels.FetchMorePosts.Response) {
let viewModel = Models.FetchMorePosts.ViewModel(posts: response.posts)
let viewModel = Models.FetchMorePosts.ViewModel(displayedPosts: response.displayedPosts)
viewController?.displayMorePosts(viewModel: viewModel)
}

Expand Down
Loading

0 comments on commit dfc5027

Please sign in to comment.