PHAssetResource.originalFilename can be nil despite non-optional Swift API

In our PhotoKit backup/export code, we need to read PHAssetResource.originalFilename for each resource.

The Swift API imports this property as non-optional:

var originalFilename: String { get }

However, we have customer reports from real Photos libraries where reading this property appears to crash because the underlying Objective-C value is nil at runtime. This affects actual users of our shipping app, not just a synthetic test case.

The relevant code path is essentially this:

import Photos

func inspectAsset(_ asset: PHAsset) {
    let resources = PHAssetResource.assetResources(for: asset)

    for resource in resources {
        // This property is imported as non-optional String.
        // For some affected customer assets, reading it appears to trap/crash
        // because the underlying value is nil.
        let filename: String = resource.originalFilename

        print(filename)
    }
}

This makes the API difficult to use safely from Swift: because the property is non-optional, there is no normal Swift optional-handling path before the crash.

We filed this as FB22589474. We also filed a related Feedback, FB22519412, for empty-string / otherwise unusable filename values.

That is a separate issue, but it points in the same direction: apps that export, back up, or sync Photos resources cannot treat PHAssetResource.originalFilename as a guaranteed usable filename.

For PHAssetResource.originalFilename, what is the intended contract?

Answered by Frameworks Engineer in 892732022

Thank you for the feedback report. Unfortunately, you will need to work around this by casting the return value to an Optional String:

let originalFilename: String? = resource.originalFilename
Accepted Answer

Thank you for the feedback report. Unfortunately, you will need to work around this by casting the return value to an Optional String:

let originalFilename: String? = resource.originalFilename

I use this API from Swift, so I’d like to make sure my code handles this safely even though I haven’t seen the crash myself.

Do you know which OS versions or Photos library states are affected by this nullability mismatch?

For nil or empty originalFilename values, is there another source for the original filename?

Do you know which OS versions or Photos library states are affected by this nullability mismatch?

This would affect all OS versions, but is likely dependent on the state a user's library.

For nil or empty originalFilename values, is there another source for the original filename?

This is the only API available to access that.

PHAssetResource.originalFilename can be nil despite non-optional Swift API
 
 
Q