0

Recently, I'm considering to migrate my app's data from Core Data to Realm.

But what I worried about is there is no attribute in Realm called: Allows External Storage. The app I made which have many images need to save. So, I think it's not a good idea for saving these images in Data type in Realm, although all of these images are less than 2MB (per image).

enter image description here

So, My questions are:

  1. Is it a good idea for saving these images into Data in Realm? (less than 2MB per images, But there are many images) Not a good idea.
  2. If it's not a good idea. How to save images into local file system and not only using String type to mapping them. I want to use a new Type (e.g. RealmImage)

like this:

class Person: Object {
    var name: String
    var avatar: ObjectWithImage
}
class ObjectWithImage : RealmObject {
    var imageUrl: String
}

no this:

class Person: Object {
    var imageUrl: String
}

So, I don't want to save a image file path as a String type only. What I want to do is create a new type (e.g. ObjectWithImage or some like this) and it will contains images' file path. The reason for that is because I'm using CloudKit as well. So I have to mapping all Realm type with CloudKit type. It will conflict with original String type if it's String type.

The problem is CKAsset. What I want is it can support CKAsset and ObjectWithImage can map with CKAsset.

Below code is a sample code for some other type, I want to support CKAsset in below Code.

public protocol CKRecordRecoverable {
    associatedtype O: Object
}

extension CKRecordRecoverable {//Mapping from CKRecord
    func parseFromRecord(record: CKRecord) -> O? {
        let o = O()
        var recordValue: Any?
        for prop in o.objectSchema.properties {
            switch prop.type {
            case .int:
                recordValue = record.value(forKey: prop.name) as? Int
            case .string:
                recordValue = record.value(forKey: prop.name) as? String
            case .bool:
                recordValue = record.value(forKey: prop.name) as? Bool
            case .date:
                recordValue = record.value(forKey: prop.name) as? Date
            case .float:
                recordValue = record.value(forKey: prop.name) as? Float
            case .double:
                recordValue = record.value(forKey: prop.name) as? Double
            case .data:
                recordValue = record.value(forKey: prop.name) as? Data
            default:
                print("Other types will be supported in the future.")
            }
            o.setValue(recordValue, forKey: prop.name)
        }
        return o
    }
}

public var record: CKRecord {
    let r = CKRecord(recordType: Self.recordType, recordID: recordID)
    let properties = objectSchema.properties
    for prop in properties {//Mapping to CloudKit type
        r[prop.name] = self[prop.name] as? CKRecordValue
    }
    return r
}

So, any ideas?

-----------Edit-------------

SO according to comments, I think the second option is a good way: Saving images into local file storage.

Can anyone can help me to think about how to mapping it with CKRecord

In parseFromRecord and record method. Define a new type to deal with images and also saving images into local file storage.

I have no any idea about that now. Thank you so much.

I have got a reason from this link: Why is it recommended practice to store images on disk rather than in a Realm .

But still want to know how to make it...

Yuan Fu
  • 310
  • 2
  • 14
  • 2
    AFAIK storing images in Realm is not recommended due to the in-memory instance Realm creates. This means that if you store a lot of images in Realm, the memory usage of your app might get large. Also, if your Realm file is larger, queries might take longer to run. One alternative approach is to store the images themselves in the file system outside of Realm and only store the local file paths in Realm. – Dávid Pásztor Jan 05 '18 at 22:09
  • I would also recommend @DávidPásztor suggestion. – Ahmad F Jan 05 '18 at 22:17
  • @Dávid Pásztor Yeah. I agree now. So do you have any recommend about `CKRecordRecoverable` and `record` method in above code. given a new type and mapping it with CKRecord. – Yuan Fu Jan 05 '18 at 22:20

1 Answers1

0

When you see that CoreData checkbox for Allows External Storage the word "External" does not mean that it's stored in the cloud or somewhere else off the device. It simply means that it may be stored in a file outside your persistent store.

In other words, your photos would still be taking up space on the user's device even if you checked Allows External Storage.

creeperspeak
  • 5,403
  • 1
  • 17
  • 38
  • 1
    Hi creeperspeak, I know it's not for saving in Cloud, it will save in **external storage**. It's a local file system. Maybe my description is not clear. I will make it clear. What I mean is saving images in file system instead of Realm itself. – Yuan Fu Jan 05 '18 at 22:06
  • @YuanFu OK - I see. I thought you were concerned about taking up space on the device. Apologies for the confusing answer, in that case. – creeperspeak Jan 05 '18 at 22:29