仅当iOS11可用时才包含类的扩展名

Mak*_*tro 8 drag-and-drop swift bridging-header objc-bridging-header ios11

我试图扩展一个用Obj-C编写的类,并包含一个用Swift编写的扩展,使其符合UIDropInteractionDelegate,如下所示:

@available(iOS 11.0, *)
extension NoteEditViewController: UIDropInteractionDelegate {
    @available(iOS 11.0, *)
    public func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
        let operation: UIDropOperation
        if session.localDragSession == nil {
            operation = .forbidden
        } else {
            // If a local drag session exists, we only want to move an
            // existing item in the pin board to a different location.
            operation = .forbidden
        }
        return UIDropProposal(operation: operation)
    }

    @objc(setupDropInteractions)
    @available(iOS 11.0, *)
    func setupDropInteractions() {
        // Add drop interaction
        self.view.addInteraction(UIDropInteraction(delegate: self))
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是该Project_Name-Swift.h文件包含以下不能编译的代码:

@class UIDropInteraction;
@protocol UIDropSession;
@class UIDropProposal;

// This line is causing the issue saying "'UIDropInteractionDelegate' is partial: introduced in iOS 11.0"
@interface NoteEditViewController (SWIFT_EXTENSION(Bloomberg_Professional)) <UIDropInteractionDelegate>
- (UIDropProposal * _Nonnull)dropInteraction:(UIDropInteraction * _Nonnull)interaction sessionDidUpdate:(id <UIDropSession> _Nonnull)session SWIFT_WARN_UNUSED_RESULT SWIFT_AVAILABILITY(ios,introduced=11.0);
- (void)setupDropInteractions SWIFT_AVAILABILITY(ios,introduced=11.0);
@end
Run Code Online (Sandbox Code Playgroud)

编译器抱怨该文件中的接口是部分的.

'UIDropInteractionDelegate'是部分:在iOS 11.0中引入

我假设包括@available(iOS 11.0, *)会生成一个SWIFT_AVAILABILITY(ios,introduced=11.0)封装整个界面但我错了.

有没有办法来解决这个问题?

UPDATE


我实施了一个玩具示例.

这是玩具ViewController:

在此输入图像描述

这是快速扩展:

在此输入图像描述

这是生成的dnd_toy-Swift.h文件.

在此输入图像描述

你是对的,它只是一个警告,但我的问题是我们必须将所有警告视为我们项目中的错误.

关于如何从这里摆脱这个警告的任何想法?

all*_*enh 8

你已经完成了所有事情,如果不是非常迟钝,投诉是准确的.

基本上,由于您已经(正确地)将该功能标记为iOS 11中可用,因此编译器会警告您在任何针对<iOS 11的内容的代码中使用它.

因此,您可以通过将部署目标设置为iOS 11来避免投诉,这意味着不允许iOS 10的用户安装它.或者,您可以使用新的(to obj-c)@available构造来防止使用API​​.

if (@available(iOS 11, *)) {
    [self setupDropInteractions];
}
Run Code Online (Sandbox Code Playgroud)

Xcode 8不支持这种结构,因为它是Swift提供的#available结构的最新后端.

更新

我在说明我来自哪里.似乎我无法重现提问者正在经历的情况,所以我正在展示我能够做到的事情.

我可以生成2个不同的编译器警告,这些警告类似但似乎与原始问题不同.

这是我生成的objc接口my_project-Swift.h:

@interface NoteEditViewController (SWIFT_EXTENSION(conditional_class_declaration)) <UIDropInteractionDelegate>
    - (UIDropProposal * _Nonnull)dropInteraction:(UIDropInteraction * _Nonnull)interaction sessionDidUpdate:(id <UIDropSession> _Nonnull)session SWIFT_WARN_UNUSED_RESULT SWIFT_AVAILABILITY(ios,introduced=11.0);
    - (void)setupDropInteractions SWIFT_AVAILABILITY(ios,introduced=11.0);
@end
Run Code Online (Sandbox Code Playgroud)

问题1:声明和objc属性以符合协议

在此输入图像描述

问题2:使用扩展中声明的方法

在此输入图像描述

有了更多信息来重现编译错误,我将能够提供更多帮助.

更新2:希望是最后一个

我发现我们之间的行为差​​异是因为我的项目是用Xcode 8.3创建的,然后迁移到9.在这些事情发生后,构建设置似乎有所不同.有问题的设置CLANG_WARN_UNGUARDED_AVAILABILITY,我认为Xcode 9是新的.

在迁移过程中,项目最终会像这样:

  • 这映射到项YES.pbxproject的文件 在此输入图像描述

新项目创建后:

  • 这映射到术语YES_AGGRESSIVE.pbxproject文件 在此输入图像描述

WWDC2017中讨论了此设置- LLVM中的新功能,但他们所说的并不表示这种轻微的行为差异.我猜这是一个铿锵的错误,以及它如何处理两个设置之间的差异(但我欢迎其他输入).我确信你已经知道了,这个代码在iOS 10上运行正常.此外,如果你将设置更改为"是",你仍然会得到关于iOS 11 API的正确警告.


Far*_*our 8

在ObjC中,添加API_AVAILABLE(ios(11.0))到函数定义的末尾将禁止警告.像这样:

- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0))
{
     ... function implementation ...
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*ric 4

如果将 @available 添加到每个方法中,则将构建 Xcode 9 beta 4。如果仅在扩展级别添加@available,构建仍然会失败。