Proposal PR submitted as https://github.com/apple/swift-evolution/pull/85
-Kevin Ballard
On Tue, Dec 15, 2015, at 11:18 AM, Kevin Ballard wrote:
> When writing ObjC code, there's a macro NS_REFINED_FOR_SWIFT (or
> __attribute__((swift_private))) that mangles the name when imported into
> Swift. The intention here is to hide an API from normal Swift usage (but
> still make it callable) so that a better Swift API can be written around it.
>
> But there's no facility for doing this in reverse. You can expose Swift APIs
> to ObjC, but the API has to be ObjC-compatible. Which means that if you have
> a non-ObjC-compatible API, you have to write a separate API to expose it to
> ObjC, and this separate API now shows up in the Swift API too.
>
> I think the simplest way to fix this is to allow for a modifier public(objc)
> (following the syntax of private(set)). The only thing this modifier does is
> ensure the declaration gets added to the generated header as if it were
> public (or—for apps—internal). If the declaration is not marked as @objc then
> it would emit an error (it could imply @objc but it feels weird to me to have
> an access control modifier do that). If the declaration is already public
> (but not internal, so the same source can be used in apps and libraries) it
> will emit a warning.
>
> Armed with this new modifier, I can start to write code like
>
> class MyClass: NSObject {
> func foo<T>(x: T) { ... }
> }
>
> extension MyClass {
> @objc(foo) public(objc) private func __foo(x: AnyObject) { ... }
> }
>
> When used on a property that already has private(set), the public(objc)
> modifier will only apply to the getter (e.g. the private(set) takes
> precedence for the setter).
>
> Alternatives:
>
> * Add a new attribute @export_objc that has the same behavior.
>
> * Change the @objc attribute to take an optional second argument, which may
> be the token "exported", as in @objc(foo,exported). When using the "exported"
> token, the selector portion is required. We could possibly support an empty
> selector to indicate the default, as in @objc(,exported), but that looks odd.
>
> My preference is for public(objc) as proposed as it matches more closely with
> the intended behavior, which is "this API is private in Swift and public in
> ObjC".
>
> -Kevin Ballard
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution