Skip to content
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

feat: 영상 재추출시 업로드 에러, 지도 인코딩중 표시 및 권한 처리 #331

Merged
merged 11 commits into from
Dec 14, 2023
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
}
}
anyukyung marked this conversation as resolved.
Show resolved Hide resolved

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)
}
}
anyukyung marked this conversation as resolved.
Show resolved Hide resolved

}
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