Swift/이슈 대응

[Swift] iPad 멀티태스킹 대응 시 확인할 것

언클린 2020. 4. 14. 10:19
728x90

이번에는 iPad에서 제공하는 멀티태스킹에 대하여 제 경험을 살려 확인해야 할 것과 수정이 필요한 부분에 대하여 설명드리겠습니다.

멀티태스킹에는 크게 두 가지로 나누어집니다. Split View와 Slide Over 간단히 이 둘의 차이라고 하면 화면을 분할해서 사용하냐 아니면 2중으로 그 위에 덮어서 사용하냐 정도가 됩니다. 

 

참조

https://support.apple.com/ko-kr/HT207582

 

iPad에서 멀티태스킹 사용하기

iPadOS에서는 멀티태스킹을 사용하여 동시에 두 개의 앱으로 작업하고, 비디오를 시청하면서 이메일에 답장하고, 제스처를 사용하여 앱을 전환하는 등 다양한 작업을 수행할 수 있습니다.

support.apple.com

 

제가 프로젝트 개발에 있어서 중간에 이 멀티태스킹 기능을 허용했는데 처음부터 멀티태스킹을 염두해 제작한 것이 아니었기 때문에 여러 가지 부분에서 문제점들을 만날 수 있었습니다. 

대표적으로 

1. 레이아웃의 망가짐

2. 카메라 캡처 기능의 무작동

3. 마이크 무작동

입니다. 이번 글에서는 제가 겪었던 일을 어떻게 해결했었는지 공유해드리겠습니다.


1. 멀티태스킹 기능 ON

우선적으로 프로젝트 개발에 앞서 어떻게 이 멀티태스킹 기능을 허용하는지 알아보겠습니다. 

1. 프로젝트 Target

첫번째로 프로젝트 생성 시 Target의 Require full screen에 체크를 해제해주시면 됩니다. 아마 처음에 프로젝트를 생성할 때는 해제되어 있는 상태일 겁니다.

2. info.plist

두번째는 info.plist 파일을 이용한 방법입니다. [+]를 눌러 새로운 키인 [UIRequiresFullScreen]을 입력해 주시고 Boolean타입의 NO로 지정해주시면 됩니다.

여기까지 보셨으면 어느 정도 아실 거라 생각합니다. 이 설정을 해주는 이유는 멀티태스킹 중 Split View가 FullScreen이 아니기 때문입니다. 반대로 허용하지 않으실 경우는 각 항목을 반대로 지정해 주시면 됩니다. 

 

2. 레이아웃의 망가짐

이제 본격적으로 해당 문제들에 대하여 제가 어떻게 해결해 나아갔는지 설명드리겠습니다. 우선 첫 번째로 레이아웃이 망가지는 현상입니다. 웬만하면 거의 일어나지는 않겠지만 제가 개발하던 프로젝트에서는 화면 전환을 허용하는 앱이며 전환을 통해 레이아웃의 구성이 변하는 앱이었습니다. 

때문에 멀티태스킹 중 Split View일 경우, 해당 뷰의 망가짐 현상이 있었습니다. 저는 이러한 현상을 해결하고자 

아래의 기능을 사용하였습니다. 

https://developer.apple.com/documentation/uikit/uicontentcontainer/1621466-viewwilltransitiontosize

 

viewWillTransitionToSize:withTransitionCoordinator: - UIContentContainer | Apple Developer Documentation

Instance Method viewWillTransitionToSize:withTransitionCoordinator: Notifies the container that the size of its view is about to change. Required. DeclarationParameterssizeThe new size for the container’s view.coordinatorThe transition coordinator object m

developer.apple.com

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
	// 프레임의 변화를 감지하여 처리 
}

레이아웃이 망가지는 현상은 Slide Over와 같은 멀티태스킹에서는 발생하지 않습니다. 보통 Split View와 같이 프레임이 변할 경우 발생하는데 그 프레임의 변화를 감지하는 것이 바로 viewWillTransitionToSize 입니다. 저는 이것을 사용하여 프레임의 변화를 감지 그 프레임에 맞추어 레이아웃 구성을 재구성할 수 있게 설정하였습니다.

하지만 viewWillTransitionToSize 는 화면 전환에도 감지가 되기 때문에 같이 고려해서 해결해야 합니다.

 

3. 카메라 캡처 기능의 무작동

두 번째 문제로는 카메라가 작동하지 않는다는 것입니다. 기본적으로 멀티태스킹에는 카메라의 캡처 기능을 지원하지 않습니다.

(이 때는 무려 Split View 타입 Slide Over 타입 전부 지원하지 않습니다...)

때문에 위와 같이 크기를 감지해서 처리하는 방법으로는 완벽히 제어할 수 없습니다.

대신 캡처 기능이 무작동이 된 그 상황을 감지할  수 있는 interrupt 키를 제공합니다. 저는 이 키를 사용하여 멀티태스킹 뷰일 경우 사용하는 유저에게 알릴 수 있는 다이어로그를 표시하여 해결했습니다.

 

우선 NSNotification.Name.AVCaptureSessionWasInterrupted 의 감지를 설정해 줍니다.

NotificationCenter.default.addObserver(self, selector: #selector(carmeraInterrupted), name: NSNotification.Name.AVCaptureSessionWasInterrupted, object: nil)

 

그러고 나서 감지되는 userInfo 데이터에서 reason키를 체크하여 처리하여 주시면 됩니다.

@objc
func carmeraInterrupted(_ notification: NSNotification) {
	if let userInfo = notification.userInfo?[AVCaptureSessionInterruptionReasonKey] as AnyObject?,
    	let intValue = userInfo.integerValue,
		let reason = AVCaptureSession.InterruptionReason(rawValue: intValue) {
			
            switch reason {
			case .audioDeviceInUseByAnotherClient: break
			case .videoDeviceInUseByAnotherClient: break
			case .videoDeviceNotAvailableDueToSystemPressure: break
			case .videoDeviceNotAvailableInBackground: break
            case .videoDeviceNotAvailableWithMultipleForegroundApps: break
            default:
            	return
           	}
 	}
}

현재 InterruptionReason는 총 5가지 키를 제공하고 있습니다.

여기서 멀티태스킹을 하게 되면 보통 .videoDeviceInUseByAnotherClient 와 .videoDeviceNotAvailableWithMultipleForegroundApps이 감지될 것입니다. 그리고 이 키를 보시게 되면 또 한 가지 알 수 있는 사실이 AVCaptureSession은 백그라운드 전환 시에도  지원하지 않는다는 것입니다. (저는 이때 알았습니다...)

 

3. 마이크 무작동

마지막으로 마이크 무작동에 대해서 설명드리겠습니다. 대부분 카메라 무작동에서 이해하셨을 거라 생각이 들지만 그래도 간단히는 집고 넘어가겠습니다. 마이크나 스피커도 AVFoundation에 속해있기 때문에 카메라와 같이 interrupt가 발생한 상황을 감지하여 처리하여 주시면 됩니다. 

 

카메라와 같이 intrerrupt의 감지를 생성해 줍니다. AVAudioSession.interruptionNotification 카메라와는 많이 다른데 저도 직접 실행해가며 찾았기 때문에 이게 괜찮았던 것 같습니다... 혹시 더 좋은 방법 아시는 분은 알려주시면 감사하겠습니다.

NotificationCenter.default.addObserver(self, selector: #selector(audioInterrupted), name: AVAudioSession.interruptionNotification, object: nil)

스피커나 마이크와 같은 경우는 기본적으로 멀티로 있을 시 한 가지에 대하여 밖에 실행이 되지 않습니다. 

한 가지가 실행되면 다른 한 가지는 종료되거나 정지상태가 되는 것

@objc
func audioInterrupted(_ notification: NSNotification) {
	if let userInfo = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as AnyObject?,
    	let intValue = userInfo.integerValue,
        let reason = AVAudioSession.InterruptionType(rawValue: UInt(intValue)) {

            switch reason {
			case .began: break
            case .ended: break
            default:
            	return
          	}
	}
}

AVAudioSession.InterruptionType 에서 제공하는 타입은 두 가지 존재합니다.

 

4. 마무리

이렇게 해서 제가 겪었던 그리고 제가 해결했던 iPad 멀티태스킹에 대하여 알아보았습니다. 제가 처음 경험했을 때 열심히 구글링 하고 API 찾아가면서 해결했던 게 생각이 나서 혹시 저와 비슷한 경험을 하시는 분들께 조금이나마 도움이 되고자 공유하게 되었습니다.

더 좋은 방법이나 보충이 필요한 부분이 있으신 분들은 댓글에 남겨주시면 감사하겠습니다.

많은 도움이 되었으면 좋겠습니다. 감사합니다.


환경 

Xcode 11.3.1

Swift 5


2020.4.27 수정

  • 카메라 기능 -> 카메라의 캡처 기능 AVCaptureSession

 

 

 

 

 

728x90