it-swarm.com.de

So speichern Sie ein Bild in Kerndaten

Ich bin neu in iOS. Ich habe versucht, eine Anwendung zu erstellen, die ein von der Kamera aufgenommenes Bild in CoreData speichert. Ich weiß jetzt, wie man Daten wie NSStrings, NSDate und andere Typen speichert, habe aber Schwierigkeiten, ein Bild zu speichern. Ich habe so viele Artikel gelesen, in denen es heißt, dass Sie es auf die Festplatte schreiben und in eine Datei schreiben müssen, aber ich kann es anscheinend nicht verstehen.

Der folgende Code ist derjenige, den ich zum Speichern anderer Daten in Kerndaten verwendet habe.

- (IBAction)submitReportButton:(id)sender
{
    UrbanRangerAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

    managedObjectContext = [appDelegate managedObjectContext];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"PotholesDB" inManagedObjectContext:appDelegate.managedObjectContext];
    NSManagedObject *newPothole = [[NSManagedObject alloc]initWithEntity:entity insertIntoManagedObjectContext:managedObjectContext];


    [newPothole setValue:self.relevantBody.text forKey:@"relevantBody"];
    [newPothole setValue:self.subjectReport.text forKey:@"subjectReport"];
    [newPothole setValue:self.detailReport.text forKey:@"detailReport"];
//    [newPothole setValue:self.imageView forKey:@"photo"];

    NSDate *now = [NSDate date];
    //NSLog(@"now : %@", now);
    NSString *strDate = [[NSString alloc] initWithFormat:@"%@", now];
    NSArray *arr = [strDate componentsSeparatedByString:@" "];
    NSString *str;
    str = [arr objectAtIndex:0];
    NSLog(@"now : %@", str);

    [newPothole setValue:now forKey:@"photoDate"];
    [newPothole setValue:self.latitudeLabel.text forKey:@"latitude"];
    [newPothole setValue:self.longitudeLabel.text forKey:@"longitude"];
    [newPothole setValue:self.addressLabel.text forKey:@"streetName"];
    [newPothole setValue:streeNameLocation forKey:@"location"];


    NSError *error;
    [managedObjectContext save:&error];

    UIAlertView *ll = [[UIAlertView alloc] initWithTitle:@"Saving" message:@"Saved data" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];

    [ll show];
} 
70
Sipho Koza

Sie können Bilder in Core Data mit dem Attributtyp Binärdaten speichern. Sie sollten sich jedoch einiger Dinge bewusst sein:

  • Konvertieren Sie Ihr UIImage immer in ein tragbares Datenformat wie png oder jpg. Zum Beispiel:

    NSData *imageData = UIImagePNGRepresentation(image);

  • Aktivieren Sie "Ermöglicht externen Speicher" für dieses Attribut description Core Data verschiebt die Daten in eine externe Datei, wenn sie einen bestimmten Schwellenwert erreichen. Diese Datei wird ebenfalls vollständig von Core Data verwaltet, sodass Sie sich darüber keine Gedanken machen müssen.

  • Wenn Sie auf Leistungsprobleme stoßen, versuchen Sie, das Attribut "Binärdaten" auf eine separate Entität zu verschieben.

  • Sie sollten die Konvertierung nach NSData hinter der Schnittstelle Ihrer NSManagedObject-Unterklasse abstrahieren, damit Sie sich nicht um Konvertierungen von UIImage nach NSData oder umgekehrt kümmern müssen.

  • Wenn Ihre Bilder keinen starken Bezug zu den Objekten in Ihrem Modell haben, würde ich empfehlen, sie außerhalb von Core Data zu speichern.

165
jansenmaarten

In der Unterklasse xcdatamodelId deklarieren Sie die Bildentität als NSData... Sie können das Format UIImage nicht verwenden, da die Bilddaten im Binärformat vorliegen.

@property (nonatomic, retain) NSData *imag;

In der Implementierungsdatei .. UIImage in NSData konvertieren

UIImage *sampleimage = [UIImage imageNamed:@"sampleImage.jpg"];

NSData *dataImage = UIImageJPEGRepresentation(sampleimage, 0.0);

Dann speichere es endlich

[obj setValue:dataImage forKey:@"imageEntity"]; // obj refers to NSManagedObject
12
Jemythehigh
- (void)imageChanged:(UIImage*)image{

    if (self.detailItem) {
        [self.detailItem setValue:UIImagePNGRepresentation(image) forKey:kSignatureImage];
    }
}

Hier ein sehr kurzes Beispiel. self ist ein Ansichtscontroller, der Kerndaten verwendet, und self.detailItem ist das übliche NSManagedObject. In diesem Projekt habe ich keine Modellklassen für die Entitäten erstellt, sondern ausschließlich das KVC-Muster verwendet, um auf die Attribute zuzugreifen. Wie Sie vielleicht erraten haben, heißt das Attribut "signatureImage", das ich in einer #define-Konstante kSignatureImage definiert hatte.

Hier wird das Image aus den Kerndaten wiederhergestellt:

self.signatureCanvas.image =  [UIImage imageWithData:[self.detailItem valueForKey:kSignatureImage]];

Wiederum ist self ein View-Controller, signatureCanvas ist eine UIImageView -Unterklasse und .image ist die reguläre Eigenschaft von image, die von UIImageView geerbt wurde. detailItem ist wieder das übliche NSManagedObject.

Das Beispiel stammt aus einem Projekt, an dem ich gerade arbeite.

Es gibt Vor- und Nachteile, große Datenobjekte wie Bilder in Kerndaten zu speichern oder in Dateien zu trennen. Wenn Sie sie in Dateien speichern, sind Sie dafür verantwortlich, sie zu löschen, wenn die zugehörigen Datenobjekte gelöscht werden. Dies sorgt für zusätzlichen Codierungsaufwand und kann bei Programmierfehlern flüchtig sein. Andererseits kann dies die zugrunde liegende Datenbank verlangsamen. Ich habe noch nicht genug Erfahrung mit diesem Ansatz, die ich in Bezug auf die Leistung teilen könnte. Am Ende ist der belegte Plattenspeicher insgesamt ungefähr gleich groß.

4
Hermann Klecker

Für Swift 5 und Swift 4.2

  1. UIImage in Data konvertieren:

    let imageData = image.jpegData(compressionQuality: 1.0)
    
  2. speichern unter CoreData:

    let object = MyEntity(context: managedContext)   //create object of type MyEntity
    object.image = imageData                         //add image to object
    
    do {
        try managedContext.save()                   //save object to CoreData
    } catch let error as NSError {
        print("\(error), \(error.userInfo)")
    }
    
4
nomnom

Es ist möglich, Bilder in Core Data als UIImage zu speichern. Dies wird zwar nicht als bewährte Methode angesehen, da Datenbanken nicht zum Speichern von Dateien vorgesehen sind. Wir verwenden keine Kerndaten, um die Bilder direkt zu speichern, sondern verwenden den Dateipfad, in dem die Bilddaten auf Ihrem Telefon gespeichert sind.

Wie auch immer, die beste Methode, die ich bei der Entwicklung eines Nebenprojekts herausgefunden habe, wird unten gezeigt

  1. Setzen Sie den Entity CodeGen auf Manual/None

  2. Wählen Sie das Attribut aus, dessen Typ Sie ändern möchten, und wählen Sie mwandelbar als Typ

  3. Benutzerdefinierte Klassenkennung als UIImage eingeben

  4. Gehen Sie zum Editor und wählen Sie Create NSManagedObject Subclass

  5. Der Prozess erstellt 2 Swift Dateien abhängig von der Anzahl Ihrer Entitäten (ich hatte nur 1 Entität). Wählen Sie nun die Datei <EntityName> + CoreDataProperties.Swift Und IKit importieren

Wenn Sie auf Zur Definition springen für die öffentliche Variable @NSManaged UIImage definition Klicken, ist Ihre Arbeit abgeschlossen.

Führen Sie Aktionen für die Entitäten genau so aus, wie Sie es tun würden, und Sie können das Bildattribut abrufen, speichern und bearbeiten, indem Sie <EntityName>?.value(forKey: "<attributeName>") as? UIImage nach unten werfen.

Ich musste die Entität als NSManagedObject -Typ verwenden und konnte aus irgendeinem Grund nicht direkt aus der erstellten Unterklasse auf das Bild zugreifen.

1
Utkarsh Jaiswal
1
Devang

Ich weiß nicht, warum Sie Bilder in Kerndaten speichern möchten, während in iOS ein anderer permanenter Speicher verfügbar ist. Wenn Sie das Bild nur zu Cache-Zwecken speichern möchten, können Sie es im Dokumentverzeichnis oder im Cache-Verzeichnis speichern. Happy Coding ...

Bitte beachten Sie die folgende URL, wie Bilder im Dokumentverzeichnis gespeichert und abgerufen werden.

http://www.wmdeveloper.com/2010/09/save-and-load-uiimage-in-documents.html

Bild im Dokumentenverzeichnis speichern und für E-Mail-Anhang abrufen

Wie erstelle ich eine temporäre Datei mit Cocoa?

0
Mangesh