https://www.youtube.com/watch?v=nqNLrpMQrU8 

Lazy Sequences in Swift Explained (Performance Tips) – iOS

유튜브 채널 iOS Academy에서 발견한 영상. lazy sequence에 관련된 영상이다. 재밌게 시청해서 가져왔다. 

 

lazy

우선 lazy 키워드에 대한 간략한 설명을 하자면 말 그대로 lazy하게 변수를 할당하는 키워드이다. 대다수의 언어가 그렇겠지만 swift에서 변수, 상수의 경우 우선적으로 초기화가 이루어져야지만 컴파일이 완료된다. 하지만 lazy의 경우, 해당 변수의 초기화가 완료되었다고 판단하고 컴파일이 우선적으로 이루어진다. 이후 lazy로 생성된 변수에 접근하게 될 경우에 뒤늦게 초기화가 이루어지게 된다. 해당 부분의 경우 cs193p swift강의를 보면서 처음 마주했는데, 사실 당시에는 필요성이 크게 와닿지 않았다. 

 

lazy sequence

앞선 얘기는 lazy stored property에 관련된 이야기였고 이번글은 lazy sequence에 관련된 이야기를 하려 한다. swift에서 collection 타입의 자료들을 다루게 되면 가장 많이 다루게 되는 부분이 고차함수가 아닐까 싶다. rest-api를 사용할 때 반환된 요청을 map() 혹은 filter()와 같은 고차함수들을 통해 파싱을 하게 되는데, 이때 입력되는 자료의 수가 많다면 성능 저하가 일어나기 쉬울 것이다. 해당 자료들을 모두 사용하게 된다면 어쩔 수 없으나 대다수의 경우 해당 자료에서 일부분의 자료만 뽑아내어 사용자에게 보여주는 일이 많다. 여기서 lazy sequence를 통해 어느 정도의 성능개선을 이루어낼 수 있다.

 

0부터 1,000,000이 담긴 배열을 생성, map() 메소드를 통해 원소값들을 가공한 뒤 필요한 자료를 호출한 모습이다. 1,000,001 개의 원소를 탐색, 마지막으로 threeTimesArr에 결과를 저장하는 과정이 더해져 1,000,002번의 자료 접근이 일어나게 된다. 곱셈이라는 단순한 작업이었지만 처리해야 할 자료의 수가 많고 더욱 복잡한 자료의 연산이 일어난다면 성능 저하를 유발하게 된다.

 

이번엔 lazy를 이용한 연산이다. 앞서 말했듯이 lazy는 해당 자료에 접근이 일어날 경우에 초기화가 이루어지게 된다. lazy를 통한 map()메소드는 마찬가지로 자료의 접근이 일어날 때에 필요한 부분에서 연산이 일어나게 되고, 자료를 반환하는 모습을 볼 수 있다. 따라서 arr [50]의 자료접근, threeTimesArr[50]에 자료를 저장하는 과정 총 두 번의 접근을 통해 값을 출력하는 모습을 보여준다. 개발과정에서 이러한 lazy sequence를 통해 성능개선을 이루어낼 수 있지 않을까 싶다.

 

이상 lazy 키워드를 통한 성능개선에 관련된 이야기였으며 아마도 iOS 개발을 하면서 정말 유용하게 사용할 수 있는 미세먼지팁이 되지 않을까 싶다. 혹시나 틀린 정보를 적었다면 성장중인 아기개발자를 위해 따끔한 지적 부탁드립니다.

foreground
사용자와의 상호작용을 처리하기 위해 CPU를 포함한 시스템 자원할당에 높은 우선순위를 가지게 됩니다.
시스템은 이러한 리소스 할당을 위해 백그라운드 상태의 앱을 종료하기도 합니다.

background
사용자 이벤트를 받기 어려운 상태입니다. 
가능한 적은 시스템 자원을 사용해야 하고, 시스템에 의해 종료되기도 합니다.

 

 

Apple Developer Documentation

 

developer.apple.com

The current state of your app determines what it can and can’t do at any time. For example, a foreground app has the user’s attention, so it has priority over system resources, including the CPU. By contrast, a background app must do as little work as possible, and preferably nothing, because it’s offscreen. As your app changes from state to state, you must adjust its behavior accordingly.

 

iOS 앱의 생명주기에 관련된 용어다. iOS는 총 다섯 개의 상태(state)가 존재하며, 생명주기에 따라 상태가 변화한다. 개발자는 앱의 생명주기를 관리하며 각 상태에 따른 적절한 동작들을 정의할 수 있다.

 

애플의 공식 문서에 따르면 foreground 상태의 경우 사용자의 상호작용을 최우선으로 취급해야 하기에, 시스템 자원을 최우선으로 할당받게 된다. 반면 background 상태의 경우 화면에 보이는 상태가 아니기 때문에, 가능한 적은 일을 해야 한다.

 

app-based life-cycle events

Not running

앱이 실행되지 않았거나, 완전히 종료되어 동작하지 않는 상태

Inactive

앱이 실행되면서 foreground 상태에 진입하지만 어떠한 이벤트도 받지 않는 상태. 앱의 상태전환과정에서 잠깐 머무는 단계

Active

앱이 실행 중이며, foreground에 있고, 사용자의 상호작용을 받고 있는 상태

Background

앱이 background에 있으며, 다른 앱으로 전환되거나, 홈버튼을 눌러 나갔을 때의 상태. 일정 시간이 지나면 Suspended 상태로 전환

Suspended

앱이 background상태에서 특별한 작업이 없을 경우 해당단계로 진입. 앱은 메모리상에 올라가 있지만, 아무 일도 하지 않기 때문에 배터리를 사용하지 않는다. iOS의 자원할당에 따라서 이 상태의 앱은 메모리에서 해제될 수 있다.

 

각 단계마다 UIKit은 UIApplicationDelegate 객체를 통해 생명주기 이벤트를 발생시켜 개발자에게 알려주는데, 해당 부분을 통해 개발자는 앱의 생명주기에 따른 앱의 동작을 제어하게 된다.

 

여기까지 iOS13까지의 앱 생명주기에 대한 내용이며, iOS13 이후에는 약간의 변화가 생겼다. iOS13 업데이트부터 아이패드에서 멀티윈도우를 지원하기 시작했고, 하나의 앱 프로세스에서 하나 이상의 UI를 제공할 수 있게 되었다. 따라서 프로세스의 생명주기와 UI화면의 생명주기 부분을 나누어서 관리하기 시작했고, UI화면 관리 부분을 애플 측은 "scene-based life-cycle"로 정의했다.

 

scene-based life-cycle events

해당 부분에 대한 설명을 적으려면 주제를 조금 벗어나게 되므로 다음글에 이어서 적도록 하겠다.

 

참고 블로그

https://icksw.tistory.com/178

https://icksw.tistory.com/137

프로그램 실행을 위한 진입 지점을 가리키는 어노테이션입니다.

 

[iOS] 앱이 시작할 때 main.c 에 있는 UIApplicationMain 함수에 의해서 생성되는 객체는 무엇인가?

Apple Developer Documentation developer.apple.com iOS 개발자라면 가장 근본적으로 알아야 할 App life Cycle에 관련된 질문이다. 질문에 대해 단답식으로 대답하자면 아래와 같이 대답할 수 있다. "UIApplication 객

hyun083.tistory.com

지난 글과 주제가 같은 글이다. 

 

사용자가 iOS앱을 클릭하면, UIKit 프레임 워크 안에 숨겨진 main() 함수가 수행되고, 뒤이어 UIApplicationMain() 함수가 수행되는데, 이때 UIApplicationMain() 함수를 호출하는 어노테이션이 바로 @UIApplicationMain 어노테이션이다. iOS 탬플릿을 생성하면 기본적으로 생성되는 파일 중 "appDelegate.swift"에서 해당 어노테이션이 자동으로 생성되는 것을 볼 수 있다. xcode12 기준으로 해당 어노테이션은 @main으로 변경되었다.

*swiftUI로 프로젝트를 생성한 경우, "OOOOApp.swift" 파일에서 찾아볼 수 있다.

 

 

GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Lang

This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhance...

github.com

@main: Type-Based Program Entry Points
A Swift language feature for designating a type as the entry point for beginning program execution. Instead of writing top-level code, users can use the @main attribute on a single type. Libraries and frameworks can then provide custom entry-point behavior through protocols or class inheritance.

 

애플이 작성한 swift-evolution 문서를 확인해 보면 프로그램을 실행하기 위한 진입지점으로 유형을 가리키는 기능이라고 적혀있다. 뒤에 이어지는 내용에는 사용자는 탑 레벨 코드를 적는 것 대신, 유형에 @main 속성을 사용할 수 있다고 한다. 완벽하게 이해되지는 않지만 뒤에 이어지는 글이 큰 힌트를 준다. "프로토콜과 클래스 상속을 통한 진입지점의 커스텀이 가능하다."

 

UIApplicationMain() 함수는 애플리케이션 객체와 애플리케이션 델리이트를 생성하고 이벤트 루프를 설정한다. 이때에 @main 어노테이션이 붙어있는 클래스(AppDelegate)를 인스턴스화하여 전달해 주게 되는 것이고, 이러한 과정에서 해당 클래스의 상속 클래스 이름과 채택한 프로토콜의 이름을 전달하는 것이 @main의 역할이라고 생각하면 될 것 같다.

 

Apple Developer Documentation

 

developer.apple.com

iOS 개발자라면 가장 근본적으로 알아야 할 App life Cycle에 관련된 질문이다. 질문에 대해 단답식으로 대답하자면 아래와 같이 대답할 수 있다.

"UIApplication 객체가 생성됩니다."

사용자가 앱 아이콘을 눌러 앱을 실행하게 되면 대략 사진과 같은 형태의 생명주기를 통해 메모리에 할당되었다가 소멸된다. 여기서 이번 글에 눈여겨볼 부분은 바로 UIApplicationMain() 호출 부분이다. swift이전에 obj-c로 작성되었던 앱은 c언어 기반이었기에 앱이 실행되면 운영체제가 가장 먼저 main.m 파일 안에 main() 함수를 호출하여 앱이 시작되었다고 한다.

 

swift가 c언어 기반은 아니지만 obj-c와 함께 사용되기 위한 언어여서인지, 동일하게 main() 함수를 호출을 해야하는데, 우선 xcode로 생성한 iOS 개발 템플릿에는 main.swift 파일은 보이지 않는다. 이유는 UIKit 프레임워크 안에 main() 함수를 숨겨놓았다고 한다. 따라서 앱이 실행되면 가장 먼저 운영체제가 개발자는 찾아볼 수 없는 main() 함수를 호출하고, main() 함수는 뒤이어 UIApplicationMain() 함수를 호출하여 UIApplication 객체가 생성이 되는 것이다. 그렇다면 UIApplication은 무엇일까?

 

UIApplication

 

Apple Developer Documentation

 

developer.apple.com

The centralized point of control and coordination for apps running in iOS.

문서에 따르면 iOS에서 실행중인 앱의 제어와 조정을 담당하는 중앙지점이라고 적혀있다. 즉 여기서부터 실직적인 앱이라고 부를 수 있고, 해당 객체가 생성되고 나서야 개발자가 작성한 코드대로 이벤트 처리 등 앱의 동작을 제어할 수 있는 것이다.

 

모든 iOS앱은 단 하나의 UIApplication 인스턴스를 가지며, 개발자가 원한다면 UIApplication의 shared 프로퍼티를 통해 객체에 접근할 수 있다고 한다. 사실 무슨 말인지는 정확하게 와닿지 않아서 이 부분에 대해서는 나중에 시간을 들여 더 깊이 알아봐야겠다.

 

참고 문서 및 블로그

https://atelier-chez-moi.tistory.com/29

https://zeddios.tistory.com/538

https://blog.naver.com/soojin_2604/222423840595

App Thining

 

https://help.apple.com/xcode/mac/current/#/devbbdc5ce4f

To see this page, you must enable JavaScript. Pour afficher cette page, vous devez activer JavaScript. Zur Anzeige dieser Seite müssen Sie JavaScript aktivieren. このページを表示するには、JavaScript を有効にする必要があります。

help.apple.com

애플리케이션을 설치할 때, 앱스토어와 운영체제가 디바이스의 환경에 맞게 설치하는 설치 최적화 기술이다.

필요한 만큼의 리소스만 다운로드하기에 적은 디스크 사용량, 빠른 다운로드를 제공한다.

해당 기술에는 slicing(슬라이싱), bitcode(비트 코드), on-demand resource(주문형 리소스)가 있다.

 

slicing

Slicing is the process of creating and delivering variants of the app bundle for different target devices and operating system versions.

슬라이싱은 여러 가지 디바이스와 운영체제를 위한 앱 번들의 variants(변형)을 생성 및 제공하는 과정을 뜻한다. variants(변형)에는 각 디바이스와 운영체제가 필요로 하는 실행 가능한 아키텍처와 리소스가 담겨있다고 한다. 개발자가 앱스토어 커넥트에 풀버전의 앱 빌드를 업로드하게 되면 앱스토어는 자동적으로 variants를 생성하고 전달한다고 한다.

유저가 앱스토어에서 앱을 다운로드하게 되면, 유저의 디바이스와 운영체제 버전에 맞는 variants를 다운로드하게 된다.

 

bitcode

Bitcode is an intermediate representation of a compiled program.

비트코드는 컴파일된 프로그램의 중간 표현이라고 한다. 즉, 기계 코드도 아니고, 프로그래밍 코드도 아닌 그 중간의 형태라고 보면 된다. 개발자는 앱스토어 커넥트에 자신의 앱에 비트 코드를 포함시켜 올릴 수 있으며 그러한 비트 코드는 컴파일되어 앱스토어에 연결된다. 애플은 업로드된 비트 코드를 통해서 개발자의 새로운 버전의 앱 업로드 없이도 앱 바이너리를 최적화할 수 있다고 한다.

*앱 바이너리 : 기계코드가 포함된 파일

 

자세한 부분까지 이해하기 쉽지 않으나, 본인이 보기엔 디바이스의 프로세서 아키텍처의 변경(32bit, 64bit)과 같은 부분에서 비트 코드가 없다면, 개발자가 새로 컴파일하여 새로운 앱을 배포해야했으나, 기계어도, 프로그래밍 언어도 아닌 중간 형태의 비트 코드를 통해서 새로운 아키텍처의 변경에도 자동적으로 최적화가 이루어진다는 얘기 같다. 추가적인 정보는 더 찾아봐야 할 거 같다.

 

on-demand resource

On-demand resources are resources—such as images and sounds—that you can tag with keywords and request in groups, by tag.

주문형 리소스는 이미지, 음원과 같은 앱의 리소스를 키워드로 태그 해놓고, 태그를 통해 그룹으로 요청이 가능한 리소스다.

앱스토어는 사용자에게 현재 필요한 리소스를 관리하고 다운로드하게 한다. 또한 주문형 리소스의 슬라이싱 작업을 통해 variants의 최적화 작업을 진행한다고 한다. 이러한 주문형 리소스는 다음과 같은 이점을 제공한다.

  • 앱의 사이즈가 작아지게 되고, 이를 통해 더 빠른 다운로드를 제공, 사용자가 앱의 최초 실행 경험을 개선하게 된다.
  • 사용자가 앱을 체험하면서 필요하게 되는 주문형 리소스들을 백그라운드에서 다운로드하게 된다.
  • 운영체제가 더 이상 필요로 하지 않는 주문형 리소스들은 제거하게 되고, 이로 인해 저장공간을 절약한다.

대표적인 예시를 들 수 있는 경우가 게임의 추가 리소스 다운이다. 일반적으로 이미지와 음원이 많은 게임 앱의 경우, 최초 실행을 위한 최소한의 리소스를 우선적으로 받고, 게임 실행 후 필요한 부분만 리소스를 추가적으로 다운로드하여 저장공간 절약, 실행을 위한 다운로드 시간 감소 등 대용량 앱 사용에 더욱 쾌적한 환경을 제공할 수 있다.

 

참고 자료 및 블로그

https://zeddios.tistory.com/655

https://jiseok-zip.tistory.com/entry/iOSApp-Thinning#toc-정의%20▾ 

UIViewController

 

Apple Developer Documentation

 

developer.apple.com

UIViewController

An object that manages a view hierarchy for your UIKit app.
UIKit으로 제작된 앱의 뷰계층구조를 관리하는 객체. UIKit으로 앱개발을 하게되면 가장 먼저, 그리고 가장 많이 마주하게 될 클래스이다. 
화면위에 보여지게될 UIView들의 로직과 관리를 담당하게 된다. 그렇다면 UIView는 무엇일까? 
 
UIView
 

Apple Developer Documentation

 

developer.apple.com

UIView

An object that manages the content for a rectangular area on the screen.

화면 위의 콘텐츠를 관리하기 위한 사각형 영역 객체를 UIView라고 정의하고 있다. 즉 사용자에게 보일 UILabel, UIButton과 같은 화면 구성요소들을 모두 UIView라고 하고 이러한 객체들을 관리하기 위한 객체가 UIViewController이다.

 

UIViewController에 대해 이어서 설명하자면 UIViewController가 하는 대표적인 일은 다음과 같다.

  • 뷰의 컨텐츠 업데이트, 주로 기본 데이터의 변경에 반응.
  • 뷰와 사용자간의 상호작용에 반응.
  • 전반적인 인터페이스 레이아웃 관리 및 뷰의 사이즈 조정
  • 다른 컨트롤러와의 화면 전환

뷰 컨트롤러는 연결되어있는 화면의 가시성(visibility)에도 관여하게 된다. 즉 화면이 나타나고 사라지는 생명주기 단계에 해당되는 함수를 자동적으로 호출한다.

그림에 표현된 것 이외에도 생명주기에 관련된 함수가 몇 가지 더 있지만 해당 부분은 생명주기에 대한 자세한 글로 적으려 한다. 

 

정리해서 말하자면 UIViewController는 화면을 관리하는 하나의 단위라고 설명하고싶다.

 

많은 종류의 UIViewController가 있지만 크게 두 가지 유형으로 나뉜다.

ContentViewController

가장 기본적인 뷰 컨트롤러로서 하나의 화면을 담당하고 그 안에서의 UIView 객체에 대한 생성과 관리를 맡으며 사용자와의 상호작용을 담당한다.

ContainerViewController

하나 이상의 뷰 컨트롤러를 관리하는 뷰 컨트롤러. 하나 이상인 컨트롤러의 레이아웃, 화면 전환을 담당한다.

대표적으로 UINavigationController, UITabBarController 및 UISplitViewController 등이 있다.

 

참고 글

https://velog.io/@swiftist9891/UIView-UIViewController

UserDefaults

https://developer.apple.com/documentation/foundation/userdefaults#1664798

 

Apple Developer Documentation

 

developer.apple.com

UserDefaults

An interface to the user’s defaults database, where you store key-value pairs persistently across launches of your app.
유저디폴트, 사용자 기본값이라고 생각하면 된다. 키-값 형태로 저장되며 키는 문자열형태, 값은 스위프트의 기본자료형인 Float, Double, Int, Bool, URL 타입 이외에 NSData,NSString,NSNumber,NSDate,NSArray,,NSDictionary 자료형을 담아낼 수 있다고한다.
설명만 들었을때는 이걸 어떻게 사용하는건가 싶었는데, Zedd님의 글을 보고서 금방 이해했다. 앱의 최근 상태를 저장하거나 최근 값을 불러내기 위해 사용된다고 보면된다. 
 

iOS ) 왕초보를 위한 User Defaults사용해보기(switch)

안녕하세요 :) 오늘은 UserDefaults에 대해서 배워볼게요!!UserDefaults가 무엇이냐!! 간단하게 말해서 "데이터 저장소"라고 생각하시면 된답니다.UserDefaults를 사용하면 앱의 어느 곳에서나 데이터를 쉽

zeddios.tistory.com

저장

func set(Any?, forKey: String)
func set(Float, forKey: String)
func set(Double, forKey: String)
func set(Int, forKey: String)
func set(Bool, forKey: String)
func set(URL?, forKey: String)

매개변수의 자료형에 따라 set메소드를 사용해 키-값 형태로 저장이 된다.

불러오기

func object(forKey: String) -> Any?
func url(forKey: String) -> URL?
func array(forKey: String) -> [Any]?
func dictionary(forKey: String) -> [String : Any]?
func string(forKey: String) -> String?
func stringArray(forKey: String) -> [String]?
func data(forKey: String) -> Data?
func bool(forKey: String) -> Bool
func integer(forKey: String) -> Int
func float(forKey: String) -> Float
func double(forKey: String) -> Double
func dictionaryRepresentation() -> [String : Any]

이후 불러올 키와 함께 자료형에 맞는 함수에 적으면 된다. 


간단하게 NavigationView를 만들어서 확인해보았다. 좌측이 UserDefaults를 사용하지 않은 경우, 뷰가 생성될 때마다 초기값으로 시작하는 것을 볼 수 있는 반면, UserDefaults를 사용하게 되면 값들을 따로 저장하고 불러오는 것이 가능해진다. 저장된 자료들은 앱을 껐다 켜도 그대로 남아있는 모습을 볼 수 있었다.

NextView의 onAppear, onDisappear 구현을 통해 UserDefaults를 저장하고 불러오는 동작을 구현하였다.

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack{
                NavigationLink(destination: NextView(), label: {
                    Text("NextView!")
                })
            }.navigationTitle("Test")
        }
        .padding()
    }
}

struct NextView: View {
    @State private var toggleIsOn = false
    @State private var count = 0
    
    var body: some View {
        VStack{
            Toggle("Toggle switch", isOn: $toggleIsOn)
            HStack{
                Button("-", action: {
                    count -= 1
                })
                Text("\(count)")
                Button("+", action: {
                    count += 1
                })
            }.font(.system(size: 50))
        }
        .padding()
        .onAppear{
            count = UserDefaults.standard.integer(forKey: "countKey")
            toggleIsOn = UserDefaults.standard.bool(forKey: "toggleKey")
        }
        .onDisappear{
            UserDefaults.standard.set(count, forKey: "countKey")
            UserDefaults.standard.set(toggleIsOn, forKey: "toggleKey")
        }
    }
}

CoreData

https://developer.apple.com/documentation/coredata/

 

Apple Developer Documentation

 

developer.apple.com

 Core Data

Persist or cache data on a single device, or sync data to multiple devices with CloudKit.

UserDefaults의 경우는 간단한 유저 설정을 저장하는 데에 용이하지만, 더 복잡한 사용자 자료를 담아내려면 Coredata가 적합하다. 

coredata에는 많은 기능들이 있지만 대다수가 Persistence 기능을 위해 사용하는 것으로 알고 있다.

Persistence

Core Data abstracts the details of mapping your objects to a store, making it easy to save data from Swift and Objective-C without administering a database directly.

문서에 따르면 데이터베이스를 직접 사용하지 않고 swift, obj-c 자료들을 손쉽게 저장할 수 있다고 한다. zedd님의 설명을 읽어보니 대략적인 느낌은 알겠으나 아직 본인의 역량이 부족한지 완벽하게 이해가 되지 않는다. coredata 부분을 완벽하게 이해하기 위해서는 나중에 더 많은 시간을 들여 공부해야겠다.

 

Core Data (1)

안녕하세요 :) Zedd입니다. Core Data를 사용할 일이 생겼는데...제가 옜날에 해봤단 말이죠..!?!?!? 근데 다시 하려니까 생각이 하나도 안나는거에요 그때는 문서 볼 생각도 안했었는데..ㅎㅎㅎㅎ 이

zeddios.tistory.com

 

 

Core Data (2)

안녕하세요 :) Zedd입니다. https://zeddios.tistory.com/987 Core Data (1) 안녕하세요 :) Zedd입니다. Core Data를 사용할 일이 생겼는데...제가 옜날에 해봤단 말이죠..!?!?!? 근데 다시 하려니까 생각이 하나도 안

zeddios.tistory.com

 

https://developer.apple.com/library/archive/documentation/IDEs/Conceptual/iOS_Simulator_Guide/TestingontheiOSSimulator/TestingontheiOSSimulator.html

 

Testing and Debugging in Simulator

Retired Document Important: The information in this document is deprecated in Xcode 9. For Xcode 9 and later, see Simulator Help by choosing Help > Simulator Help in Simulator. Testing and Debugging in Simulator Simulator is a great tool for rapid prototyp

developer.apple.com

시뮬레이터에서 할 수 없는 동작들에 대해 생각해보았다. 시뮬레이터 관련 공식문서는 찾았지만 구버전의 xcode 시뮬레이터 관련 문서였고, 최근 버전의 레퍼런스 페이지에서는 시뮬레이터 관련 문서를 찾지 못했다. 일단 구버전 문서의 기준에 따르면 다음과 같은 동작들이 불가능하다.


Hardware Differences

Though most of the functionality of devices can be simulated in Simulator, some hardware features must be tested directly on a device. The hardware features that are not simulated as of iOS 8.2 are:

  • Motion support (accelerometer and gyroscope) are unsupported.
  • Audio and video input (camera and microphone) are unsupported.
  • Proximity sensor
  • Barometer
  • Ambient light sensor

API Differences

Simulator APIs don’t have all the features that are available on a device. For example, the APIs don’t offer:

  • Receiving and sending Apple push notifications
  • Privacy alerts for access to Photos, Contacts, Calendar, and Reminders
  • The UIBackgroundModes key
  • Handoff support

In addition, Simulator doesn’t support the following frameworks:

  • External Accessory
  • IOSurface
  • Media Player
  • Message UI
  • In UIKit, the UIVideoEditorController class

한 가지 의문인 점은 하드웨어에서의 오디오 입력 부분이다. 현시점 시뮬레이터 14.1 버전에서는 입출력 관련 메뉴가 따로 있다. 해당 메뉴를 통해 오디오 입력을 맥북의 마이크로 지정할 수 있고, 실제로 입력이 가능한지 텍스트 입력을 해보았다.

영어는 물론 한국어로도 잘 인식이 되는 모습을 확인할 수 있었다. 시뮬레이터가 오디오 입력을 지원하니 아마도 테스트용 앱 개발을 통해서도 입력을 지원하지 않을까 싶다. 나머지 가속도, 근접, 조도 센서와 같은 부분은 당연히 지원하지 않을 것으로 보인다. 기압계(barometer)도 적혀있는데, 아이폰에 운동량 측정을 위해 아이폰6부터 들어간 센서라고 한다. 해당 센서를 통해 개발자는 대략적인 고도를 알아낼 수 있다고 한다. 이런 부분은 처음 알았다.

이외에도 시뮬레이터의 메뉴들을 좀 더 찾아보니 페이스아이디 지원 부분도 있었다. 맥북에는 당연하게도 페이스 아이디 센서가 없으니 일치, 불일치와 같은 조건 상황만 지원하는 것으로 보인다. 

 

그리고 정보를 찾다가 많은 분들이 마우스로만 조작해야하므로 핀치 줌인/아웃 동작을 할 수 없다고 적어놨던데, 틀린 정보다. 옵션 키를 누르면 투 포인트로 제어할 수 있다. 해당 부분은 스탠퍼드 swift 강의로 유명한 cs193p 강의에서 확인했던 기능이다. 해당 부분은 본인도 지도 관련 앱을 개발할 당시 잘 사용했던 기능이다. 

option키를 누르고 있으면 x,y축 반전으로 동작하는 하나의 포인터가 추가되고, shift를 추가로 누르게 되면 평행이동하는 포인터로 제어가 가능하다.

이상 요약하자면 시뮬레이터로 할 수 없는 것들은 다음과 같다.

하드웨어

  • 가속도, 자이로스코프센서
  • 비디오 입력(카메라)
  • 근접센서
  • 기압 센서
  • 조도센서

API

  • 애플 푸시 알림
  • 사진, 연락처, 캘린더, 리마인더 등 개인 정보 접근
  • The UIBackgroundModes key
  • 핸드오프 기능

API 측면에는 적지 않은 더 많은 기능들이 적혀있는데 하나하나 확인하기에는 시간이 걸릴 것 같으므로 천천히 알아봐야겠다.

+ Recent posts