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))
}
}
_
私の問題は、_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
_
コンパイラは、そのファイルのインターフェイスが部分的であると文句を言っています。
「UIDropInteractionDelegate」は部分的です:iOS11.0で導入されました
@available(iOS 11.0, *)
を含めるとインターフェイス全体をカプセル化するSwift_AVAILABILITY(ios,introduced=11.0)
が生成されると思いましたが、間違っていました。
これを修正する方法はありますか?
[〜#〜]更新[〜#〜]
おもちゃの例を実装しました。
これがおもちゃのViewControllerです:
これがSwift拡張子です:
そして、これが生成されたdnd_toy-Swift.hファイルです。
単なる警告であるというのは正しかったのですが、私の問題は、すべての警告をプロジェクトのエラーとして扱わなければならないということです。
ここからこの警告を取り除く方法についてのアイデアはありますか?
@availableが各メソッドに追加されると、Xcode9ベータ4がビルドされます。 @availableが拡張レベルでのみ追加された場合でも、ビルドは失敗します。
ObjCでは、関数定義の最後にAPI_AVAILABLE(ios(11.0))
を追加すると、警告が抑制されます。このような:
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0))
{
... function implementation ...
}
あなたはすべてを正しく行いました、そして苦情は極端に鈍感ではないにしても正確です。
基本的に、その関数をiOS 11で使用可能として(正しく)マークしたので、コンパイラーは、iOS11未満のものを対象とするコードでの使用について警告します。
そのため、展開ターゲットをiOS 11に設定することで、苦情を解消できます。つまり、iOS10のユーザーは単にインストールを許可されません。または、新しい(obj-cへの)@available
構造を使用して、APIの使用を防ぐことができます。
if (@available(iOS 11, *)) {
[self setupDropInteractions];
}
このコンストラクトは、Swiftが提供する#availableコンストラクトの最近のバックポートであるため、Xcode8ではサポートされていません。
私はどこから来たのかを明確にしています。アスカーが経験している状況を再現できていないようですので、何ができたかをデモンストレーションしています。
2つの異なるコンパイラ警告を作成できますが、これらは類似していますが、元の質問と同じではないようです。
my_project-Swift.h
から生成されたobjcインターフェイスは次のとおりです。
@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
コンパイルエラーを再現するための詳細情報があれば、さらにサポートできるようになります。
私たちの間の振る舞いの不一致は、私のプロジェクトがXcode 8.3で作成され、その後9に移行されたという事実によるものであることがわかりました。問題の設定はCLANG_WARN_UNGUARDED_AVAILABILITY
で、これはXcode9の新機能だと思います。
この設定については WWDC2017-LLVMの新機能 で説明されていますが、この小さな動作の違いを示唆するものは何もありません。これはclangのバグであり、2つの設定の違いをどのように処理するかを推測しています(ただし、他の入力を歓迎します)。ご存知のとおり、このコードはiOS 10で正常に実行されます。また、設定を単に「はい」に変更しても、iOS 11APIに関する正しい警告が表示されます。