iosswiftswiftuiswiftui-sharelink

Conditional FileRepresentation format in transferRepresentation with Swift


I'm pretty new to Swift and iOS development, and have hit a stumbling block that I should have seen coming...

I've implemented a class called Media, which can contain Data or a Url, depending on the type of media that it contains - at the moment this is audio and photo, but will include video as well.

I've managed to get it to allow sharing of audio no problem, but as I went to implement sharing for images, I realised that the implementation of transferRepresentation is static, so I have no way of conditionally specifying the format or whether it uses the Data or Url properties I have set.

So the question is, is this even possible, or will I need to split my media types into different classes to allow this to work?

Here is a section of the class to show what I've done. It's the transferRepresentation implementation that I need to somehow update

@Model
class Media: Transferable {
    @Attribute(.externalStorage) var file: Data? = nil    
    var url: String? = nil
    
    
    public static var transferRepresentation: some TransferRepresentation {
        FileRepresentation(exportedContentType: .wav) { audio in
            SentTransferredFile(URL(string: "\(AudioHelper.getDocumentsDirectory())\(audio.url!)")!)
        }
    }
}

This is my setup so far, so looking for any possible options, or if I need to rework how my classes are setup, so it's not using the Media class as a catch-all


Solution

  • Although the transferRepresentation property is static, almost everything you call in there will provide a closure that gives you an instance of your Transferable item, like the initialiser for FileRepresentation, and also exportingCondition - the dedicated method for making a representation conditional.

    FileRepresentation(exportedContentType: .wav) { audio in
        SentTransferredFile(...)
    }
    .exportingCondition { media in media.url != nil }
    

    Side note: Consider creating the URL for the file using init(string:relativeTo:).