ฉันจะเชื่อมโยงประเภทไฟล์กับแอปพลิเคชั่น iPhone ได้อย่างไร


318

ในเรื่องของการเชื่อมโยงแอพ iPhone กับประเภทไฟล์

ในคำถามที่ให้ข้อมูลนี้ฉันได้เรียนรู้ว่าแอปสามารถเชื่อมโยงกับโปรโตคอล URL ที่กำหนดเองได้

เกือบหนึ่งปีที่ผ่านมาและตั้งแต่นั้น Apple ได้เปิดตัว 'การสนับสนุนเอกสาร' ซึ่งจะไปอีกขั้นหนึ่งและอนุญาตให้แอปเชื่อมโยงกับประเภทไฟล์ มีจำนวนมากของการพูดคุยในเป็นเอกสารเกี่ยวกับวิธีการตั้งค่าของแอปพลิเคชันที่จะเปิดตัวอื่น ๆ ที่เหมาะสมเมื่อพบชนิดไฟล์ที่ไม่รู้จัก ซึ่งหมายความว่าการเชื่อมโยงไม่ได้ทำงานนอกกรอบสำหรับแอพใด ๆ เช่นเดียวกับการลงทะเบียนโปรโตคอล URL

สิ่งนี้ทำให้ฉันมีคำถาม: มีแอประบบเช่น Safari หรือ Mail ที่ใช้งานระบบนี้สำหรับการเลือกแอพพลิเคชั่นที่เกี่ยวข้องหรือพวกเขาจะไม่ทำอะไรเหมือนเมื่อก่อน?

คำตอบ:


408

การจัดการประเภทไฟล์นั้นใหม่กับ iPhone OS 3.2 และแตกต่างจากโครงร่าง URL ที่กำหนดเองที่มีอยู่แล้ว คุณสามารถลงทะเบียนแอปพลิเคชันของคุณเพื่อจัดการเอกสารบางประเภทและแอปพลิเคชันใด ๆ ที่ใช้ตัวควบคุมเอกสารสามารถส่งมอบการประมวลผลเอกสารเหล่านี้ไปยังแอปพลิเคชันของคุณเอง

ตัวอย่างเช่นแอปพลิเคชันของฉันโมเลกุล (ซึ่งมีซอร์สโค้ดอยู่) จัดการกับประเภทไฟล์. 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ที่สำคัญช่วยให้คุณให้อาร์เรย์ของตัวบ่งชี้ประเภท Uniform (อุทิศ) ที่โปรแกรมของคุณสามารถเปิด สำหรับรายชื่อของระบบกำหนดอุทิศให้ดูที่แอปเปิ้ลUniform ประเภทตัวบ่งชี้การอ้างอิง รายละเอียดเพิ่มเติมเกี่ยวกับการอุทิศสามารถพบได้ในแอปเปิ้ลUniform ประเภทภาพรวมของตัวบ่งชี้ คำแนะนำเหล่านั้นอยู่ในศูนย์นักพัฒนาของ Mac เพราะความสามารถนี้ได้รับการส่งผ่านจาก Mac

หนึ่งใน UTIs ที่ใช้ในตัวอย่างด้านบนคือกำหนดโดยระบบ แต่อีกตัวหนึ่งเป็น 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.pdbUTI มีนามสกุลไฟล์ .pdb chemical/x-pdbสอดคล้องกับชนิดไมม์

แอปพลิเคชันของคุณจะสามารถจัดการเอกสารที่แนบมากับอีเมลหรือจากแอปพลิเคชันอื่น ๆ ในระบบได้ ใน Mail คุณสามารถแตะค้างเพื่อแสดงรายการแอปพลิเคชันที่สามารถเปิดสิ่งที่แนบมา

เมื่อเปิดสิ่งที่แนบมาแอปพลิเคชันของคุณจะเริ่มต้นขึ้นและคุณจะต้องจัดการกับการประมวลผลของไฟล์นี้ใน-application:didFinishLaunchingWithOptions:วิธีการมอบหมายแอปพลิเคชันของคุณ ดูเหมือนว่าไฟล์ที่โหลดในลักษณะนี้จาก Mail จะถูกคัดลอกไปยังไดเรกทอรีเอกสารของแอปพลิเคชันของคุณภายใต้ไดเรกทอรีย่อยที่สอดคล้องกับกล่องอีเมลที่พวกเขาเข้ามาคุณสามารถรับ URL สำหรับไฟล์นี้ภายในวิธีมอบหมายตัวแทนโดยใช้รหัสดังนี้

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

โปรดทราบว่านี่เป็นวิธีการเดียวกับที่เราใช้ในการจัดการแบบแผน 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 *)urlบน iOS 4+
มิทรี

1
สิ่งที่เกี่ยวกับคีย์ 'CFBundleTypeExtensions' ข้อมูลโค้ดของคุณดูเหมือนจะไม่ตั้งค่า มันไม่จำเป็นหรือไม่
Bram

3
ฉันได้ลองวิธีการทั้งหมดที่มีให้ที่นี่และที่อื่น ๆ ด้วย แต่ฉันยังคงดิ้นรนเพื่อเปิดไฟล์ PNG ฉันกำลังทำงานกับ iOS 7 ในบางแห่งที่พวกเขาบอกว่าปัญหานี้เริ่มต้นด้วย ios 6 จริงหรือไม่? เราไม่สามารถเปิดไฟล์ png ในกล่องโต้ตอบ "เปิดใน" ด้วย ios 7 ได้หรือไม่?
Kumar Aditya

24

นอกเหนือจากคำตอบที่ยอดเยี่ยมของแบรดแล้วฉันพบว่า (บน iOS 4.2.1 เป็นอย่างน้อย) เมื่อเปิดไฟล์ที่กำหนดเองจากแอพ Mail แอพของคุณจะไม่ถูกยิงหรือได้รับการแจ้งเตือนหากมีการเปิดไฟล์แนบมาก่อน ป๊อปอัป "เปิดด้วย ... " ปรากฏขึ้น แต่ไม่ทำอะไรเลย

ดูเหมือนว่าจะได้รับการแก้ไขโดย (อีกครั้ง) การย้ายไฟล์จากไดเรกทอรีกล่องจดหมาย วิธีที่ปลอดภัยดูเหมือนจะเป็นการย้ายไฟล์ตามที่เปิดอยู่ (ใน-(BOOL)application:openURL:sourceApplication:annotation:) รวมถึงการเข้าไปในไดเรกทอรีเอกสาร / กล่องขาเข้าลบรายการทั้งหมดเช่นสิ่งapplicationDidBecomeActive:ต่อไปนี้ อาจต้องมีการตรวจจับครั้งสุดท้ายเพื่อให้แอปอยู่ในสถานะที่สะอาดอีกครั้งในกรณีที่การนำเข้าก่อนหน้านี้ทำให้เกิดความผิดพลาดหรือถูกขัดจังหวะ


6
ฉันไม่เห็นพฤติกรรมนี้ หากแอพของฉันเป็นแบ็คกราวน์-(BOOL)application:openURL:sourceApplication:annotation:จะมีการเรียกใช้เสมอแม้ว่าจะมีไฟล์แนบที่เปิดอยู่แล้วก็ตาม ทุกครั้งที่มีการเปิดสิ่งที่แนบมาหมายเลขจะถูกต่อท้ายชื่อไฟล์และจะเพิ่มขึ้นเป็นค่าที่ไม่ซ้ำกัน - test.text, test-1.txt, test-2.txt ฯลฯ
memmons

ไดเรกทอรี Inbox ของฉันว่างเปล่า แต่ฉันยังมีปุ่ม "เปิดใน" ใน Safari ที่คุณพูดถึง หลายปีที่ผ่านมาแอปของฉันทำงานได้ดี แต่ทันใดนั้นก็หยุดทำงาน ฉันสงสัยว่า Apple เปลี่ยนบางสิ่งใน Safari
Bram

18

คำเตือนที่ยิ่งใหญ่: ตรวจสอบให้แน่ใจว่า PERCENT หนึ่งร้อยเปอร์เซ็นต์ต้องแน่ใจว่าส่วนขยายของคุณไม่ได้เชื่อมโยงกับ mime บางประเภทแล้ว

เราใช้ส่วนขยาย '.icz' สำหรับไฟล์ที่กำหนดเองของเราโดยทั่วไปเคยและ Safari จะไม่ยอมให้คุณเปิดพวกเขาโดยบอกว่า "Safari ไม่สามารถเปิดไฟล์นี้ได้" ไม่ว่าเราจะทำหรือลองทำอะไรกับ UT

ในที่สุดฉันก็รู้ว่ามีฟังก์ชั่น UT * C บางอย่างที่คุณสามารถใช้เพื่อสำรวจสิ่งต่าง ๆ และในขณะที่. icz ให้คำตอบที่ถูกต้อง (แอพของเรา):

ในแอปโหลดที่ด้านบนเพียงทำสิ่งนี้ ...

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

และหยุดพักหลังจากบรรทัดนั้นและดูว่า UTI และ ur คืออะไร - ในกรณีของเรามันคือตัวระบุของเราตามที่เราต้องการ) และ url มัด (ur) ชี้ไปที่โฟลเดอร์แอปของเรา

แต่ประเภท MIME ที่ Dropbox ให้เรากลับมาที่ลิงก์ของเราซึ่งคุณสามารถตรวจสอบได้โดยทำเช่น

$ 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

Content-Type เป็นสิ่งที่เราต้องการ Dropbox อ้างว่านี่เป็นรายการข้อความ / ปฏิทิน ยิ่งใหญ่ แต่ในกรณีของฉันฉันได้ลองใส่ข้อความ / ปฏิทินลงในประเภท mime ของแอปของฉันแล้วและยังใช้งานไม่ได้ แต่เมื่อฉันพยายามรับ UTI และมัด URL สำหรับชนิดข้อความ / ปฏิทิน

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

CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

ฉันเห็น "com.apple.ical.ics" เป็น UTI และ "... / MobileCoreTypes.bundle /" เป็น URL มัด ไม่ใช่แอปของเรา แต่เป็น Apple ดังนั้นฉันลองใส่ com.apple.ical.ics ลงใน LSItemContentTypes ข้างๆของฉันเองและไปที่ UTConformsTo ในการส่งออก แต่ไม่ไป

ดังนั้นโดยทั่วไปถ้า Apple คิดว่าพวกเขาต้องการจัดการรูปแบบไฟล์บางรูปแบบ (ซึ่งสามารถสร้างได้ 10 ปีหลังจากที่แอปของคุณใช้งานได้คุณจะต้องคำนึงถึงคุณ) คุณจะต้องเปลี่ยนนามสกุลเพราะจะไม่ทำให้คุณจัดการได้ ประเภทไฟล์


ขอบคุณสำหรับคำเตือนที่มีประโยชน์!
RockSolid

0

ในการจัดการกับไฟล์ประเภทใด ๆ สำหรับแอพของฉันเองฉันใช้การกำหนดค่านี้สำหรับ 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.