usar puedo programar programación notas lenguaje gestionar desde crear apple almacenamiento abrir iphone objective-c mime mime-types

iphone - puedo - ¿Cómo se puede leer un archivo de tipo MIME en object-c?



swift apple (8)

Agregar el marco de MobileCoreServices .

C objetivo:

#import <MobileCoreServices/MobileCoreServices.h> 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);

Rápido:

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

}

Estoy interesado en detectar el tipo MIME para un archivo en el directorio de documentos de mi aplicación de iPhone. Una búsqueda a través de los documentos no proporcionó ninguna respuesta.


Basándome en la respuesta anterior de Lawrence Dol / slf , resolví que el NSURL cargaba todo el archivo en el problema de memoria cortando los primeros bytes en un talón de cabeza y obteniendo el MIMEType de eso. No lo he evaluado, pero probablemente sea más rápido de esta manera también.

+ (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; }


En Mac OS X, esto se manejaría a través de LaunchServices y UTIs. En el iPhone estos no están disponibles. Ya que la única forma de que los datos ingresen a su caja de arena es que usted los coloque allí, la mayoría de las aplicaciones tienen conocimiento intrínseco sobre los datos de cualquier archivo que puedan leer.

Si necesita esta función, debe file una solicitud de función a Apple.


Es un poco intrincado, pero debería funcionar, no lo sé a ciencia cierta porque simplemente lo adivino

Hay dos opciones:

  1. Si solo necesita el tipo MIME, use el timeoutInterval: NSURLRequest.
  2. Si también desea los datos, debe utilizar el NSURLRequest comentado.

Asegúrese de realizar la solicitud en un hilo, ya que es síncrono.

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];


Estaba usando la respuesta provista por slf en una aplicación de cacao (no iPhone) y noté que la solicitud de la URL parece estar leyendo el archivo completo del disco para determinar el tipo de mimo (no es bueno para archivos grandes).

Para cualquier persona que quiera hacer esto en el escritorio, aquí está el fragmento que usé (basado en la sugerencia de Louis):

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; }

Si lo llamara en un archivo PDF, se escupiría: aplicación / pdf


La respuesta aceptada es problemática para archivos grandes, como han mencionado otros. Mi aplicación se ocupa de los archivos de video, y cargar un archivo de video completo en la memoria es una buena manera de hacer que iOS se quede sin memoria. Una mejor manera de hacer esto se puede encontrar aquí:

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

Código del enlace de arriba:

+ (NSString*) mimeTypeForFileAtPath: (NSString *) path { if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { return nil; } // Borrowed from https://.com/questions/5996797/determine-mime-type-of-nsdata-loaded-from-a-file // itself, derived from https://.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]; }


No estoy seguro de cuáles son las prácticas en el iPhone, pero si se me permite, usaré la filosofía de UNIX aquí: usar el file programa, que es la forma estándar de detectar el tipo de archivo en un sistema operativo UNIX. Incluye una amplia base de datos de marcadores mágicos para la detección de tipos de archivo. Como es probable que el file no se envíe en iPhone, puede incluirlo en su paquete de aplicaciones. Puede haber una biblioteca implementando la funcionalidad del file .

Alternativamente, puedes confiar en el navegador. Los navegadores envían el tipo MIME que adivinaron en algún lugar de los encabezados HTTP. Sé que puedo capturar fácilmente la información de tipo MIME en PHP. Eso, por supuesto, depende de si estás dispuesto a confiar en el cliente.


La solución de Prcela no funcionó en Swift 2 . La siguiente función simplificada devolverá el tipo mime para una extensión de archivo dada en 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 }