Swift 4.2 UIDocumentBrowser View Controller Powerpoint PPTX files greyed out - swift

I'm using a Document Based App template in Xcode 10.1 with Swift. Out of the box, it doesn't support many file types, so I have added a number of Document Types including various Microsoft Office formats (doc, xls, ppt) which work fine. I have also added the open xml formats for docx, xlsx, and pptx. These also work fine with the exception of pptx which remains greyed out when running the app. I have also tried using the imported UTI section with no success. Here is an extract of the Info.plist, showing the docx and xlsx entries (which work) and the equivalent pptx entry which doesn't work.
These work:
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>wordx</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>org.openxmlformats.wordprocessingml.document</string>
</array>
</dict>
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>excelx</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>org.openxmlformats.spreadsheetml.sheet</string>
</array>
</dict>
Whilst this doesn't:
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>powerx</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHanderRank</key>
<string>Default</string>
<key>LSItemContentTypes</key>
<array>
<string>org.openxmlformats.presentationml.presentation</string>
</array>
</dict>
I've also tried an imported UTI with no success:
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.content</string>
</array>
<key>UTTypeDescription</key>
<string>powerpoint pptx</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>org.openxmlformats.presentationml.presentation</string>
<key>UTTypeTagSpecification</key>
<array>
<string>pptx</string>
<string>application/vnd.openxmlformats-officedocument.presentationml.presentation</string>
</array>
</dict>
</array>
Any help would be appreciated, thanks.

The UTI identifier for ppt files is com.microsoft.powerpoint.​ppt, as per the documentation here.
Therefore you could try:
<dict>
<key>CFBundleTypeIconFiles</key>
<array/>
<key>CFBundleTypeName</key>
<string>powerx</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHanderRank</key>
<string>Default</string>
<key>LSItemContentTypes</key>
<array>
<string>com.microsoft.powerpoint.​ppt</string>
</array>
</dict>

Related

How to get ppt file from iPhone mail and safari?

I want to read .ppt files from the iPhone mail app. I have already done read the PDF file using this SO question. It's working fine, and they used this code for generating the menu in the mail app:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>PDF Document</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.adobe.pdf</string>
</array>
</dict>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Powerpoint</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.microsoft.powerpoint.ppt</string>
</array>
</dict>
</array>
It's working fine. I googled the problem, but if someone could guide me how to detect .ppt files from mail attachments, that'd be helpful.
In order to use PPT files, you must declare your intent to conform to its UTI, which means simply changing the bit about com.adobe.pdf to com.microsoft.powerpoint.ppt. Easy.
For all intents and purposes, also change CFBundleTypeName to Powerpoint.
The issue here is that you shouldn't have duplicated the entire CFBundleDocumentTypes entry like you have for pdfs and ppts.
Rather, you only need one of these such blocks, and you simply want to add another CFBundleTypeName to the .
So, your plist should look like this:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>PDF Document</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.adobe.pdf</string>
</array>
</dict>
<dict>
<key>CFBundleTypeName</key>
<string>Powerpoint</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.microsoft.powerpoint.ppt</string>
</array>
</dict>
</array>
<key>UIFileSharingEnabled</key>
<true/>
Notice that I didn't end the CFBundleDocumentTypes array until I had added both entries.

Some sites block my app file type

I created my own file type called foo. It is text file.
What I want to do is when user touches file name with extension .foo in Safari, my app is executed.
But, because it is text file, some sites show that file in text viewer.
How can I prevent that? It works fine in other sites.
This is what I wrote in my info.plist.
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFiles</key>
<array>
<string>myicon.png</string>
</array>
<key>CFBundleTypeName</key>
<string>my file</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.mycompany.foo</string>
</array>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeDescription</key>
<string>my file</string>
<key>UTTypeIdentifier</key>
<string>com.mycompany.foo</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<string>foo</string>
</dict>
</dict>
</array>
It would be to do with the MIME types on the web servers serving the content. There is not much you can do about this unless of course you run the webserver in question.
Hope that helps.

cant open file in app from email

i have managed to get my app to email a copy of its database to my self, but now when i try and re open it, it says "open in my app" but does nothing. This is what i have in my info.plist
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.darcapps.myapp.lb</string>
<key>UTTypeDescription</key>
<string>myapp backup</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<string>lb</string>
<key>public.mime-type</key>
<string>application/myapp</string>
</dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>myapp backup</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSItemContentTypes</key>
<array>
<string>com.darcapps.myapp.lb</string>
</array>
</dict>
</array>
The other thing i wasnt sure about was <string>com.mycompany.myapp.extName</string>
Do i have to set these anywhere? eg do i have to set a setting anywhere to tell it what my app is called and what my company is?
thanks
Swapped over to xcode 4 and it made the whole process easier

How do I associate icons to zip file type with an iPhone/iPad application?

Here is my code in plist file.
It run correctly but the icon was not displayed.
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeIconFiles</key>
<array>
<string>iPad-320.png</string>
<string>iPad-64.png</string>
</array>
<key>CFBundleTypeName</key>
<string>Zip Archive</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.pkware.zip-archive</string>
</array>
</dict>
</array>
I think you should use CFBundleIconFiles like this:
<key>CFBundleIconFiles</key>
<array>
<string>icon.png</string>
<string>icon#2x.png</string>
<string>icon-72.png</string>
</array>

Associating sqlite3 db to an iPhone app

I'm trying to associate an SQLite3 database file with our app so that it's easy to open backed up database from an email. The following however does not seem to work as Mail still doesn't recognizes the file (on an iPad and iPhone 4):
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.database</string>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>App Database File</string>
<key>UTTypeIdentifier</key>
<string>com.company.App.db</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<string>db</string>
<key>public.mime-type</key>
<string>application/x-sqlite3</string>
</dict>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<dict>
<key>CFBundleTypeName</key>
<string>App Database</string>
<key>CFBundleTypeIconFiles</key>
<array>
<string>Icon-Small.png</string>
<string>Icon.png</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSItemContentTypes</key>
<array>
<string>com.company.App.db</string>
</array>
<key>LSHandlerRank</key>
<string>Alternate</string>
</dict>
</dict>
Any idea what I'm doing wrong?
For completeness and possibly my own reference later here is a bit of the further details that got it working for me:
Declaring Document Types your app supports
(eg sqlite3 databases)
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.company.sqlite3.database</string>
<key>UTTypeReferenceURL</key>
<string>http://www.company.com/</string>
<key>UTTypeDescription</key>
<string>MyCompany SQLite Database</string>
<key>UTTypeIconFile</key>
<array>
<string>Icon-Small.png</string>
<string>Icon.png</string>
</array>
<key>UTTypeConformsTo</key>
<array>
<string>public.database</string>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>sqlite</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/x-sqlite3</string>
<string>application/octet-stream</string>
</array>
</dict>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>MyCompany SQLite Database</string>
<key>CFBundleTypeIconFiles</key>
<array>
<string>Icon-Small.png</string>
<string>Icon.png</string>
</array>
<key>CFBundleTypeExtensions</key>
<array>
<string>sqlite</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/x-sqlite3</string>
<string>application/octet-stream</string>
</array>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>com.company.sqlite3.database</string>
</array>
<key>NSPersistentStoreTypeKey</key>
<string>SQLite</string>
</dict>
</array>
Copy paste the above XML into your Info.plist file.
Setting the 'Store Type' to 'SQLite' didn't wasn't the killer fix for me.
My previous post here mentioned a rather incorrect way of getting it to work which accepts all files and didn't properly export the type.
Also if your app is emailing off these files as attachments make sure it matches the MIME type you set it to capture. The application/octet-stream is not important it is just that older versions of our app are emailing out the databases with that MIME type.
eg,
[controller addAttachmentData:[NSData dataWithContentsOfFile:dbPath] mimeType:#"application/x-sqlite3" fileName:filename];
I sure hope anyone else that tries to find out how to get their app to support opening sqlite3 database backups finds this helpful.
Okay I've sorted this out. If you instead use 'target's info' panel and add your document type there (and then select 'SQLite' as the type') it just works. Obviously provided you've exported the type as above.
As per Apple's documentation, CFBundleDocumentTypes is an array, not a dict.
You have:
<key>CFBundleDocumentTypes</key>
<dict>
so the <dict> needs to be in an <array> element, like so:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>App Database</string>
<!-- ... -->
</dict>
</array>