2016-05-09 15 views
5

Tôi đang cố gắng di chuyển từ từ từ Obj-C sang Swift. Bước đầu tiên của tôi là di chuyển các phương thức nhỏ, đơn giản sang các phần mở rộng Swift vì vậy tôi quyết định thử và di chuyển didRegisterForRemoteNotifications nhưng điều đó không hiệu quả vì nó cho rằng phương thức được thực hiện ở đâu đó trong mã Objective-C của tôi. Không phải vậy.Triển khai didRegisterForRemoteNotificationsWithDeviceToken trong tiện ích mở rộng Swift không hoạt động

Tôi đang sử dụng Xcode 7.3 (7D175)

Dưới đây là một số bước tái tạo:

  • Tạo một dự án obj-C mới.
  • Tạo tệp Swift trống mới có tên AppDelegate-Extension.swift. Điều này cũng tạo ra một tập tin tiêu đề Bridging.
  • Thêm #import AppDelegate.h vào tệp tiêu đề Ẩn.
  • Đến file Swift trống và gõ:

    extension AppDelegate { 
    
        public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { 
    
        } 
    } 
    

Điều này làm cho trình biên dịch để phàn nàn:

method 'application(_:didRegisterForRemoteNotificationsWithDeviceToken:)' with Objective-C selector 'application:didRegisterForRemoteNotificationsWithDeviceToken:' conflicts with previous declaration with the same Objective-C selector public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { ^ __ObjC.AppDelegate:38:17: note: 'application' previously declared here public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)

Tôi đang làm gì sai?

EDIT: Một số ý kiến ​​cho rằng tôi đã cố gắng:

Add override to the method declaration so it reads override public ...

này trả về lỗi sau (ngoài các lỗi ban đầu)

error: method does not override any method from its superclass override public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)

+0

bạn có ý nghĩa gì về tệp tiêu đề nhanh? Bạn nên tạo lớp Bridge và nhập 'AppDelegate.h' của bạn ở đó –

+0

Xin lỗi, đó là chính xác những gì tôi có ý nghĩa. Tôi đã chỉnh sửa câu hỏi để phản ánh điều này. – OlivaresF

+0

thử 'override func ứng dụng (ứng dụng: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {' –

Trả lời

2

Vấn đề của bạn là bạn có thể không sử dụng phần mở rộng theo cách này trong môi trường Swift & Mục tiêu-C hỗn hợp.

Trong Swift, bạn có thể sử dụng phần mở rộng để cung cấp các triển khai cho các hàm đã được khai báo trong một giao thức được một lớp chấp nhận. Đây là cốt lõi của 'lập trình theo định hướng giao thức'

Trong mục tiêu-C, một danh mục được sử dụng để thêm các chức năng bổ sung vào một lớp hiện có. Khi bạn tạo tiện ích mở rộng Swift của mình, Xcode tạo tệp targetname-Swift.h trong thư mục dữ liệu có nguồn gốc. Bây giờ, bạn không thể nhìn thấy tập tin này vì biên dịch của bạn là thất bại, nhưng nếu bạn thay đổi phần mở rộng của bạn một chút để biên soạn các công trình

extension AppDelegate { 
    public func application(app application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {  
    } 
} 

và sau đó bạn nhìn vào tập tin này, bạn sẽ tìm thấy một cái gì đó như:

@interface AppDelegate (SWIFT_EXTENSION(XTNTest)) 
    - (void)applicationWithApp:(UIApplication * _Nonnull)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData * _Nonnull)deviceToken; 
@end 

Lưu ý cách phương thức tiện ích mở rộng của bạn đã được thêm làm danh mục vào AppDelegate. Bây giờ, hãy tưởng tượng những gì tập tin này sẽ như thế nào nếu bạn có các hình thức đúng đắn về chức năng của bạn (không app trong chữ ký)

@interface AppDelegate (SWIFT_EXTENSION(XTNTest)) 
    - (void)application:(UIApplication * _Nonnull)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData * _Nonnull)deviceToken; 
@end 

Đây là một tái tuyên bố một phương pháp mà đã được khai báo trong giao thức UIApplicationDelegate.

Kết quả của tất cả điều này là bạn cần phải áp dụng Swift trên cơ sở từng lớp hoặc bạn cần sử dụng phân lớp nếu bạn muốn sử dụng cơ sở từng hàm vì có sự khác biệt giữa Mục tiêu-C thể loại và một phần mở rộng Swift.

+0

Đúng. My Test-Swift.h autogenerated tập tin trông rất giống với những gì bạn đã đề cập ... Cảm ơn! – OlivaresF

Các vấn đề liên quan