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에게 데이터를 전달하는 것은 매우 심플합니다:

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

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

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

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

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

WWDC 2017 예시

canLoad() & loadObject()

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

Progress & Cancellation

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

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

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

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

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

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

하나씩 살펴봅시다

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

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

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

NsItemProviderReading Protocol

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)

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

종합하자면...

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

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

Advanced Topics

profile
james, the enthusiastic developer

0개의 댓글