2014-02-14 11 views
14

Wie würden Sie den MIME-Typ für ein NSData-Objekt ermitteln? Ich plane, den Benutzer ein Video/Bild von ihrem iPhone hochladen zu lassen und diese Datei in eine NSData-Klasse verpackt zu haben.Ermitteln MIME-Typ von NSData?

Ich frage mich, ob ich den MIME-Typ von den NSData erzählen kann. Es gibt nur wenige Antworten auf diese Frage und die letzte stammt aus dem Jahr 2010 (vor 4 Jahren!). Vielen Dank!

NSData *data; // can be an image or video 
NSString *mimeType = [data getMimetype]; // how would I implement getMimeType 
+0

Sie könnten hav Ein anderes Feld, das den MIME-Typ deklariert und auch mitschickt. – aust

+0

Es gibt keine (genaue) Möglichkeit, den MIME-Datentyp aus den Daten selbst zu bestimmen. Im besten Fall können Sie eine fundierte Vermutung abgeben. –

+0

Wenn Sie weitere MIME-Typen hinzufügen möchten, finden Sie ihre Hex-Werte hier: https://en.wikipedia.org/wiki/List_of_file_signatures –

Antwort

2

Da Sie sagen, dass Sie diese Daten hochladen, sollten Sie bereits den MIME-Typ wissen. Sie haben das Datenobjekt erstellt, Sie wissen, woher die Daten stammen, und es gibt eine begrenzte Anzahl von MIME-Typen. Verwenden Sie also, was auch immer für Ihre Daten gilt. Für ein Bild ist es wahrscheinlich image/jpeg oder image/png. Für Videos gibt es eine Reihe von video/ Arten. Sie können eine lange Liste von MIME-Zeichenfolgen auf Ihrem Mac in /etc/apache2/mime.types finden. Je nachdem, welche Art von Video du hast, wirst du eine oder mehrere davon haben wollen.

Das Ermitteln des MIME-Typs ist ein Problem; Ein NSData kann jede Art von Binärdaten codieren. Die einzige Möglichkeit zu bestimmen, was codiert wurde, besteht darin, die Bytes zu untersuchen. Das bedeutet wiederum, dass Sie wissen, welche Bytestreams in verschiedenen Dateitypen existieren. Es sollte möglich sein, ein Nachschlagewörterbuch in vielen (aber nicht allen) Fällen zu verwenden, und es könnte irgendwo eine Open-Source-Implementierung für gebräuchliche Dateitypen geben. Um eine Vorstellung davon zu bekommen, was es gibt, versuchen Sie man file auf Ihrem Mac und schauen Sie in /usr/share/file/magic/, um zu sehen, wie verschiedene Dateitypen identifiziert werden (der file Befehl erzeugt keine MIME-Typen, aber es analysiert Dateiinhalte, um Dateitypen zu identifizieren und zu identifizieren das gleiche Prinzip).

+0

Danke für die Erklärung. Nun, die Hintergrundgeschichte ist ein bisschen komplizierter. Ich schreibe einen API-Aufruf und ich weiß nicht, was der Benutzer reingibt. Ich weiß nur, dass es sich um eine NSData-Klasse handelt und es sich um ein Bild oder Video handeln kann. Und ich brauche den MIME-Typ auch richtig upload die Datei via AFNetworking. – blee908

+0

Muss Ihr Server den genauen MIME-Typ kennen? Sie können immer auf "application/octet-stream" zurückgreifen, um "irgendeine Art von binären Daten" anzuzeigen. Wenn Sie etwas Spezielleres benötigen, ist der beste Weg, es in eine 'AVFoundation'-Klasse zu laden (vielleicht' AVAsset') und dann auf die Metadaten zu schauen, um einen MIME-Typ zu wählen. –

+0

Sehr nah. Es stellt sich heraus, dass "application/octet-stream" zu funktionieren scheint (ich habe png und jpeg getestet, aber den gleichen MIME-Typ eingegeben), aber AFNetworking muss die Dateierweiterung kennen, also müssen Sie einen NSString * -Dateinamen mit übergeben "mypic.jpeg" oder "mypic.png" nicht "mypic" – blee908

3

Soweit ich weiß, ist NSData ein nur ein Datenobjekt, das eine Byte-Array Wraps:

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/Reference/Reference.html

... so eine Weise, die ich denken kann, wenn man will seinen MIME-Typen entdecken ist es, die Bytes selbst zu inspizieren und dann den Typ von dort zu vermuten. Es gibt ein Beispiel dafür hier: Finding image type from NSData or UIImage

Ich habe das auch gefunden: Determine MIME Type of NSData Loaded From a File; das bezieht sich auf eine interne Datenbank (ich denke), die für eine Suche nach MIME-Typ verwendet werden kann.

Aber wie Tom Harrington in seiner Antwort sagt, könnte es schwierig werden, je nachdem, womit Sie es zu tun haben.

Bearbeiten ...

Natürlich setzt die zweite Lösung auf der Dateierweiterung, die Sie offensichtlich nicht haben, aber ich bin sicher, dass Sie das schon bemerkt.

+0

Danke für die Rückmeldung! – blee908

24

Basierend auf ml's answer from a similar post habe ich die MIME-Typen Bestimmung für NSData hinzugefügt:

+ (NSString *)mimeTypeForData:(NSData *)data { 
    uint8_t c; 
    [data getBytes:&c length:1]; 

    switch (c) { 
     case 0xFF: 
      return @"image/jpeg"; 
      break; 
     case 0x89: 
      return @"image/png"; 
      break; 
     case 0x47: 
      return @"image/gif"; 
      break; 
     case 0x49: 
     case 0x4D: 
      return @"image/tiff"; 
      break; 
     case 0x25: 
      return @"application/pdf"; 
      break; 
     case 0xD0: 
      return @"application/vnd"; 
      break; 
     case 0x46: 
      return @"text/plain"; 
      break; 
     default: 
      return @"application/octet-stream"; 
    } 
    return nil; 
} 

Diese nur Hauptdateitypen umgehen, aber Sie können es ausführen: Sie alle Signaturdateien finden here, benutzen Sie einfach das gleiche Muster wie ich.

PS: alle entsprechenden MIME-Typen sind verfügbar here

+0

Hey @ blee908, das könnte eine gültige Antwort sein, was denkst du? :) – Tib

+0

Wie können wir Audio-Dateien erkennen? – Ankush

+0

@Ankush überprüfen Sie die Liste der Signaturen wie oben erwähnt https://en.wikipedia.org/wiki/List_of_file_signatures – Tib

10

❤️ Swift

extension Data { 
    private static let mimeTypeSignatures: [UInt8 : String] = [ 
     0xFF : "image/jpeg", 
     0x89 : "image/png", 
     0x47 : "image/gif", 
     0x49 : "image/tiff", 
     0x4D : "image/tiff", 
     0x25 : "application/pdf", 
     0xD0 : "application/vnd", 
     0x46 : "text/plain", 
     ] 

    var mimeType: String { 
     var c: UInt8 = 0 
     copyBytes(to: &c, count: 1) 
     return Data.mimeTypeSignatures[c] ?? "application/octet-stream" 
    } 
} 
+0

Super, es hat perfekt funktioniert! – kikettas

0

var WERTE = [UInt8] (Wiederholung von: 0, zählen: imgData.count)

imgData .copyBytes (bis: & Werte, Anzahl: 1)

switch values { 
    case 0xff: 
     return "image/jpeg" 
    case 0x89: 
     return "image/png" 
    case 0x47: 
     return "image/gif" 
    case 0x49, 0x4d: 
     return "image/tiff" 
    } 

    return ""