MOTIVATION:

Sometimes, it’s necessary to write a top-level C function in order to interact 
with some C-based code. This can come up, for example, when making a new port 
for a cross-platform app that implements OS-dependent functionality via C 
functions. More urgently, though, it also pops up in certain Apple APIs, such 
as the standard QuickLook plug-in template. In order to write a QuickLook 
plug-in, developers are required to write implementations for certain 
predefined C functions, such as GeneratePreviewForURL(), 
GenerateThumbnailForURL(), CancelPreviewGeneration(), and 
CancelThumbnailGeneration(). Unfortunately, this API contract cannot be met in 
Swift. Currently, Swift can only expose class members to C/Objective-C, which 
means that implementing a QuickLook plug-in involves a rather awkward series of 
hoops to jump through:

GeneratePreview.swift:

class QLGlue: NSObject {
        @objc static func generatePreview(_: UnsafeMutableRawPointer, request 
preview: QLPreviewRequest, url: URL, contentTypeUTI: String, options: [String : 
Any]) -> OSStatus {
                // generate the preview
        }
}

GeneratePreview.m:

#import “MyProject-Swift.h"

OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef 
request, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) {
    return [QLGlue generatePreview:thisInterface request:request url:(__bridge 
NSURL *)url contentTypeUTI:(__bridge NSString *)contentTypeUTI 
options:(__bridge NSDictionary *)options];
}

PROPOSED SOLUTION:

Allow the @objc on top-level functions. This will cause the functions to be 
exposed as C functions, satisfying contracts such as Apple’s QuickLook plug-in 
contract, and allowing developers to just write:

@objc func generatePreview(_: UnsafeMutableRawPointer, _ preview: 
QLPreviewRequest, _ url: CFURL, _ contentTypeUTI: CFString, _ options: 
CFDictionary) -> OSStatus {
        // generate the preview
}

This would eliminate an entire source file of glue code.

IMPACT ON EXISTING CODE:

None, since @objc is not currently allowed on top-level functions. This is 
purely additive.

Charles

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to