How can I use a Core Data Image (Data) within a Live Activity?

374 Views Asked by At

I have an app that saves created user events with a title, date and an image for personal use. This is stored with Core Data so the Image is stored as Data. I have a shared App Group that I am trying to write the file to and then display it within the Live Activity. The writing of the file seems to go through, but the Live Activity never starts and I receive an error in creating the Live Activity.

When I keep the IF statement in the View, but change the image within the statement to an asset, it actually presents the image, so it seems like the function for getting Data to UIImage also works. But when I set the let image as the image inside the if statement it doesn't create the Live Activity.

Thank you so much for any contributions here. (Apologies for Beginner-knowledge here. Starting out :) )

This is the creation of the Live Activity and functions: `

class EventModel: ObservableObject {
    @Published var event: EventEntity
    var liveActivity: Activity<EventAttributes>? = nil

    func startLiveActivity() {
        
        let _ = saveImage(data: (event?.image)!)
        
        let liveEvent = LiveActivityEvent(title: (event?.title)!, date: (event?.date)!)
        let attributes = EventAttributes(event: liveEvent)
        
        do {
            liveActivity = try Activity.request(attributes: attributes, contentState: EventAttributes.ContentState())
        } catch {
            print(error.localizedDescription)
        }
    }
}

func saveImage(data: Data) -> Bool {
    
    guard let groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "AppGroupIdentifier") else {
        fatalError("could not get shared app group directory.")
    }
    
    do {
        try data.write(to: groupURL.appendingPathComponent("LiveActivityPhoto"))
        return true
    } catch {
        print(error.localizedDescription)
        return false
    }
    
}

func getSavedImage(named: String) -> UIImage? {
    if let dir = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "AppGroupIdentifier") {
        return UIImage(contentsOfFile: URL(fileURLWithPath: dir.absoluteString).appendingPathComponent(named).path)
    }
    return nil
}

`

And this is the Live Activity View `

struct LiveActivityView: View {
    
    var context: ActivityViewContext<EventAttributes>
    
    var body: some View {
        HStack {
            
            if let image = getSavedImage(named: "LiveActivityPhoto") {
                Image(uiImage: image)
             
            }
        }
    }
}


`

1

There are 1 best solutions below

0
On

I have found a solution based on the App Group

  1. Add App Group capability for both targets, main and widget (Project -> Target -> Signing&Capability tab -> find “+” sign. The app group should have the same name

  2. Then you can save any image to the destination URL like this

    private func uploadImage() {
    guard var destination = FileManager.default.containerURL(
      forSecurityApplicationGroupIdentifier: "group.YOUR_GROUP_NAME")
    else { return }
    
    destination = destination.appendingPathComponent("imageName")
    
    let image = UIImage(named: "kopiumTest")!
    if let imageData = image.jpegData(compressionQuality: 0.5) {
      try? imageData.write(to: destination)
    }}
    

and then you will be able to use just saved image in the Widget

@ViewBuilder var uploadIcon: some View {
  let imageContainer = FileManager.default.containerURL(
    forSecurityApplicationGroupIdentifier: "group.YOUR_GROUP_NAME")?
    .appendingPathComponent("imageName"),
  let uiImage = UIImage(contentsOfFile: imageContainer.path()) {
    Image(uiImage: uiImage)
      .resizable()
      .aspectRatio(contentMode: .fill)
      .frame(width: 50, height: 50)
  } else {
    Text("Not found")
  }
}

Cheers