protocols, optional, and public


(Rick M) #1

I'm wrapping CLLocationManager (and its delegate), and I'm trying to create a protocol like this. This is directly cribbed from CLLocationManagerDelegate.

···

---------------
public
protocol
LZLocationManagerDelegate : NSObjectProtocol
{
    optional public func locationManager(manager: LZLocationManager, didUpdateLocations locations: [CLLocation])
}
---------------

But I get these errors:

LZLocationManager.swift:16:5: 'optional' can only be applied to members of an @objc protocol
LZLocationManager.swift:70:41: Cannot use optional chaining on non-optional value of type '(LZLocationManager, didUpdateLocations: [CLLocation]) -> ()'

Apple's version compiles flawlessly (comments removed):

---------------
public protocol CLLocationManagerDelegate : NSObjectProtocol {
    @available(iOS 6.0, *)
    optional public func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])

    // ...remainder removed for brevity
}
---------------

Adding @objc fixes it, but I would have thought NSObjectProtocol implied that. Also, when I look at the Apple Swift exports, it's not there (is that a limitation of the exported view?).

--
Rick Mann
rmann@latencyzero.com


(Zhao Xin) #2

“Optional requirements are available so that you can write code that
interoperates with Objective-C. Both the protocol and the optional
requirement must be marked with the @objc attribute. ”

https://itun.es/us/k5SW7.l

I think the CLLocationManagerDelegate you saw was converted from
Objective-C, which means it was not written in Swift directly. It was just
the counterpart called interface. In swift, interface is automatically
generated. It is not the source file.

For example, you can create a new project, open a swift file, open
assistant window (option+command+enter). Add a protocol in your swift file.

public protocol UnmanagedCopy {

    func unmanagedCopy() -> Self
}

Build your project. Reload your interface file in the assistant window by
changing to other files and back. You can see the counterpart is

public protocol UnmanagedCopy {

    public func unmanagedCopy() -> Self

}

You should aware that though there is a `public func` in interface. You can
not do it in protocol definition in source file.

Further more, I also test a new protocol Foo.

@objc public protocol Foo {

    @objc optional func bar()
}

It turns out the counterpart is not as my expectation. The @objc remains.

@objc public protocol Foo {

    @objc optional public func bar()
}

Since my testing code was written in Swift, I thought the reason of that
was because the interface generated from Objective-C code was not identical
as from Swift. For an interface file generated from Objective-C, the source
code was definitely working in Objective-C. So the interface file was for
Swift only, which means there was no need to apply those restrictions.

Zhaoxin

···

from: Apple Inc. “The Swift Programming Language (Swift 3 Beta)”。 iBooks.

On Sat, Aug 27, 2016 at 8:52 AM, Rick Mann via swift-users < swift-users@swift.org> wrote:

I'm wrapping CLLocationManager (and its delegate), and I'm trying to
create a protocol like this. This is directly cribbed from
CLLocationManagerDelegate.

---------------
public
protocol
LZLocationManagerDelegate : NSObjectProtocol
{
    optional public func locationManager(manager: LZLocationManager,
didUpdateLocations locations: [CLLocation])
}
---------------

But I get these errors:

LZLocationManager.swift:16:5: 'optional' can only be applied to members of
an @objc protocol
LZLocationManager.swift:70:41: Cannot use optional chaining on
non-optional value of type '(LZLocationManager, didUpdateLocations:
[CLLocation]) -> ()'

Apple's version compiles flawlessly (comments removed):

---------------
public protocol CLLocationManagerDelegate : NSObjectProtocol {
    @available(iOS 6.0, *)
    optional public func locationManager(manager: CLLocationManager,
didUpdateLocations locations: [CLLocation])

    // ...remainder removed for brevity
}
---------------

Adding @objc fixes it, but I would have thought NSObjectProtocol implied
that. Also, when I look at the Apple Swift exports, it's not there (is that
a limitation of the exported view?).

--
Rick Mann
rmann@latencyzero.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users