Skip to content

Commit

Permalink
Merge pull request #331 from boostcampwm2023/iOS/feat#300
Browse files Browse the repository at this point in the history
feat: 영상 재추출시 업로드 에러, 지도 인코딩중 표시 및 권한 처리
  • Loading branch information
anyukyung authored Dec 14, 2023
2 parents 18cd15b + 64ce2ab commit 7ab724d
Show file tree
Hide file tree
Showing 28 changed files with 312 additions and 115 deletions.
5 changes: 5 additions & 0 deletions iOS/Layover/Layover.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@
FCEE0FF22B036B6000195BBE /* LOButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEE0FF12B036B6000195BBE /* LOButton.swift */; };
FCEE0FF62B03804000195BBE /* LOTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEE0FF52B03804000195BBE /* LOTextField.swift */; };
FCEE0FFA2B03AF8500195BBE /* SignUpViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEE0FF92B03AF8400195BBE /* SignUpViewController.swift */; };
FCF19BE22B2A4088003002E0 /* AVFileType+.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF19BE12B2A4088003002E0 /* AVFileType+.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -507,6 +508,7 @@
FCEE0FF12B036B6000195BBE /* LOButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LOButton.swift; sourceTree = "<group>"; };
FCEE0FF52B03804000195BBE /* LOTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LOTextField.swift; sourceTree = "<group>"; };
FCEE0FF92B03AF8400195BBE /* SignUpViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SignUpViewController.swift; path = ../SignUpViewController.swift; sourceTree = "<group>"; };
FCF19BE12B2A4088003002E0 /* AVFileType+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVFileType+.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -1165,6 +1167,7 @@
FC767FA42B125F430088CF9B /* UIViewController+.swift */,
1972CCDE2B14C9B000C3C762 /* Notification.Name+.swift */,
19A169482B181AE300DB34C0 /* Sequence+.swift */,
FCF19BE12B2A4088003002E0 /* AVFileType+.swift */,
19AE482D2B2A24C700DD4612 /* URL+.swift */,
);
path = Extensions;
Expand Down Expand Up @@ -1432,6 +1435,8 @@
1945520D2B0399E500299768 /* MainTabBarViewController.swift in Sources */,
FC2511AB2B04EA6B004717BC /* MapConfigurator.swift in Sources */,
1945523B2B05258200299768 /* HomeConfigurator.swift in Sources */,
FCF19BE22B2A4088003002E0 /* AVFileType+.swift in Sources */,
FC5BE11D2B148D160036366D /* EditProfileWorker.swift in Sources */,
19A1693A2B17BCC400DB34C0 /* MemberDTO.swift in Sources */,
194551F62B037F2D00299768 /* LoginViewController.swift in Sources */,
FC767FA52B125F430088CF9B /* UIViewController+.swift in Sources */,
Expand Down
25 changes: 25 additions & 0 deletions iOS/Layover/Layover/Extensions/AVFileType+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// AVFileType+.swift
// Layover
//
// Created by kong on 2023/12/14.
// Copyright © 2023 CodeBomber. All rights reserved.
//

import AVFoundation

extension AVFileType {
static func from(_ url: URL) -> AVFileType? {
let pathExtension = url.pathExtension
switch pathExtension {
case "mp4":
return .mp4
case "mov":
return .mov
case "m4v":
return .m4v
default:
return nil
}
}
}
4 changes: 2 additions & 2 deletions iOS/Layover/Layover/Extensions/URL+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ extension URL {
return components?.url ?? self
}

var customHLS_URL: URL {
var customHLSURL: URL {
changeScheme(to: "lhls")
}

var originHLS_URL: URL {
var originHLSURL: URL {
changeScheme(to: "https")
}
}
2 changes: 2 additions & 0 deletions iOS/Layover/Layover/Scenes/Home/HomeConfigurator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ final class HomeConfigurator: Configurator {
let interactor = HomeInteractor()
let homeWorker = HomeWorker()
let videoFileWorker = VideoFileWorker()
let locationManager = CurrentLocationManager()

router.viewController = viewController
router.dataStore = interactor
presenter.viewController = viewController
interactor.presenter = presenter
interactor.homeWorker = homeWorker
interactor.videoFileWorker = videoFileWorker
interactor.locationManager = locationManager
viewController.router = router
viewController.interactor = interactor

Expand Down
18 changes: 18 additions & 0 deletions iOS/Layover/Layover/Scenes/Home/HomeInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
// Copyright © 2023 CodeBomber. All rights reserved.
//

import CoreLocation
import UIKit

protocol HomeBusinessLogic {
@discardableResult
func fetchPosts(with request: HomeModels.FetchPosts.Request) async -> Bool
func playPosts(with request: HomeModels.PlayPosts.Request)
func fetchLocationAuthorizationStatus()
func selectVideo(with request: HomeModels.SelectVideo.Request)
func showTagPlayList(with request: HomeModels.ShowTagPlayList.Request)
}
Expand All @@ -33,6 +35,7 @@ final class HomeInteractor: HomeDataStore {
var videoFileWorker: VideoFileWorkerProtocol?
var homeWorker: HomeWorkerProtocol?
var presenter: HomePresentationLogic?
var locationManager: CurrentLocationManager?

// MARK: - DataStore

Expand All @@ -45,6 +48,7 @@ final class HomeInteractor: HomeDataStore {
// MARK: - Use Case

extension HomeInteractor: HomeBusinessLogic {

@discardableResult
func fetchPosts(with request: Models.FetchPosts.Request) async -> Bool {
guard let posts = await homeWorker?.fetchPosts() else { return false }
Expand All @@ -63,6 +67,20 @@ extension HomeInteractor: HomeBusinessLogic {
presenter?.presentPlaybackScene(with: Models.PlayPosts.Response())
}

func fetchLocationAuthorizationStatus() {
guard let authorizationStatus = locationManager?.getAuthorizationStatus() else { return }
switch authorizationStatus {
case .authorizedAlways, .authorizedWhenInUse:
presenter?.presentUploadScene()
case .restricted, .notDetermined:
locationManager?.requestWhenInUseAuthorization()
case .denied:
presenter?.presentSetting()
@unknown default:
return
}
}

func selectVideo(with request: Models.SelectVideo.Request) {
selectedVideoURL = videoFileWorker?.copyToNewURL(at: request.videoURL)
}
Expand Down
10 changes: 10 additions & 0 deletions iOS/Layover/Layover/Scenes/Home/HomePresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ protocol HomePresentationLogic {
func presentPosts(with response: HomeModels.FetchPosts.Response)
func presentPlaybackScene(with response: HomeModels.PlayPosts.Response)
func presentTagPlayList(with response: HomeModels.ShowTagPlayList.Response)
func presentUploadScene()
func presentSetting()
}

final class HomePresenter: HomePresentationLogic {
Expand Down Expand Up @@ -52,4 +54,12 @@ final class HomePresenter: HomePresentationLogic {
func presentTagPlayList(with response: HomeModels.ShowTagPlayList.Response) {
viewController?.routeToTagPlayList()
}

func presentUploadScene() {
viewController?.routeToVideoPicker()
}

func presentSetting() {
viewController?.openSetting()
}
}
17 changes: 16 additions & 1 deletion iOS/Layover/Layover/Scenes/Home/HomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ protocol HomeDisplayLogic: AnyObject {
func displayPosts(with viewModel: HomeModels.FetchPosts.ViewModel)
func routeToPlayback()
func routeToTagPlayList()
func routeToVideoPicker()
func openSetting()
}

final class HomeViewController: BaseViewController {
Expand Down Expand Up @@ -179,7 +181,7 @@ final class HomeViewController: BaseViewController {
// MARK: - Actions

@objc private func uploadButtonDidTap() {
present(videoPickerManager.phPickerViewController, animated: true)
interactor?.fetchLocationAuthorizationStatus()
}

@objc private func tagButtonDidTap(_ sender: UIButton) {
Expand Down Expand Up @@ -231,6 +233,7 @@ extension HomeViewController: VideoPickerDelegate {
// MARK: - DisplayLogic

extension HomeViewController: HomeDisplayLogic {

func displayPosts(with viewModel: HomeModels.FetchPosts.ViewModel) {
var snapshot = NSDiffableDataSourceSnapshot<UUID, Models.DisplayedPost>()
snapshot.appendSections([UUID()])
Expand All @@ -247,4 +250,16 @@ extension HomeViewController: HomeDisplayLogic {
func routeToTagPlayList() {
router?.routeToTagPlay()
}

func routeToVideoPicker() {
present(videoPickerManager.phPickerViewController, animated: true)
}

func openSetting() {
guard let url = URL(string: UIApplication.openSettingsURLString) else { return }
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
}

}
2 changes: 2 additions & 0 deletions iOS/Layover/Layover/Scenes/Map/MapConfigurator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ final class MapConfigurator: Configurator {
let router = MapRouter()
let worker = MapWorker()
let videoFileWorker = VideoFileWorker()
let locationManager = CurrentLocationManager()

router.viewController = viewController
viewController.interactor = interactor
interactor.presenter = presenter
interactor.worker = worker
interactor.videoFileWorker = videoFileWorker
interactor.locationManager = locationManager
presenter.viewController = viewController
viewController.router = router
router.dataStore = interactor
Expand Down
89 changes: 41 additions & 48 deletions iOS/Layover/Layover/Scenes/Map/MapInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@
import CoreLocation
import Foundation

import OSLog

protocol MapBusinessLogic {
func checkLocationAuthorizationStatus()
func playPosts(with: MapModels.PlayPosts.Request)

@discardableResult
func fetchPosts() -> Task<Bool, Never>

@discardableResult
func fetchPost(latitude: Double, longitude: Double) -> Task<Bool, Never>
func fetchPosts() async
func fetchPost(latitude: Double, longitude: Double) async
func selectVideo(with request: MapModels.SelectVideo.Request)
func checkLocationAuthorizationOnEntry()
func checkLocationPermissionOnUpload()
}

protocol MapDataStore {
Expand All @@ -35,77 +34,71 @@ final class MapInteractor: NSObject, MapBusinessLogic, MapDataStore {
var presenter: MapPresentationLogic?
var videoFileWorker: VideoFileWorker?
var worker: MapWorkerProtocol?

private let locationManager = CLLocationManager()
var locationManager: CurrentLocationManager?

var postPlayStartIndex: Int?
var posts: [Post]?
var index: Int?
var selectedVideoURL: URL?

override init() {
super.init()
locationManager.delegate = self
}

func checkLocationAuthorizationStatus() {
checkCurrentLocationAuthorization(for: locationManager.authorizationStatus)
}

func playPosts(with request: MapModels.PlayPosts.Request) {
postPlayStartIndex = request.selectedIndex
presenter?.presentPlaybackScene()
}

func fetchPosts() -> Task<Bool, Never> {
Task {
locationManager.startUpdatingLocation()
guard let coordinate = locationManager.location?.coordinate else { return false }
let posts = await worker?.fetchPosts(latitude: coordinate.latitude,
longitude: coordinate.longitude)
guard let posts else { return false }
self.posts = posts
let response = Models.FetchPosts.Response(posts: posts)
await MainActor.run {
presenter?.presentFetchedPosts(with: response)
}
return true
func fetchPosts() async {
locationManager?.startUpdatingLocation()
guard let coordinate = locationManager?.getCurrentLocation()?.coordinate else { return }
let posts = await worker?.fetchPosts(latitude: coordinate.latitude,
longitude: coordinate.longitude)
guard let posts else { return }
self.posts = posts
let response = Models.FetchPosts.Response(posts: posts)
await MainActor.run {
presenter?.presentFetchedPosts(with: response)
}
}

func fetchPost(latitude: Double, longitude: Double) -> Task<Bool, Never> {
Task {
let posts = await worker?.fetchPosts(latitude: latitude, longitude: longitude)
guard let posts else { return false }
self.posts = posts
let response = Models.FetchPosts.Response(posts: posts)
await MainActor.run {
presenter?.presentFetchedPosts(with: response)
}
return true
func fetchPost(latitude: Double, longitude: Double) async {
let posts = await worker?.fetchPosts(latitude: latitude, longitude: longitude)
guard let posts else { return }
self.posts = posts
let response = Models.FetchPosts.Response(posts: posts)
await MainActor.run {
presenter?.presentFetchedPosts(with: response)
}
}

func selectVideo(with request: Models.SelectVideo.Request) {
selectedVideoURL = videoFileWorker?.copyToNewURL(at: request.videoURL)
}

private func checkCurrentLocationAuthorization(for status: CLAuthorizationStatus) {
switch status {
func checkLocationAuthorizationOnEntry() {
guard let authorizationStatus = locationManager?.getAuthorizationStatus() else { return }
switch authorizationStatus {
case .authorizedAlways, .authorizedWhenInUse:
presenter?.presentCurrentLocation()
case .restricted, .notDetermined:
locationManager.requestWhenInUseAuthorization()
locationManager?.requestWhenInUseAuthorization()
case .denied:
presenter?.presentDefaultLocation()
@unknown default:
return
}
}
}

extension MapInteractor: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
checkCurrentLocationAuthorization(for: manager.authorizationStatus)
func checkLocationPermissionOnUpload() {
guard let authorizationStatus = locationManager?.getAuthorizationStatus() else { return }
switch authorizationStatus {
case .authorizedAlways, .authorizedWhenInUse:
presenter?.presentUploadScene()
case .restricted, .notDetermined:
locationManager?.requestWhenInUseAuthorization()
case .denied:
presenter?.presentSetting()
@unknown default:
return
}
}

}
10 changes: 9 additions & 1 deletion iOS/Layover/Layover/Scenes/Map/MapModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ enum MapModels {
struct DisplayedPost: Hashable {
let boardID: Int
let thumbnailImageData: Data?
let videoURL: URL
let videoURL: URL?
let latitude: Double
let longitude: Double
let boardStatus: BoardStatus
}

// MARK: - Fetch Video Use Cases
Expand Down Expand Up @@ -64,4 +65,11 @@ enum MapModels {

}
}

enum CheckLocationAuthorizationOnEntry {
struct ViewModel {
let latitude: Double = 36.350411
let longitude: Double = 127.384548
}
}
}
Loading

0 comments on commit 7ab724d

Please sign in to comment.