web-dev-qa-db-fra.com

Comment mettre une image dans une base de données Realm?

J'écris une application iOS en utilisant Swift 2 et je voudrais enregistrer la photo de profil d'un compte localement dans une base de données Realm. Je ne trouve aucune documentation ni personne en parlant.

C'est possible? Et comment?

Peut-être est-ce mauvais de faire ça?

25
VivienG

Vous pouvez stocker des images sous la forme NSData. Étant donné que vous disposez de l'URL d'une image que vous souhaitez stocker localement, voici un extrait de code indiquant comment y parvenir.

class MyImageBlob {
    var data: NSData?
}

// Working Example
let url = NSURL(string: "http://images.Apple.com/v/home/cb/images/home_evergreen_hero_iphone_medium.jpg")!
if let imgData = NSData(contentsOfURL: url) {
    var myblob = MyImageBlob()
    myblob.data = imgData 

    let realm = try! Realm()
    try! realm.write {
        realm.add(myblob)
    }
}

C'est peut-être une mauvaise idée de faire ça?

La règle est simple: si les images sont de petite taille, le nombre d'images est petit et elles sont rarement modifiées, vous pouvez vous en tenir à les stocker dans la base de données.

S'il y a un tas d'images, il vaut mieux les écrire directement dans le système de fichiers et simplement stocker le chemin de l'image dans la base de données.

Voici comment cela peut être fait:

class MyImageStorage{
    var imagePath: NSString?
}

let url = NSURL(string: "http://images.Apple.com/v/home/cb/images/home_evergreen_hero_iphone_medium.jpg")!
if let imgData = NSData(contentsOfURL: url) {
    // Storing image in documents folder (Swift 2.0+)
    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
    let writePath = documentsPath?.stringByAppendingPathComponent("myimage.jpg")

    imgData.writeToFile(writePath, atomically: true)

    var mystorage = MyImageStorage()
    mystorage.imagePath = writePath

    let realm = try! Realm()
    try! realm.write {
         realm.add(mystorage)
    }
}

Veuillez noter: Les deux exemples de code ne sont pas des méthodes fiables pour télécharger des images car il existe de nombreux pièges. Dans les applications du monde réel/en production, je suggère d'utiliser une bibliothèque prévue à cet effet comme AFNetworking ou AlamofireImage .

50
ProblemSlover

La solution de ProblemSlover mise à jour pour Swift 2.2:

Remarque importante: le seul changement est que maintenant stringByAppendingPathComponent a été supprimé à partir de Swift 2.1, donc vous obtiendrez une erreur disant:

stringByAppendingPathComponent n'est pas disponible: utilisez plutôt URLByAppendingPathComponent sur NSURL.

Veuillez garder à l'esprit que même si cela peut être gênant, il a été supprimé pour une raison et vous devez suivre la recommandation d'Apple d'utiliser NSURL à la place. MAIS si vous souhaitez continuer avec cette solution, le correctif pour Swift 2.1+ est de lancer explicitement documentsPath à NSString:

class MyImageStorage{
var imagePath: NSString?
}

let url = NSURL(string: "http://images.Apple.com/v/home/cb/images/home_evergreen_hero_iphone_medium.jpg")!
if let imgData = NSData(contentsOfURL: url) {
    //Explicitly cast to NSString
    let documentsPath = (NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString)
    let writePath = documentsPath.stringByAppendingPathComponent("myimage.jpg")

    imgData.writeToFile(writePath, atomically: true)

    var mystorage = MyImageStorage()
    mystorage.imagePath = writePath

    let realm = try! Realm()
    try! realm.write {
        realm.add(mystorage)
    }
}
4
Geoherna