파일 유형을 iPhone 응용 프로그램과 어떻게 연결합니까?


318

iPhone 앱을 파일 형식과 연결하는 주제.

에서 정보를 질문 나는 앱은 사용자 정의 URL 프로토콜과 연관 될 수 있다는 것을 배웠습니다.

거의 1 년 전부터 애플은 '문서 지원'을 도입하여 한 단계 더 나아가 앱이 파일 형식과 연결할 수 있도록했습니다. 문서 에 알 수없는 파일 형식이있을 때 다른 적절한 앱을 시작하도록 앱을 설정하는 방법에 대한 설명 이 많이 있습니다 . 이는 URL 프로토콜 등록과 같이 모든 앱에서 연결이 즉시 작동하지 않음을 의미합니다.

이로 인해 문제가 발생합니다. Safari 또는 Mail과 같은 시스템 응용 프로그램이 관련 응용 프로그램을 선택하기 위해이 시스템을 구현 했습니까, 아니면 이전과 같이 아무 것도 수행하지 않습니까?

답변:


408

파일 유형 처리는 iPhone OS 3.2의 새로운 기능이며 기존의 사용자 정의 URL 체계와 다릅니다. 특정 문서 유형을 처리하기 위해 응용 프로그램을 등록 할 수 있으며, 문서 제어기를 사용하는 모든 응용 프로그램은 이러한 문서 처리를 사용자 고유의 응용 프로그램으로 전달할 수 있습니다.

예를 들어, 내 응용 프로그램 Molecules (소스 코드를 사용할 수있는)는 전자 메일이나 다른 지원되는 응용 프로그램을 통해 수신 된 경우 .pdb 및 .pdb.gz 파일 형식을 처리합니다.

지원을 등록하려면 Info.plist에 다음과 같은 것이 있어야합니다.

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeIconFiles</key>
        <array>
            <string>Document-molecules-320.png</string>
            <string>Document-molecules-64.png</string>
        </array>
        <key>CFBundleTypeName</key>
        <string>Molecules Structure File</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSHandlerRank</key>
        <string>Owner</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>com.sunsetlakesoftware.molecules.pdb</string>
            <string>org.gnu.gnu-zip-archive</string>
        </array>
    </dict>
</array>

Mail 및 문서를 표시 할 수있는 기타 응용 프로그램에서 지원되는 유형의 아이콘으로 사용될 두 개의 이미지가 제공됩니다. 이 LSItemContentTypes키를 사용하면 응용 프로그램에서 열 수있는 UTI (Uniform Type Identifier) ​​배열을 제공 할 수 있습니다. 시스템 정의 UTI 목록은 Apple의 Uniform Type Identifiers Reference를 참조하십시오 . UTI에 대한 자세한 내용은 Apple의 Uniform Type Identifiers Overview를 참조하십시오 . 이 기능은 Mac에서 이식 되었기 때문에이 안내서는 Mac 개발자 센터에 있습니다.

위 예제에서 사용 된 UTI 중 하나는 시스템 정의이지만 다른 하나는 응용 프로그램 별 UTI입니다. 시스템의 다른 응용 프로그램이이를 인식 할 수 있도록 응용 프로그램 별 UTI를 내 보내야합니다. 이렇게하려면 Info.plist에 다음과 같은 섹션을 추가하십시오.

<key>UTExportedTypeDeclarations</key>
<array>
    <dict>
        <key>UTTypeConformsTo</key>
        <array>
            <string>public.plain-text</string>
            <string>public.text</string>
        </array>
        <key>UTTypeDescription</key>
        <string>Molecules Structure File</string>
        <key>UTTypeIdentifier</key>
        <string>com.sunsetlakesoftware.molecules.pdb</string>
        <key>UTTypeTagSpecification</key>
        <dict>
            <key>public.filename-extension</key>
            <string>pdb</string>
            <key>public.mime-type</key>
            <string>chemical/x-pdb</string>
        </dict>
    </dict>
</array>

이 특정 예 com.sunsetlakesoftware.molecules.pdb는 MIME 유형에 해당하는 .pdb 파일 확장자로 UTI 를 내 보냅니다 chemical/x-pdb.

이를 통해 응용 프로그램은 전자 메일 또는 시스템의 다른 응용 프로그램에 첨부 된 문서를 처리 할 수 ​​있습니다. Mail에서 길게 누르면 특정 첨부 파일을 열 수있는 응용 프로그램 목록이 나타납니다.

첨부 파일이 열리면 응용 프로그램이 시작되고 -application:didFinishLaunchingWithOptions:응용 프로그램 대리자 메서드 에서이 파일의 처리를 처리해야합니다 . Mail에서 이러한 방식으로로드 된 파일은 도착한 이메일 상자에 해당하는 서브 디렉토리 아래에있는 애플리케이션의 문서 디렉토리로 복사 된 것으로 보입니다. 다음과 같은 코드를 사용하여 애플리케이션 위임 메소드 내에서이 파일의 URL을 얻을 수 있습니다.

NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];

이는 맞춤 URL 체계를 처리 할 때 사용한 것과 동일한 방식입니다. 다음과 같은 코드를 사용하여 파일 URL을 다른 URL과 분리 할 수 ​​있습니다.

if ([url isFileURL])
{
    // Handle file being passed in
}
else
{
    // Handle custom URL scheme
}

9
주목해야한다 -application:didFinishLaunchingWithOptions:이 파일을 처리하기 위해 열 때 앱이 백그라운드로되지 않은 경우 응용 프로그램 위임 만이라고합니다.
memmons

3
QuickLook 피하기 : raywenderlich.com/1980/…
TheLearner

4
우리는 - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)urliOS 4+에서도 사용해야합니다
Dmitry

1
'CFBundleTypeExtensions'키는 어떻습니까? 스 니펫이 설정하지 않은 것 같습니다. 필요하지 않습니까?
Bram

3
나는 여기와 다른 곳에서 제공되는 모든 방법론을 시도했지만 여전히 PNG 파일을 열기 위해 고심하고 있습니다. 나는 iOS 7에서 일하고 있습니다. 어떤 곳에서는이 문제가 iOS 6에서 시작된다고 말합니다. iOS 7의 "에서 열기"대화 상자에서 png 파일을 열 수 없습니까?
Kumar Aditya

24

Brad의 탁월한 답변 외에도 Mail 앱에서 사용자 정의 파일을 열 때 (iOS 4.2.1 이상) 첨부 파일을 열었을 때 앱이 실행되거나 알림을받지 않는다는 것을 알았습니다. "다음으로 열기…"팝업이 나타나지만 아무 것도 수행하지 않습니다.

이것은받은 편지함 디렉토리에서 파일을 (재) 이동하여 수정 된 것으로 보입니다. 안전한 접근 방법은 파일을 열 때 (in -(BOOL)application:openURL:sourceApplication:annotation:) 파일을 이동하거나 ( Documents / Inbox) 디렉토리를 통과하여 (예 : in) 모든 항목을 제거하는 것입니다 applicationDidBecomeActive:. 이전 가져 오기로 인해 충돌이 발생하거나 중단 된 경우 앱을 다시 깨끗한 상태로 유지하려면 마지막 catch-all이 필요할 수 있습니다.


6
이 동작이 보이지 않습니다. 내 앱이 백그라운드 인 경우 -(BOOL)application:openURL:sourceApplication:annotation:이미 열려있는 첨부 파일에 대해서도 항상 호출됩니다. 첨부 파일을 열 때마다 파일 이름의 접미사가 붙고 숫자는 test.text, test-1.txt, test-
2.txt

받은 편지함 디렉토리가 비어 있지만 Safari에 응답하지 않는 "열기"단추가 있습니다. 몇 년 전 내 앱이 제대로 작동했지만 갑자기 작동이 멈췄습니다. 애플이 사파리에서 무언가를 바꿨다고 생각합니다.
Bram

18

큰 경고 : 하나의 백분율로 확장 기능이 이미 일부 MIME 유형에 연결되어 있지 않은지 확인하십시오.

우리는 기본적으로 사용자 정의 파일에 확장자 '.icz'를 사용했으며, Safari는 "Safari가이 파일을 열 수 없습니다."라고 말하지 않습니다. 우리가 위의 UT와 함께 무엇을했거나 시도했는지에 관계없이.

결국 나는 다양한 것들을 탐구하는 데 사용할 수있는 UT * C 함수가 있다는 것을 깨달았으며 .icz는 올바른 대답 (우리의 앱)을 제공합니다.

앱에서 맨 위에로드되었습니다.이 작업을 수행하십시오 ...

NSString * UTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, 
                                                                   (CFStringRef)@"icz", 
                                                                   NULL);
CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

그 줄 뒤에 휴식을 취하고 UTI와 ur가 무엇인지 확인하십시오. 우리의 경우 원하는 식별자 였고 번들 URL (ur)은 앱 폴더를 가리키고있었습니다.

그러나 Dropbox가 우리에게 링크를 제공하는 MIME 유형은 예를 들어 확인할 수 있습니다.

$ curl -D headers THEURLGOESHERE > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 27393  100 27393    0     0  24983      0  0:00:01  0:00:01 --:--:-- 28926
$ cat headers
HTTP/1.1 200 OK
accept-ranges: bytes
cache-control: max-age=0
content-disposition: attachment; filename="123.icz"
Content-Type: text/calendar
Date: Fri, 24 May 2013 17:41:28 GMT
etag: 872926d
pragma: public
Server: nginx
x-dropbox-request-id: 13bd327248d90fde
X-RequestId: bf9adc56934eff0bfb68a01d526eba1f
x-server-response-time: 379
Content-Length: 27393
Connection: keep-alive

콘텐츠 유형은 우리가 원하는 것입니다. Dropbox는 이것이 텍스트 / 달력 항목이라고 주장합니다. 큰. 그러나 필자의 경우 이미 앱의 MIME 유형에 텍스트 / 캘린더를 입력하려고 시도했지만 여전히 작동하지 않습니다. 대신 text / calendar mimetype에 대한 UTI 및 번들 URL을 얻으려고하면

NSString * UTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
                                                                   (CFStringRef)@"text/calendar", 
                                                                   NULL);

CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

"com.apple.ical.ics"를 UTI로, "... / MobileCoreTypes.bundle /"을 번들 URL로 봅니다. 우리의 앱이 아니라 애플입니다. 따라서 com.apple.ical.ics를 내 항목과 함께 LSItemContentTypes에 내보내고 UTConformsTo에 내보내려고하지만 아무 것도 시도하지 않습니다.

따라서 기본적으로 Apple이 특정 시점에서 파일 형식의 형식을 처리하려고한다고 생각하면 (응용 프로그램이 활성화 된 후 10 년이 지나면 생성 될 수 있습니다.) 확장 원인을 변경해야합니다. 파일 타입


유용한 경고에 감사드립니다!
RockSolid

0

내 APP에 대한 모든 유형의 파일을 처리하기 위해 CFBundleDocumentTypes에이 구성을 사용합니다.

    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeName</key>
            <string>IPA</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.item</string>
                <string>public.content</string>
                <string>public.data</string>
                <string>public.database</string>
                <string>public.composite-content</string>
                <string>public.contact</string>
                <string>public.archive</string>
                <string>public.url-name</string>
                <string>public.text</string>
                <string>public.plain-text</string>
                <string>public.source-code</string>
                <string>public.executable</string>
                <string>public.script</string>
                <string>public.shell-script</string>
                <string>public.xml</string>
                <string>public.symlink</string>
                <string>org.gnu.gnu-zip-archve</string>
                <string>org.gnu.gnu-tar-archive</string>
                <string>public.image</string>
                <string>public.movie</string>
                <string>public.audiovisual-​content</string>
                <string>public.audio</string>
                <string>public.directory</string>
                <string>public.folder</string>
                <string>com.apple.bundle</string>
                <string>com.apple.package</string>
                <string>com.apple.plugin</string>
                <string>com.apple.application-​bundle</string>
                <string>com.pkware.zip-archive</string>
                <string>public.filename-extension</string>
                <string>public.mime-type</string>
                <string>com.apple.ostype</string>
                <string>com.apple.nspboard-typ</string>
                <string>com.adobe.pdf</string>
                <string>com.adobe.postscript</string>
                <string>com.adobe.encapsulated-​postscript</string>
                <string>com.adobe.photoshop-​image</string>
                <string>com.adobe.illustrator.ai-​image</string>
                <string>com.compuserve.gif</string>
                <string>com.microsoft.word.doc</string>
                <string>com.microsoft.excel.xls</string>
                <string>com.microsoft.powerpoint.​ppt</string>
                <string>com.microsoft.waveform-​audio</string>
                <string>com.microsoft.advanced-​systems-format</string>
                <string>com.microsoft.advanced-​stream-redirector</string>
                <string>com.microsoft.windows-​media-wmv</string>
                <string>com.microsoft.windows-​media-wmp</string>
                <string>com.microsoft.windows-​media-wma</string>
                <string>com.apple.keynote.key</string>
                <string>com.apple.keynote.kth</string>
                <string>com.truevision.tga-image</string>
            </array>
            <key>CFBundleTypeIconFiles</key>
            <array>
                <string>Icon-76@2x</string>
            </array>
        </dict>
    </array>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.