-1

I'm looking to save an image from PhotosPicker to CoreData (as a Binary Data with Allows External Storage) but I have an issue. I don't know it's default value.

I'm fine with other types but definitely not with Data, here's an example:

import SwiftUI

struct ContentView: View {
    @State var value: Double = 0
    @State var title: String = ""
    @State var image: Data? = nil

    var body: some View {
        Button("Add", action: {
            Persistence.shared.add(value: value, title: title, image: image ?? /* Something here */, context: viewContext)
        })
    }
}

1 - As said by Rob, the default value of type Data is just Data(). I don't know why it tooks me so long to understand it. For the record, if you look at what it means for CoreData to store Data() you will be able to see that there is almost nothing. It's very interesting. But it's not nil as well.

2 - The result is like that:

Persistence.shared.add(value: value, title: title, image: image ?? Data(), context: viewContext)
HangarRash
  • 7,314
  • 5
  • 5
  • 32
Alexnnd
  • 429
  • 4
  • 13
  • See the documentation: [`Data`](https://developer.apple.com/documentation/foundation/data). – HangarRash Apr 18 '23 at 20:52
  • You need to allow the `image` parameter for `add` to be nil, you should not store a default value if you have no image. – Joakim Danielson Apr 18 '23 at 20:55
  • As you mention *External Storage* consider to save the images to disk and keep only the (relative) URLs in CoreData. And consider also to use less optionals especially in SwiftUI. – vadian Apr 18 '23 at 20:56
  • Binary Data allows for nulls as long as the attribute is marked as optional in your schema. – HangarRash Apr 18 '23 at 21:11
  • No, it means you can write `image: image`. Of course your `Persistence.add` method needs to allow an optional image. – HangarRash Apr 18 '23 at 21:17
  • Saving empty data even when there is no image is likely the wrong thing to do. – HangarRash Apr 22 '23 at 21:01
  • @HangarRash What's the right way to do then? – Alexnnd Apr 23 '23 at 07:43
  • @Alexnnd As shown in the answer by rob mayoff. Properties in your data model with no value (`nil`) should be represented in your persistent store as no value (NULL) as well. Think about getting the image back out. If there's data then you expect an image. But you can't create an image from empty data. It's confusing. So if there is no image then there should be no data. That's different from empty data. – HangarRash Apr 23 '23 at 15:19

2 Answers2

2

The default value of Data is Data(), which is an empty data collection, and likely what you want here.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
0

@RobNapier's answer to your question is correct, but it's possible you're asking the wrong question, and would prefer this code:

import SwiftUI

struct ContentView: View {
    @State var value: Double? = nil
    @State var title: String = ""
    @State var image: Data? = nil

    var body: some View {
        Button("Add", action: {
            guard let image else { return }
            Persistence.shared.add(
                value: value ?? 0,
                title: title,
                image: image,
                context: viewContext)
        })
        .disabled(image == nil)
    }
}
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • No because I want to save no matter if there is an image or not. But it could be useful for another case. – Alexnnd Apr 22 '23 at 20:23