Как вы можете читать файлы MIME-типа в объективе-c

Я заинтересован в обнаружении MIME-типа для файла в каталоге документов моего приложения iPhone. Поиск в документах не дал никаких ответов.

Это немного взломанный, но он должен работать, не знаю точно, потому что я просто догадываюсь об этом

Существует два варианта:

  1. Если вам просто нужен тип MIME, используйте timeoutInterval: NSURLRequest.
  2. Если вам нужны данные, вы должны использовать запрошенное NSURLRequest.

Обязательно выполняйте запрос в streamе, хотя он синхронный.

NSString* filePath = [[NSBundle mainBundle] pathForResource:@"imagename" ofType:@"jpg"]; NSString* fullPath = [filePath stringByExpandingTildeInPath]; NSURL* fileUrl = [NSURL fileURLWithPath:fullPath]; //NSURLRequest* fileUrlRequest = [[NSURLRequest alloc] initWithURL:fileUrl]; NSURLRequest* fileUrlRequest = [[NSURLRequest alloc] initWithURL:fileUrl cachePolicy:NSURLCacheStorageNotAllowed timeoutInterval:.1]; NSError* error = nil; NSURLResponse* response = nil; NSData* fileData = [NSURLConnection sendSynchronousRequest:fileUrlRequest returningResponse:&response error:&error]; fileData; // Ignore this if you're using the timeoutInterval // request, since the data will be truncated. NSString* mimeType = [response MIMEType]; [fileUrlRequest release]; 

Добавьте инфраструктуру MobileCoreServices .

objective C:

  #import  NSString *fileExtension = [myFileURL pathExtension]; NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, NULL); NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType); 

Swift:

 import MobileCoreServices func MIMEType(fileExtension: String) -> String? { guard !fileExtension.isEmpty else {return nil} if let UTIRef = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as CFString, nil) { let UTI = UTIRef.takeUnretainedValue() UTIRef.release() if let MIMETypeRef = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType) { let MIMEType = MIMETypeRef.takeUnretainedValue() MIMETypeRef.release() return MIMEType as String } } return nil 

}

Принятый ответ проблематичен для больших файлов, как упомянули другие. Мое приложение имеет дело с видеофайлами, и загрузка всего видеофайла в память – хороший способ сделать iOS исчерпанной. Лучший способ сделать это можно найти здесь:

https://stackoverflow.com/a/5998683/1864774

Код сверху ссылки:

 + (NSString*) mimeTypeForFileAtPath: (NSString *) path { if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { return nil; } // Borrowed from https://stackoverflow.com/questions/5996797/determine-mime-type-of-nsdata-loaded-from-a-file // itself, derived from https://stackoverflow.com/questions/2439020/wheres-the-iphone-mime-type-database CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)[path pathExtension], NULL); CFStringRef mimeType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType); CFRelease(UTI); if (!mimeType) { return @"application/octet-stream"; } return [NSMakeCollectable((NSString *)mimeType) autorelease]; } 

Решение Prcela не работало в Swift 2 . Следующая упрощенная функция вернет тип mime для данного расширения файла в Swift 2:

 import MobileCoreServices func mimeTypeFromFileExtension(fileExtension: String) -> String? { guard let uti: CFString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as NSString, nil)?.takeRetainedValue() else { return nil } guard let mimeType: CFString = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() else { return nil } return mimeType as String } 

Я использовал ответ, предоставленный slf в приложении для cocoa (не iPhone), и заметил, что URL-запрос, кажется, читает весь файл с диска, чтобы определить тип mime (не очень большой для больших файлов).

Для тех, кто хочет сделать это на рабочем столе, вот fragment, который я использовал (на основе предложения Луи):

 NSString *path = @"/path/to/some/file"; NSTask *task = [[[NSTask alloc] init] autorelease]; [task setLaunchPath: @"/usr/bin/file"]; [task setArguments: [NSArray arrayWithObjects: @"-b", @"--mime-type", path, nil]]; NSPipe *pipe = [NSPipe pipe]; [task setStandardOutput: pipe]; NSFileHandle *file = [pipe fileHandleForReading]; [task launch]; [task waitUntilExit]; if ([task terminationStatus] == YES) { NSData *data = [file readDataToEndOfFile]; return [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease]; } else { return nil; } 

Если вы назвали это в файле PDF, это выплевывало бы: application / pdf

Основываясь на ответе Лоуренса Дол / Slf выше , я решил, что NSURL загружает весь файл в память, измельчая первые несколько байтов в головной заглушке и получая MIMEType этого. Я не сравнивал это, но, скорее всего, это происходит быстрее.

 + (NSString*) mimeTypeForFileAtPath: (NSString *) path { // NSURL will read the entire file and may exceed available memory if the file is large enough. Therefore, we will write the first fiew bytes of the file to a head-stub for NSURL to get the MIMEType from. NSFileHandle *readFileHandle = [NSFileHandle fileHandleForReadingAtPath:path]; NSData *fileHead = [readFileHandle readDataOfLength:100]; // we probably only need 2 bytes. we'll get the first 100 instead. NSString *tempPath = [NSHomeDirectory() stringByAppendingPathComponent: @"tmp/fileHead.tmp"]; [[NSFileManager defaultManager] removeItemAtPath:tempPath error:nil]; // delete any existing version of fileHead.tmp if ([fileHead writeToFile:tempPath atomically:YES]) { NSURL* fileUrl = [NSURL fileURLWithPath:path]; NSURLRequest* fileUrlRequest = [[NSURLRequest alloc] initWithURL:fileUrl cachePolicy:NSURLCacheStorageNotAllowed timeoutInterval:.1]; NSError* error = nil; NSURLResponse* response = nil; [NSURLConnection sendSynchronousRequest:fileUrlRequest returningResponse:&response error:&error]; [[NSFileManager defaultManager] removeItemAtPath:tempPath error:nil]; return [response MIMEType]; } return nil; } 

В Mac OS X это будет обрабатываться через LaunchServices и UTI. На iPhone они недоступны. Поскольку единственный способ доступа данных к вашей песочнице – для вас, вы можете ее разместить, большинство приложений обладают внутренними знаниями о данных любого файла, который они могут читать.

Если у вас есть необходимость в такой функции, вы должны подать заявку на функцию с помощью Apple.

Я не уверен, что такое практика на iPhone, но если вам это позволено, я бы использовал философию UNIX здесь: используйте программный file , который является стандартным способом определения типа file в операционной системе UNIX. Он включает в себя обширную базу данных магических маркеров для обнаружения файлов. Поскольку file , вероятно, не отправлен на iPhone, вы можете включить его в свой пакет приложений. Может быть библиотека, реализующая функциональность file .

Кроме того, вы можете доверять браузеру. Браузеры отправляют тип MIME, о котором они догадывались где-то в заголовках HTTP. Я знаю, что я могу легко получить информацию типа MIME в PHP. Это, конечно, зависит от того, хотите ли вы доверять клиенту.

  • Как Apple знает, что вы используете частный API?
  • Скрытые особенности Xcode
  • Соглашение об именах iPhone ivar
  • Есть ли документальный способ настройки ориентации iPhone?
  • Сохранить фотографии в пользовательский альбом в iPhones Photo Library
  • Как включить / выключить флэш-память iPhone?
  • Ошибка сервера Bootstrap в Xcode IPHONE
  • Как установить приложение Cocoa в качестве браузера по умолчанию?
  • Измените первый символ в каждом слове строки на верхний регистр.
  • Как я могу получить объект NSDate на сегодня в полночь?
  • Как написать таймер в Objective-C?
  • Давайте будем гением компьютера.