July 02, 2021, TIL (Today I Learned) Data Delivery with Drag and Drop

Inwoo Hwang·2021년 8월 26일
0
post-thumbnail

Data Delivery with Drag and Drop ( feat WWDC 2017)


드래그앤 드랍을 활용하여 사용자는 아이패드 앱의 데이터를 같은 앱 또는 다른 앱으로 복사할 수 있습니다. 해당 데이터는 NSItemProvider 개체를 활용해서 공유됩니다.

NSItem Provider Basics

NSItem Provider는 데이터 약속입니다. 모든 드래그 앤 드랍 데이터는 비동기적으로 전달되고 NsItem Provider는 데이터의 progress 또는 cancellation을 제공합니다.

그렇다면 데이터를 약속하다 또는 제공하는 것은 어떤 것을 의미하는건가요?

NSItemProvider에게 데이터를 전달하는 것은 매우 심플합니다:

Screen Shot 2021-07-02 at 11.46.19 AM

NS itemProvider 객체를 생성한 뒤 적합한 object를 해당 객체에게 전달 해 주면 됩니다.

문자열에 들어가 있는 UIImage 과 같은 시스템이 제공하는 클래스들이 이런 object로 사용될 수 있습니다.

물론 프로그래머의 커스텀 클래스 또한 보내기 적합한 형태로 구현될 수 있습니다.[ 해당 내용은 Model Classes에서 자세하게 나와있습니다.]

이런 데이터를 제공하면 loadObject 메서드를 통해서 데이터를 전달 받을 수 있습니다.

Screen Shot 2021-07-02 at 11.52.34 AM

데이터 로딩 작업은 비동기적으로 이뤄지기 때문에 만약 UI를 업데이트 해야하는 경우 해당 작업은 메인 thread에서 실행해야 합니다.

WWDC 2017 예시

Screen Shot 2021-07-02 at 11.57.08 AM

canLoad() & loadObject()

해당 메서드들은 attributed string, url, image, 그리고 색상과 같은 다른 시스템타입에도 사용될 수 있습니다.

Progress & Cancellation

NSItemProvider를 활용하여 데이터를 받으면 NSItem은 프로그래머가 데이터 전달 상황을 추적할수 있는progress object를 반환합니다.

Screen Shot 2021-07-02 at 12.15.33 PM

progress 와 cancel은 KVO를 통해서 확인할 수 있고 프로그래머는 커스텀 캔슬 버튼과 activity indicator를 활용하여 진행상황을 체크하거나 데이터 전달을 취소할 수 있습니다.

만약 이 progress object에서 cancel 메서드를 실행하면 어떠한 데이터를 받던 콜백으로 error 처리를 해서 데이터 전달을 취소합니다.

One Progress object per load request

Overall Progress object from UIDropSession

하나의 NSProvider 객체는 == 사용자가 드래그앤드랍으로 이동하는 하나의 객체

Uniform Type Identifiers

Maximize Compatibility

우리는 다양한 앱으로부터 드래그된 아이템을 받을 수 있게 앱을 구현하기를 원하며 동시에 다양한 앱으로 드래그해서 데이터를 보내고자 합니다. 데이터의 호환성을 극대화 하기 위해서는 먼저 Uniform Type Identifier에 대해 이해하여야 합니다.

유저가 드래그하는 아이템을 다양한 데이터타입에 호환되도록 설정할 수 있습니다.

예를 들어 벡터를 그리는 프로그램에서는 해당 프로그램의 네이티브 파일포맷을 통해 최고의 퀄리티를 제공할 수 있지만 동시에 pdf, png, jpg 파일 포맷으로 변환하여 다양한 외부 앱으로 드래그 앤 드랍을 통해 데이터를 이동할 수도 있습니다.

Uniform type identifier라는 고유의 문자열을 변환되는 각 타입 포멧에 태그값을 줘서 드래그 된 아이템이 어떠한 데이터 타입인지 식별할 수 있게 합니다.

Screen Shot 2021-07-02 at 12.57.35 PM

네이티브 파일 포맷 같은 경우 프로그래머가 지정한 문자열 값을 태그로 줄 수 있고 그외 잘 알려진 pdf, png포멧 같은 경우 mobile core service에서 정의된 kuttype을 활용하여 태그 값을 줄 수 있습니다.

이렇게 uniform type으로 등록을 할 때는 등록하는 순서 또한 매우 중요합니다. 네이티브 포맷의 태그 부터 설정한 뒤 그 다음으로 중요한 순서대로 태그값을 주어야 합니다.

Screen Shot 2021-07-02 at 1.09.11 PM

UTI를 설정할 때 추상적인 타입 보다는 구체적인 타입의 태그값을 줘야 합니다. 수신자가 추상적인 태그 값보다 구체적인 데이터를 더 수월하게 해석하고 사용할 수 있기 때문입니다. 물론 커스텀 태그값일 경우 프로그래머가 자기 자신의 데이터 타입의 태그값을 임의로 지정할 수 있습니다.

Model Classes

특정 모델이 드래그앤드랍에 최적화 되기 위해서는 아래와 같은 두 가지 protocol이 필요합니다:

NSItemProviderReadingNSItemProviderWriting

NSItemProviderWriting: exports data from model object

즉 모델 개체로 부터 데이터를 내보냅니다.

NSItemProviderReading: reads the data and creates model object from data

Maintained with model classes, not UICode

받아온 데이터를 읽고 데이터를 통해 모델 개체를 다시 만들어 냅니다.

NSItemProvider Writing Protocol

Screen Shot 2021-07-02 at 1.15.53 PM

위 프로퍼티와 메서드를 채택하여야합니다.

하나씩 살펴봅시다

writableTypeIdentifiersForItemProvider: 데이터를 중요도 순서대로 전달할 때 사용되는 identifier list 입니다.

loadData(): 목적지 에서 요청한 type identifier를 갖고 call back으로 필요한 데이터 또는 에러를 전달하는 메서드입니다.

해당 프로토콜을 채택하여 UI code와 framework code는 아래와 같이 구성될 수 있습니다.

Screen Shot 2021-07-02 at 1.59.21 PM

NsItemProviderReading Protocol

Screen Shot 2021-07-02 at 2.25.32 PM

readabletypeIdentifiersForItemProvider:

해당 프로퍼티는 중요도 순서대로 나열된 데이터 태그 값입니다.

(the first is the readable type identifiers in fidelity order, also)

init() :

해당 이니셜라이저는 data block 또는 data 개체를 파라미터로 받아서 데이터를 인스턴스로 만들어줍니다.

(initializer that will take a NSdata block, ns data object, which should be used to initialize the instances of the object)

Screen Shot 2021-07-02 at 2.53.38 PM

canLoadObject 메서드를 통해 검증이 끝난 뒤 loadObject를 활용해서 framework는 보내는 쪽 그리고 받는 쪽의 type identifiers list를 검증하고 가장 적합한 퀄리티의 데이터가 받는 쪽 object의 인스턴스를 만드는데 사용되도록 합니다.

종합하자면...

드래그 앤 드랍에 용이한 모델을 만들기 위해서는

  • NSItemProvider Reading, NSItemProvider Writing을 순응하는 클래스를 만들어야 합니다.
  • 위 프로토콜은 Object-C 프로토콜이기 때문에 사용자 모델 또한 NSObject를 상속 받아야 합니다.
  • 위 요건이 맞춰지면 드래그앤드랍, UIPasteConfiguration 그리고 UIPasteboard에 사용될 수 있습니다.

Advanced Topics

Screen Shot 2021-07-02 at 4.18.19 PM Screen Shot 2021-07-02 at 4.16.57 PM Screen Shot 2021-07-02 at 4.19.27 PM
profile
james, the enthusiastic developer

0개의 댓글