'2020/07/28'에 해당되는 글 4건

  1. 2020.07.28 CEF 시작하기! 2
  2. 2020.07.28 iOS App Extension #3 만들기
  3. 2020.07.28 iOS App Extension #2 동작 이해하기
  4. 2020.07.28 iOS App Extension #1 기초
Windows2020. 7. 28. 13:56

CEF

 

Chromium Embedded Framework (CEF).

chromium 기반의 브라우저를 내포하는 앱을 만들 수 있는 프레임워크이다.

 

 

BSD-license이고 구글 크로미엄프로젝트 기반으로 2008년에 마샬그린브랫에의해 시작된 오픈소스 프로젝트이다.

크로미엄프로젝트와 다르게 구글 크롭앱개발에 주로 집중하였고 써드파티앰의 내장된 브라우저 사용 케이스에 집중하였다.

CEF는 크로미텀의 하부와 코드의 복잡함으로부터 고수준의 안정화된 API, 특정목적의 배포, 그리고 바이너리 배포를 통해 벗어날수 있게 해준다.

CEF기본 구현은 사용자로부터 조금의 또는 전혀 통합하는 작업을 필요로 하지 않는다.

현재 1억개 이상의 인스턴스가 사용되고 있다. 그 일부가 위키페이지에 정리되어 있다.

 

사용케이스 몇가지는 다음과 같다.

* 기존 네이티브 애플리케이션에 HTML5호환 웹브라우저를 내장

* 가벼운 네이트브 쉘애플리케이션으로 기본적으로 웹기술에 기반하여 개발된 UI를 호스팅

* 자체적인 드로잉프레이뭐크를 사용하는 오프스크린 웹컨텐츠를 렌더링

* 웹속성이나 애플리케이션의 자동화된 테스트를 수행

 

CEF는 수많은 언어와 운영체제를 지원하며 새로운 또는 기존애플리케이션에 쉽게 통합이 가능하다. 성능과 쉬운 사용을 목표로 설계되었다.

기반프레임워크는 C, C++로 네이티브라이브러리로 제공되고 애플리케이션과 크로미엄과 상세한 구현으로부터 분리해준다.

이는 브라우저와 커스텀플러그인, 프로토콜, 자바스크립트 객체 그리고 자바스크립트 확장 등을 포함하는 앱간에 밀접한 통합을 제공한다.

애플리케이션은 리로스로딩을 제어하거나, 네비게이션, 메뉴, 프린트 등을 하면서 구글 크롬웹브라우저와 동일한 성능과 HTML5기술을 사용할 수 있다.

 

수많은 개인과 단체가 시간과 자원을 CEF개발에 기연하고 있지만 더 많은 커뮤니티로부터의 참여는 항상 환영한다.

 

시작하기

 

시작은 튜터리얼 위키페이지에서 CEF 사용에 대한 개요를 읽고 아키텍쳐적인 내용이나 사용이슈에 대한 더 깊은 논의를 하기 위하여 GeneralUsage 위키를 읽어라.

API문서를 살펴보고 지원과 관련된 논의에 대해서는 포럼을 참고하라

 

 

 

CEF Tutorial

 

CEF3로 간단한 앱을 작성하는 방법을 설명한다. CEF3 사용에 대해서는 GeneralUsage위키페이지를 참고하라.

 

시작하기

 

CEF개발을 시작하기 쉽게 해주는 샘플프로젝트를 제공한다. cef-project 웹사이트에 방문하고 단계별로 설명을 따라해보기 바란다.

 

 

커스텀URL 로딩하기

 

샘플프로젝트는 구글 홈페이지를 로딩한다. 다른 url로 변경하려면 커맨드라인에서 다음과같이 수행한다.

 

# Load the local file “c:\example\example.html”

cefsimple.exe --url=file://c:/example/example.html

 

샘플프로젝트에서 cefsimple/simple_app.cc에서 다음라인을 수정하고 다시 컴파일하면 바로 진입한다.

 

// Load the local file “c:\example\example.html”

if (url.empty())

  url = "file://c:/example/example.html";

 

 

애플리케이션 요소들

 

모든 CEF애플리케이션은 다음의 기본 콤포넌트들로 구성된다.

 

1. CEF dynamic library(libcef.dll 윈도우용, libcef.so 리눅스용, Chromium Embedded Framework.framework 맥용)

2. 지원 파일들(*.pak, *.bin, ...)

3. 리소스 (html/js/css, string, ...)

4. 클라이언트 실행파일

 

CEF dynamic library, 지원파일들, 리소스는 모든 CEF 애플리케이션에 존재한다. 바이너리 배포판의 Debug / Release 또는 Resources 디렉토리에 포함된다. 이러한 파일 중 필요한 파일과 제외 할 수있는 파일에 대한 자세한 내용은 이진 배포에 포함 된 README.txt 파일을 참조하십시오. 각 플랫폼에서 필요한 애플리케이션 레이아웃에 대한 자세한 설명은 아래를 참조하십시오.

 

60초 아키텍쳐

 

다음은 이 튜터리얼의 기본적인 중요한 아이템들을 요약한다.

 

* CEF는 멀티프로세스를 사용한다. 메인 애플리케이션 프로세스는 '브라우저' 프로세스로 불린다. 서브프로세스들은 렌더러, 플러그인, GPU등으로 생성해되게 될것이다.

* 윈도우와 리눅스에서는 메인과 서브프로세스가 같이 실행될 수 있다. OS-X는 실행과 서브프로세스의 번들이 분리되어야 한다.

* 대부분의 프로세스는 다중스레드를 갖는다.

* 일부 콜백과 함수들은 개개 프로세스 또는 개개의 스레드를 사용할 수 있다. 콜백이나 함수를 처음 사용하는 경우 헤더파일의 코멘트를 반드시 읽어볼것을 권장한다.

 

소스코드

 

cefsimple애플리케이션은 CEF를 초기화하고 하나의 브라우저팝업윈도우를 생성한다. 애플리케이션은 모든 브라우저윈도우가 닫히면 종료된다. 프로그램 흐름은 다음과 같다.

 

1. OS는 브라우저프로세스를 시작한다. 진입포인트는 main또는 wWinMain

2. 진입포인트 함수는

  프로세스레벨의 콜백을 처리하는 SimpleApp의 인스턴스를 생성한다.

  CEF를 초기화 하고 CEF message loop를 시작한다.

3. CEF가 초기화 되면 SimpleApp::OnContextInitialized가 호출된다. 이 메서드는

  SimpleHandler의 싱글턴 인스턴스를 생성한다.

  CefBrowserHost::CreateBrowser를 사용하여 브라우저윈도우를 생성한다.

4. 모든 브라우저는 SimpleHandler인스턴스를 공유하며 이는 브라우저의 행위를 커스텀하고 관련된 콜백을 처리한다(life span, 로딩상태, 타이틀 표시등...)

5. 브라우저하나가 닫히면 SimpleHandler::OnBeforeClose가 호출된다. 모든 브라우저가 닫히면 CEF message loop가 끝나며 애플리케이션이 종료된다.

 

 

진입포인트 함수

 

이 함수는 CEF와 운영체제 관련된 객체들을 초기화해야 한다. 예를 들어 리눅스에서는 X11 에러헨들러를 인스톨해야 하고, OS-X에서는 필요한 코코아객체들의 할당이 필요하다.

 

* 윈도우 : cefsimple/cefsimple_win.cc

* 리눅스 : cefsimple/cefsimple_linux.cc

* OS-X

  브라우저 프로세스 : cefsimple/cefsimple_mac.mm

  서브 프로세스 : cefsimple/process_helper.mac.cc

 

 

SimpleApp

 

프로세스레벨의 콜백을 처리해야 한다. interface/method로 노출되며 멀티프로세스에 의해 공유되고 각 프로세스만 에서 호출된다.

예를 들어 CefBrowserProcessHandler인터페이스는 브라우저 프로세스에서만 호출된다.

CefRenderProcessHandler인터페이스(샘플에서는 없음)는 렌더프로세스에서만 호출된다.

GetBrowserProcessHandler는 반드시 this를 리턴해야 한다. SimpleApp CefApp CefBrowserProcessHandler를 구현해야 하기 때문이다. GeneralUsage 위키페이지나 API 헤더파일을 보고 CefApp과 관련된 인터페이스들에 대해 좀더 많은 정보를 살펴보길 바란다.

 

* 공유된 구현 : cefsimple/simple_app.h, cefsimple/simple_app.cc

 

SimpleHandler

 

브라우저레벨의 콜백을 처리해야 한다. 브라우저 프로세스로부터 실행된다. 샘플에서우리는 CefClient인스턴스를 모든 브라우저에서 사용했다. 하지만 당신의 애플리케이션은 각각 전용의 인스턴스를 사용해도 된다. GeneralUsage 위키페이지나 API 헤더파일을 보고 CefApp과 관련된 인터페이스들에 대해 좀더 많은 정보를 살펴보길 바란다.

 

* 공유된 구현 : cefsimple/simple_handler.h, cefsimple/simple_handler.cc

* 윈도우 : cefsimple/simple_handler_win.cc

* 리눅스 : cefsimple/simple_handler_linux.cc

* OS-X : cefsimple/simple_handler_mac.mm

 

빌드 순서

 

빌드 순서는 플랫폼에 의존한다. binary 배포와 함께 포함된 CMake파일을 찾아서 살펴보면 모든과정에 대한 이해가 가능할것이다. 모든 플랫폼에 공통된 빌드 순서는 일반적으로 다음과 같이 요약될 수 있다.

 

1. libcef_dll_wrapper static library를 컴파일

2. application 소스 컴파일, libcef dynamic library libceff_dll_wrapper static library 링크

3. library와 리소스들을 출력디렉토리에 복사

 

 

윈도우 빌드순서

 

1. libcef_dll_wrapper static library를 컴파일

2. cefsimple.ext 컴파일 및 링크

- 필요한 소스코드 : cefsimple_win.cc, simple_app.cc, simple_handler.cc, simple_handler_win.cc.

- 필요한 라이브러리 : comctl32.lib, shlwapi.lib, rcprt4.lib, libcef_dll_wrapper.lib, libcef.lib, cef_sandbox.lib

cef_sandbox.lib(sandbox지원시) VS 2015 update3으로 빌드된 정적라이브러리이다. 다른 버전의 VS는 컴파일이 안될수도 있다. sandbox를 지원하지 않으면 문제가 없으며 cefsimple_win.cc의 코멘트를 확인하여 비활성화 하면 된다.

- 리소스 파일 : cefsimple.rc

- 매니페스트 파일 : cefsimple.exe.manifest, compatibility.manifest

3. Resource 폴더의 모든 파일 대상폴더로 복사

4. Debug/Release 폴더의 모든 파일 대상폴더로 복사

 

결과 폴더의 구조는 2526 브랜치정도가 보일거다.

 

Application/

    cefsimple.exe  <= cefsimple application executable

    libcef.dll <= main CEF library

    icudtl.dat <= unicode support data

    libEGL.dll, libGLESv2.dll, ... <= accelerated compositing support libraries

    cef.pak, devtools_resources.pak, ... <= non-localized resources and strings

    natives_blob.bin, snapshot_blob.bin <= V8 initial snapshot

    locales/

        en-US.pak, ... <= locale-specific resources and strings

 

Posted by 삼스
iOS2020. 7. 28. 13:54

앱익스텐션을 개발할 준비가 되었다면 먼저 적절한 익스텐션포인트를 결정해야 한다. 원하는 익스텐션포인트에 해당하는 Xcode 익스텐션 템플릿으로 시작하여 코드와 UI를 커스텀하는 방식으로 진행하는것이 좋다. 테스트와 최적화가 완료된 후 포함하는 앱에 함께 배포할 준비가 된것이다.

 

적절한 익스텐션포인트를 선택하여 개발 시작하기

 

익스텐션포인트가 잘 정의되어 있기 때문에 이를 선택하는것이 우선이다. 이를 선택함으로써 사용가능한 API와 동작이 결정된다.

 

익스텐션포인트는 iOS, OS X에서 제공되고 Info.plist에 익스텐션포인트 아이디키로 정의되어 있으며 다음 링크에서 확인이 가능하다.

 

익스텐션포인트를 선택하면 새로운 타겟을 추가한다. 가장 쉬운 방법은 기본설정을 모두 가지고 있는 Xcode template을 사용하여 추가하는 방법이다.

 

Xcode프로젝트에 타겟을 추가하려면 File > New > Target를 선택. Application Extension for iOS 또는 macOS 를 선택. 그러면 다음 그림에서처럼 선택가능한 템플릿들이 나온다. 

 

 

 

템플릿을 선택하면 익스텐션코드를 수정하기 전에 빌드하고 실행해볼수 있다. 빌드가 완료되면 .appex로 끝나는 익스텐션번들을 얻을 수 있다.

 

대부분 디폴튼 익스텐션을 시스템프리퍼런스나 셋팅에서 활성화함으로써 다른앱을 통해서 접근하여 테스트가 가능하다. 예를 들어 OS X extension을 사파리에서 웹페이지를 오픈하고 툴바의 공유버튼을 선택할 수 있고 이 때 나타나는 당신의 익스텐션을 선택 가능하다.

 

디폴트익스텐션 템플릿 살펴보기

 

각 익스텐션템플릿은 Info.plist, 하나의 view controller클래스 그리고 기본 UI를 포함하고 있으며 이것들은 익스텐션포인트에서 정의된 것들이다. 기본 view controller 클래스(또는 기반클래스)는 반드시 구현해야 하는 필수 메서드들을 가질 수 있다.

 

앱익스텐션포인트 타겟의 Info.plist에 익스텐션에 대한 상세한 정보를 포함할 수 있다. NSExtension키가 기본으로 있으며 Dictionary로 키/값쌍으로 익스텐션포인트를 기술한다. 예를 들어 NSExtensionPointIdentifier 키는 익스텐션포인트의 리버스 DNS명이다. 다음은 NSExtension 딕셔너리에서 볼 수 있는 키/값들이다.

 

- NSExtensionAttributes 익스텐션포인트에 해당하는 속성들의 딕셔너리로 PhotoEditing익스텐션의 경우 PHSupportedMediaTypes가 예이다.

- NSExtensionPrincipalClass 템플릿에서 생성하는 기본뷰컨트롤러 클래스의 이름으로 SharingViewController같은 호스트앱이 익스텐션을 호출할때 이 클래스를 인스턴스화하게 된다.

- NSExtensionMainStoryboard(iOS 익스텐션만 해당)  기본 스토리보드파일, MainInterface로 보통 명명됨

 

Info.plist외에 일부 capability가 추가될 수 있다. iOS Document Provider익스텐션의 경우 com.apple.security.application-groups 인타이틀먼트를 포함한다.

 

모든 OS X 앱익스텐션 템플릿들은 App Sandbax와 com.apple.security.files.user-selected.read-only 인타이틀먼트를 기본으로 포함한다. 익스텐션이 네트웍이나 연락처의 사진에 접근한다면 추가적인 capability  를 포함해야 한다.

 

 

 호스트앱의 요청에 응답하기.

 

호스트앱에서 유저가 익스텐션을 선택하면 익스텐션이 오픈되고 호스트앱의 요청이 발생한다. 고수준에서는 익스텐션은 이 요청을 받게되며 유저의 작업을 수행하고 사용자의 액션에 따라 요청을 완료하거나 취소한다. 

공유익스텐션의 경우 호스트앱의 요청을 받아서 표시된 뷰에서 응답한다. 유저가 내용을 구성하고 포스트 전송 또는 취소를 선택하면 익스텐션은 완료 또는 취소를 처리한다.

 

호스트앱이 요청을 전달하면 거기에는 익스텐션의 컨텍스트를 기술한다. 많은 익스텐션에서 익스텐션 컨텍스트에서 중요한 부분은 익스텐션에서 원하는 작업에 대한 아이템을 기술하는 것이다. 예를 들어 OS X 공유 익스텐션의 컨텍스트는 유저가 포스팅하는데 필요한 선택된 테스트가 될것이다.

 

호스트앱의 요청이 발생하면 앱익스텐션은 기반 뷰컨트롤러의 extensionContext프로퍼티를 컨텍스트를 얻기 위해 사용할 수 있다. 자식뷰컨트롤러 역시 체이닝을 통해 이 프로퍼티에 접근 할 수 있다.

 

이어서 NSExtensionContext클래스로 컨텍스트의 아이템을 사용할 수 있다.  뷰컨트롤러의 loadView메서드에서 컨텍스트와 아이템에 접근할 수 있으며 이 정보를 뷰에 표시할 수 있다. 다음과 같이 이 작업을 수행할 수 있다.

 

  1. NSExtensionContext *myExtensionContext = self.extensionContext;

컨텍스트 객체의 inputItems에 익스텐션에서 필요한 아이템들이 있다. NSExtensionItem객체의 배열을 답고 있으며 다음과 같이 사용 가능하다.

 

  1. NSArray *inputItems = myExtensionContext.inputItems;

각 NSExtensionItem객체는 아이테믜 유형을 설명하는 여러개의 프로퍼티(title, content text, attachment, userInfo등)를 담고 있다. 

 

attachments 프로퍼티는 아이템과 관련된 미디어데이터 배열을 포함한다. 공유요처어의 경우 유저가 공유하고자 하는 웹페이지의 표현이 포함될수 있다.

 

input items 으로 작업 후 보통 유저에게 테스크를 완료 혹은 취소를 선택하도록 한다. 유저의 선택에 따라 completeRequestReturningItems:completionHandler: 메서드를 호출하는데 NSExtensionItem객체를 추가로 반환할 수 있고 cancelRequestWithError:메서드로 에러코드를 반환할 수 있다.

 

iOS에서 앱익스텐션이 잠재적으로 긴 작업을 완료하기 위해 긴 시간이 필요할 수 있다. 웹사이트에 컨텐츠를 업로드할 때 가 해당된다. 이럴경우 NSURLSession클래스로 백그라운드에서 전송을 시작할 수 있다. 백그라운드 전송이 ㅂ ㅕㄹ도의 프로세스를 사용하기 때문에 전송은 계속될 수 있고 낮은 우선순위의 테스크로 처리되고 익스텐션이 완료된 후 종료된다.

 

업로드/다운로드 이외의 VoIP, 오디오 백그라운드 재생같은 백그라운드 작업은 불가하다. 만일 UIBackgroundModes키를 익스텐션의 Info.plist에 기술한다면 AppStore에서 리젝될것이다.

 

효율성 및 성능 최적화

 

앱익스텐션은 유저에게 빠르고 가벼운 느낌을 주어야 한다. 1초이내의 빠르게 적재되도록 앱익스텐션을 설계해야 한다.

 

포그라운드앱의 메모리제한보다 앱익스텐션은 훨씬 더 적게 사용해야 한다. 두 플랫폼에서 모두 시스템은 유저가 호스트엡의 주목적에 맞게 돌아가기를 원하기 때문에 익스텐션을 적극적으로 종료할것이다. 일부 익스텐션은 더 적은 메모리를 사용한다. 예로 위젯은 동시에 유저가 몇개의 위젯을 열수도 있기 때문에 더 효율적이어야 한다.

 

앱익스텐션은 자신의 메인 루프를 가지고 있지 않기 때문에 메인루프에서 적절한 동작을 하려면 설정된 룰을 따라야 한다. 예로 익스텐션이 메인루프를 블럭한다면 이는 다른 익스텐션이나 앱에세 좋지않은 사용자경헙을 선사하게 될것이다.

 

GPU는 시스템에서 리소스를 공유한다는 것을 상기해야 한다. 공유리소스에 대해 앱익스텐션은 우선순위가 낮다. 예로 투데이 위젯이 그래픽이 강조된 게임에서 사용된다면 아주 나쁜 결과를 초래할것이다. 메모리가 부족해지면 시스템은 이런 익스텐션을 죽이려고 한다.  시스템리소스를 많이 사용하는 기능은 앱이 적합하며 앱익스텐션은 그렇지 않다.

 

간소화된 UI설계

 

대부분의 앱익스텐션은 당신의 익스텐션을 오픈할때 보게되는 커스텀UI를 제공해야 한다. UI는 단순하고 억제되고 단일작업을 촉진하는데 집중해야 한다. 성능과 UX를 개선하고자 한다면 익스텐션이 제공하는 기능을 지원하지 않는 추가적인 UI는 피해야 한다.

 

Xcode 앱익스텐션 템플릿은 시작하는데 필요한 UI를 제공한다.

 

아이콘은 일관성과 가독성을 위해 포함하는 앱과 동일한게 좋다. 

 

액션익스텐션은 포함하는 앱의 아이콘의 이미지버전을 사용한다. 반드시 제공되어야 한다.

 

공유익스텐션은 자동으로 포함하는 앱의아이콘을 갖는다. 공유익스텐션 타겟에 다른 아이콘을 제공해도 Xcode는 이를 무시한다. 

나머지 다른 익스텐션들도 앱의 아이콘을 제공해야 한다.

 

앱익스텐션 이름은 짧고 가독성좋은 이름이어야 하며 포함하는 앱의 이름을 포함해야 한다. 패턴은 <포함하는앱이름>-<앱익스텐션이름>이다. 이는 유저가 시스템에서 쉽게 다룰수 있게 해준다. 옵션으로 포함하는앱이름을 사용해도 되는 경우가 있는데 이 경우는 오직 하나의 익스텐션만 제공하는 앱의 경우이다.

 

앱익스텐션이름은 타겟의 CFBundleDisplayName값이다. 이 값을 지정하지 않으면 CFBundleName값이 사용되며 포함하는 앱이름이 된다.

 

로컬화된 앱익스텐션으로 다국어가 적용된 앱익스텐션이름을 제공할 수 있다.

 

일부 앱익스텐션은 짧은 설명글이 필요할 수 있는데 OS X 위젯의 경우 투데이 뷰에서 보기를 원하는 위젯을 선택하는데 도움을 준다. InfoPlist.strings 파일에서 widget.description키의 값을 편집하면 된다.

 

모든 디바이스에서 iOS 앱익스텐션 지원하기

 

universal을 반드시 지원해야 한다. 아이폰, 아이팟터치, 아이패드등에서 모두 가능해야 한다. 포함하는 앱이 어떤 디바이스를 타겟으로 하는것과는 무관하다. Xcode 앱익스텐션 템플릿은 유니버셜로 설정되어 있다.

 

Xcode 빌드설정에서 디바이스패밀리를 "Universal"로 지정해야 한다.

 

 

AutoLayout과 size클래스를 UI 디자인시 적용한다. 그러면 모든 디바이스 사이즈와 방향에 대응될것이다. 

 

 

디버그, 프로파일링 그리고 테스트

 

앱익스텐션디버그는 다른 프로세스 디버깅하는 방법과 한가지만 제외하고 아주 비슷하다. 앱익스텐션의 Run phase에서 실행파일로 호스트앱을 지정한다. 지정한 호스트앱의 UI로 앱익스텐션에 접근하면 Xcode 디버거가 익스텐션에 연결한다.

 

Xcode 앱익스텐션 템플릿의 scheme에서 Ask On Launch 옵션이 사용된다. 이 옵션을 사용하면 앱을 빌드하여 실행할 때 마다 어떤 호스트앱을 사용할지 지정할 수 있다. 이렇게 하지 않고 개별적으로 호스트를 지정하고 싶다면 scheme editor에서 info tab의 app extension scheme's Run phase를 이용한다.

 

다음은 앱익스텐션에 Xcode debugger를 연계하는 절차이다.

 

1. Produce > Scheme > MyExtensionName 또는 toobar의 MyExtensionName 의 scheme 팝업메뉴 선택

2. 지정한 호스트앱을 시작하기 위해 Build and Run 버튼 선택

3. 호스트앱의 UI에서 앱익스텐션 호출하면 Xcode 디버거가 앱익스텐션의 프로세스에 연결되고 브레이크포인트가 활성화되고 익스텐션이 시작된다. 그러면 다른 프로세스의 디버깅할떄와 동일하게 디버깅 가능하다.

 

디버깅전에 익스텐션 scheme이 선택되어 있는지 확인해야. 앱의 scheme을 선택하면 앱익스텐션 디버깅이 아니고 앱디버깅이다.

 

OS X에서 호스트앱 테스트 및 디버깅으로 접근하기 전에 앱익스텐션활성화 단계를 수행해야 한다. 시스템 프리퍼런스의 익스텐션 페인에서 대부분의 익스텐션타입을 활성화 하라. 공유나 액션메뉴의 More를 선택하여 익스텐션 페인을 오픈할수도 있다.

 

OS X 투데이위젯을 위해 위젯시뮬레이터로 테스트 및 디버깅할 수 있다.

 

iOS에서 커스텀 키보드를 위해 Settings > General > Keyboard > Keyboards에서 활성화해야 한다.

 

OS X 디버깅 세션 동안에 Xcode는 빌드된 앱익스텐션을 등록한다. 이는 개발버전을 OS X에 설치하려면 FInder로 빌드위치에서 애플리케이션폴더같은 위치로 복사해야 한다. 

 

Xcode 디버깅콘솔로그에서 앱익스텐션 바이너리는 CFBundleDisplayName프로퍼티값 대신에 CFBundleIdentifier프로퍼티값이 사용된다.

 

앱익스텐션이 효율적이고 응답성이 있어야 하기 때문에 앱익스텐션 동작중에 디버그네비게이터의 디버그게이지를 살피는것이 좋다. 디버그 게이지는 CPU, 메모리, 다른 시스템리소스들의 사용량을 볼수 있게 해준다. 성능이슈의 증거를 보게 된다면 앱익스텐션을 프로파일하기 위해 instrument를 사용할 수 있고 향상된 부분을 확인할수도 있다. 

 

앱배포

 

포함하는 앱없이 스토어에 앱익스텐션을 배포할수 없으며 다른앱으로 이전할수도 없다.

 

iOS 앱익스텐션을 배포하려면 포함하는 앱을 스토어에 배포해야 한다.

OS X 앱익스텐션을 배포하려면 스토어에 포함하는 앱을 배포하는것이 추천되나 필수는 아니다.

 

Mac App Store가 아닌 다른 채널로 OSX 앱익스텐션을 배포하면 Getekeeper가 유저가 오픈할 때 걸러내게 되며 포함하는 앱을 승인한다. 또한 개발자 ID외의 인증서로 서명된 경우 사용자는 Gatekeeper를 명시적으로 재정의하여 익스텐션을 사용할수 있도록 포함앱을 열어야 한다.

 

리뷰를 통과하려면 포함하는앱은 유저에게 기능을 제공해야 한다. 앱익스텐션만 제공할수는 없다.

 

Posted by 삼스
iOS2020. 7. 28. 13:54

앱익스텐션은 앱이 아니며 제한되고 잘 범위지어진 정책으로 정의된 각각 익스텐션포인트에 맡게 구현된다.

 

앱익스텐션 생명주기

 

앱이 아니기 때문에 생명주기나 환경이 앱과 다르다. 대개는 뷰컨트롤러에서 표시된 앱의 UI로부터 유저에게 선택되어졌을때 시작된다. 앱익스텐션을 선택하여 실행해주는 앱을 호스트앱이라고 칭한다. 호스트앱은 앱에 제공되는 컨텍스트를 제공하며 유저의 액션의 응답으로써 리퀘스트가 전달될 때 익스텐션의 생명주기가 시작된다. 그리고 호스트앱으로부터 전달받은 요청을 모두 처리하게 되면 익스텐션도 종료된다.

 

예를 들어 OS X 호스트앱에서 텍스트일부를 선택했다고 상상해보자, 공유버튼이 활성화 되고 텍스트를 공유할 수 있는 공유목록에서 익스텐션하나를 선택한다. 호스트앱은 유저의 선택에 응답으로 선택한 테스트를 포함하는 요청을 앱익스텐션에 전달하게 된다. 이 상황에 대한 일반화한 다음 그림을 참고하라.

 

 

 

그림의 step2에서 시스템은 호스트앱의 요청을 포함하는 앱익스텐션의 인스턴스를 만들고 서로간의 통신채널을 셋업한다. 익스텐션은 호스트앱의 컨텍스트내에서 표시되어지고 작업을 수행하기 위한 호스트앱 요청을 수신한다(여기서는 선택한 텍스트이다).

 

그림의 step3에서 유저는 수행하거나 취소할 수 있고 닫을수도 있다. 이 액션의 응답으로 익스텐션은 유저의 작업을 바로 수행함으로 써 호스트앱의 요청을 완료하거나 필요하다면 백그라운드 프로세스로 수행한다. 호스트앱은 익스텐션뷰를 떼어내게 되고 유저는 이전 컨텍스트로 돌아가게 된다. 익스텐션의 작업이 끝나면 바로 또는 후에 결과가 호스트앱에 반환될것이다.

 

step4처럼 앱익스텐션의 작업을 수행한 후 시스템은 익스텐션을 종료한다.

 

 

앱익스텐션 통신

 

앱익스텐션은 기본적으로 호스트앱과 통신한다. 그리고 트랜잭션프로세싱처럼 동작한다. 호스트앱에서 요청을 보내고 앱익스텐션에서 응답을 받는다.다음 그림에서 호스트앱에서 시작된 실행중인 익스텐션과 이를 포함하는 앱간의 관계를 보여준다.

 

 

 

앱익스텐션과 이를 포함하는 앱간에 직접적인 통신은 없다 포함하는 앱은 포함된 익스텐션이 수행중에 실행되지 않는다. 포함하는 앱은 호스트앱과 통신하지 않는다.

 

일반적인 요청/응답의 트랜잭션처럼 시스테메서 호스트앱대신에 앱익스텐션을 오픈하며 호스트에서 제공하는 익스텐션컨텍스의 데이터를 전달한다. 익스텐션은 UI를 표시하고 작업을 수행한다. 그리고 익스텐션의 목적에 부합하는 데이터를 호스트에 반환한다.

 

그림에서 점선은 익스텐션과 포함하는 앱간에 유효한 상호작용이 제한된다는것을 의미한다. 투데이위젯은 시스템에 포함하는 앱의 오픈을 요청할 수 있는데 NSExtensionContext 클래스의 openURL:completionHandler: 메서드로 가능하다.

 

아래 그림에서 Read/Write 화살표를 보면 앱익스텐션과 포함하는 앱은 private으로 정의된 shared container에 공유된 데이터에 접근할 수 있다.

 

 

 

앱익스텐션에서 할수 없는 것들

 

시스템에 그 책임이 집중되기 때문에 앱익스텐션은 일부 작업은 불가하다. 아래 나열한것들은 수행 불가하다.

 

- sharedApplication 객체에 접근 불가하여 이 객체의 모든 메서드사용불가

- NS_EXTENSION_UNAVAILABLE 메크로, 잘알고 있는 메크로 또는 유효하지 않는 프레임워크등의 사용 불가, 예) HealthKit, EventKit UI framework등

- 카메라, 마이크 사용불가

- 오랫동안 동작하는 백그라운드테스크 사용불가. (NSURLSession을 이용한 upload/download를 일으킬수 있고 포함하는 앱에 결과를 보고할 수 있다)

- AirDrop으로 데이터 수신할수 없음(UIActivityViewController로 데이터를 보내는것은 가능)

Posted by 삼스
iOS2020. 7. 28. 13:53

App Extension으로 영향력을 증대하기

 

앱익스텐션은 앱을 뛰어 넘어 컨텐츠와 기능을 더 확장할 수 있게 한다. 

임의작업을 활설화하기 위해 앱익스텐션을 작성할 수 있다. 예를 들어 브라우저에서 당신의 소셜서비스에 유저가 포스팅하도록 공유 익스텐션을 제공할 수 있다. 또는 유저가 좋아하는 팀을 따라잡기 위해 알림센터에서 현재 점수를 표시하는 투데이 위젯을 제공할 수 있다. 시스템 키보드를 대체하는 커스텀 키보드를 제공할 수도 있다.

 

iOS와 macOS에서 몇가지 타입의 앱익스텐션을 정의한다. 

앱익스텐션이 활성화된 하나의 시스템영역은 하나의 익스텐션포인트로 부른다. 

익스텐션포인트는 사용정책과 해당 영역에서 앱익스텐션을 생성할 때 사용하는 API들을 제공한다.

 

다음 표는 iOS와 macOS에서 제공하는 앱익스텐션의 목록을 제공하며 각 익스텐션의 익스텐션포인트를 예로 들고 있다.

 

Action(iOS, macOS; UI, nonUI)

- host앱에서 컨텐츠를 다루거나 표시한다.

Audio Unit(iOS, macOS; UI, nonUI)

- host앱에 전달할 오디오스트림을 생성하거나 host앱으로부터 오디오스트림을 받아서 수정 한 후 host앱으로 다시 전달한다.

Broadcast UI(iOS, tvOS)

Broadcast Upload(iOS, tvOS)

Call Directory(iOS)

- 전화번호를 구별하고 블럭한다. CallKit Framework로 구현 가능하다.

Content Blocker(iOS, macOS)

- 컨텐츠블로킹앱이 규칙을 업데이트 했는지 표시(UI없음)

Custom Keyboard(iOS)

- 시스템키보드를 대체함.

Document Provider(iOS; ui, nonUI)

- 파일저장소에 접근하고 조작한다.

Finder Sync(macOS)

- Finder에 파일 동기화 상태를 바로 반영(Ui없음)

Game App(watchOS)

- Apple Watch에서 게임앱을 작성할 수 있게 해줌.

iMessage(iOS)

- 메세지앱과 상호작용

Intents(iOS)

- Siri와 통합하여 작업을 처리할 수 있다. SiriKit Programming Guide참조

Notification Content(iOS)

Notification Service(iOS)

Photo Editing(iOS, macOS)

- 사진앱으로 사진이나 비디오를 편집

Share(iOS, macOS)

- wetsite나 컨텐츠들을 공유하는 포스팅

Smart Card Token(macOS)

Spotlight Index(iOS)

- 앱 동작 중이 아닌동안에 앱의 컨텐츠를 인덱스함

Sticker Pack(iOS)

- 사용자가 메세지앱에서 사용할 수 있는 스티커셋을 제공

Today(iOS, macOS)

- 알림센터의 투데이에 빠르게 업데이트하거나 빠르게 태스크를 수행

TV Services(tvOS)

VPN(iOS, macOS)

- VPN client

WatchKit App(watchOS)

- 애플워치를 위한 알림UI나 앱을 제공

Xcode Source Editor(macOS)

 

시스템에서 각 앱익스텐션에 대한 제한된 영역을 정의하기 때문에 작성하려고 하는 앱에 가장 적합한 영역을 선택하는것이 중요하다. 경험공유를 활성하한 앱을 작성하고자 한다면 Share Extension Xcode template로 시작하여 공유익스텐션포인트를 사용해야 한다.

 

앱익스텐션과 앱은 구별된다.

 

앱에 익스텐션을 추가하고 배포한다고 해도 앱익스텐션은 바이너리가 분리되고 앱과 독립적으로 동작한다.

 

앱익스텐션은 새로운 타겟으로 생성하게 된다. 다른 타겟들 처럼 익스텐션타겟도 각각 셋팅과 빌드에 포함되는 파일들을 지정하게 된다. 하나의 앱에 여러개의 익스텐션타겟을 추가할 수 있다.

 

익스텐션개발을 시작하는 가장 좋은 방법은 xcode가 제공하는 템플릿으로 시작하는 것이다. 각 템플릿들은 익스텐션포인트에 맞는 구현파일과 셋팅을 포함한다.

 

유저에 앱익스텐션을 배포하려면 앱스토어에 앱과함께 제출하면 된다. 유저가 앱설치 시 익스텐션도 함께 설치된다.

 

앱익스텐션을 설치한 후 유저는 반드시 활성화하는 액션을 수행해야 한다. 유저는 유형에 따라 익스텐션을 활성화할 수 있다. 예를 들어 투데이위젯 익스텐션인 경우 유저는 익스텐션을 활성화 하기 위해 알림센터의 투데이뷰를 편집할 수 있다. 혹은 어떤 경우는 iOS는 설정에서 macOS는 시스템프리퍼런스에서 활성화 할 수 있다.

 

각 앱익스텐션 타입별로 서로 다른 작업유형을 활성화함에도 불구하고 대부분의 익스텐션에 공통적인 UX 부분이 있다. 가장 훌룡한 UX는 빠르고 이어지고 하나의 작업에 집중하는 것이다.

 

유저는 시스템에서 제공되는 일련의 UI에 반을하여 당신의 앱익스텐션을 오픈하게 된다. 예를 들어 공유익스텐션은 시스템에서제공되는 공유버튼에 의해 표시된 목록에서 당신의 앱익스텐션을 선택함으로써 비로소 활성화된다.

 

대부분의 앱익스텐션이 자체 커스텀 UI요소를 갖고 있지만 앱익스텐션에 진입하기 전까지 유저는 커스텀UI를 보지 않는다. 유저가 당신의 앱익스텐션에 진입할 때 당신의 커스텀 UI는 사용자에세 새로운 맥락으로 이동되었다는것을 알게 한다. 현재 사용중인 앱과 당신의 익스텐션을 구분할 수 있기 때문에 오동작하거나 제대로 수행하지 못하는 액스텐션을 삭제할 수 있게 해준다.

 

 

 

Posted by 삼스