Using built-in icons for mime type or UTI type in iOS
Asked Answered
M

3

13

Problem:

I would like to be able to use the built-in iOS icons for standard mime types (or UTI types) in my listing of binary file content.

Background:

I have looked into using the new (since 3.2) document architecture, but using the UIDocumentInteractionController it seems that the assumption is that the actual binaries are already on the local device.

In my case I have a file listing from a remote server and know the mime type, name, title, etc for the remote file so I just want to show a file listing with icons (the actual binary is only loaded as needed).

The meta data I get from the server contains proper mime types for the binaries so in theory I just want to get the system icon based on the type.

Work around?

I have tried the following "hack" as a proof of concept and it seems to work but this doesn't seem like the best way to go...

//Need to initialize this way or the doc controller doesn't work
NSURL*fooUrl = [NSURL URLWithString:@"file://foot.dat"];
UIDocumentInteractionController* docController = [[UIDocumentInteractionController interactionControllerWithURL:fooUrl] retain];

UIImage* thumbnail = nil;
//Need to convert from mime type to a UTI to be able to get icons for the document
NSString *uti = [NSMakeCollectable(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (CFStringRef)self.contentType, NULL)) autorelease];

//Tell the doc controller what UTI type we want
docController.UTI = uti;

//The doc controller now seems to have icon(s) for the type I ask for...
NSArray* icons = docController.icons;
if([icons count] > 0) {
    thumbnail = [icons objectAtIndex:0];
}
return thumbnail;
Marla answered 3/5, 2011 at 23:29 Comment(1)
Can you mark https://mcmap.net/q/860334/-using-built-in-icons-for-mime-type-or-uti-type-in-ios as correct? It sounds like it works for people.Upstretched
A
12

You can create a UIDocumentInteractionController without needing to specify a URL. The header for the class says the icons are determined by name if set, URL otherwise.

UIDocumentInteractionController* docController = [[UIDocumentInteractionController alloc] init];
docController.name = @"foo.dat";
NSArray* icons = docController.icons;
// Do something with icons
...
[docController release];
Ardra answered 20/6, 2012 at 11:54 Comment(2)
This doesn't seem to work in iOS 6.1. I've tried it on both the simulator and device.Upstretched
Just tried this on an iOS 7 project in the simulator. The debugger shows me the array with UIMappedBitmapImage values as expected.Gelsemium
U
10

I tried Ben Lings's solution, but it didn't work on iOS6.1 in either the simulator or on my iPad3. You need to provide an NSURL to the UIDocumentInteractionController, but that URL doesn't need to exist. Its last path component just needs to have the extension that you want.

The following code worked for me

NSString *extension = @"pptx"; // or something else
NSString *dummyPath = [@"~/foo" stringByAppendingPathExtension:extension]; // doesn't exist
NSURL *URL = [NSURL fileURLWithPath:dummyPath];
UIDocumentInteractionController *documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:URL];
NSArray *systemIconImages = documentInteractionController.icons;

return systemIconImages;
Upstretched answered 14/2, 2013 at 17:46 Comment(6)
I am using this solution and it worked great but recently I am having a problem for unknown file type. For example, if the file is anyFile.supal it shows dropbox icon (dropbox is installed in my device). Is there any way to get rid of this problem?Overdrive
I just found the solution -> 1. Edit .plist file 2. Find Doucument types -> Item 0 -> Handler rank 3. Change the value to OwnerOverdrive
Please file a radar, and copy it to openradar. I'll duplicate it.Upstretched
@arif - fanstastic how crappy are the APIs Apple create. It is a total contrast between the Amazing Apple that creates fantastic hardware and the Crappy Apple that creates APIs. THANKS ARIF!Subdued
The basic idea still works, but in iOS 10 even though the actual file does not need to exist, the containing directory must exist and must be one which can contain user documents e.g. Documents and Library/caches work but ~, Developer, Library and Application Support do not. Note also in iOS 10 the icons array can be returned empty even though the documentation says it always returns somethingJoviality
iOS 10 behaviour is different on device compared to simulator. This code continues to work on the simulator, but not on device. See my previous comment on how to fix itJoviality
B
1

So we are talking about hacks uh? I did this by doing some bad stuff, but it's working... I copied the icons from /system/library/frameworks/QuickLook.framework and added to my project. Inside this same folder, there is some property lists, that make the link between the UTI/extension/mime-type with the png file. With the plist and the pngs, all you have to do is make a logic to read the plists and show the correct png.

Blackamoor answered 27/5, 2011 at 11:55 Comment(3)
Yeah ideally I was hoping that a more official approach was out there without any hacking. But thanks for the details on where the underlying icons are coming from. I had not dug into that.Marla
hi, "/system/library/frameworks/QuickLook.framework" you refere to Mac or iPhone? ThanksImpartial
This suggestion has two issues: 1. it does not consider the icons present on the user's device (if a specific app is installed to handle a particular file type) and 2. using icons from Apple can result in a rejection, as it is clearly a violation against the rules.Honeysucker

© 2022 - 2024 — McMap. All rights reserved.