In this snippet, I try to map [RegisteredMediaAttachment]
to [BasicAttachmentInput]
, but only for those items that have a parseable uploadUrl
.
private func createSecondaryAttachments(
_ attachments: [RegisteredMediaAttachment]
) -> [BasicAttachmentInput] {
return attachments.compactMap {
guard let name = URL(string: $0.registration.uploadUrl) else {
return nil
}
return BasicAttachmentInput(
name: name,
contentType: $0.attachment.type.mime(),
sizeBytes: $0.attachment.data.count,
mediaId: $0.registration.media.id
)
}
}
However, Swift complains on the line return nil
that 'nil' is not compatible with closure result type 'BasicAttachmentInput'
This surprises me. I expect the function to compile and reduce the map result to contain only non-nil
values returned from the compactMap
closure. What is wrong with the snippet above?
Turns out Swift is just failing to infer the types correctly: simply annotating the compactMap()
closure with the implied return type solves the issue:
private func createSecondaryAttachments(
_ attachments: [RegisteredMediaAttachment]
) -> [BasicAttachmentInput] {
return attachments.compactMap { (attachment: RegisteredMediaAttachment) -> BasicAttachmentInput?
// Note the explicit return type signature of the closure above ^
guard let name = URL(string: $0.registration.uploadUrl) else {
return nil
}
return BasicAttachmentInput(
name: name,
contentType: $0.attachment.type.mime(),
sizeBytes: $0.attachment.data.count,
mediaId: $0.registration.media.id
)
}
}