2015-01-27 21 views
13

Tôi làm cách nào để gọi các chức năng iOS không công khai và truy cập các tính năng không công khai từ Swift? Cụ thể, tôi muốn sử dụng một lớp không công khai trong khung công tác QuartzCore. Một giải pháp mà tôi nghĩ đến là tạo dự án Objective-C "bắc cầu" để bọc các API ngoài công lập này vào các API công khai và gọi các hàm Objective-C này từ Swift. Tuy nhiên, giải pháp của tôi là Swift thuần túy và tôi muốn giữ nó theo cách đó. Có cách nào khác hơn không? (ví dụ: thêm một cái gì đó vào Objective-C bridging header file)Cách truy cập API riêng tư của iOS trong Swift?

Lưu ý: Tôi biết bạn đang nghĩ gì, các API riêng tư là riêng tư vì chúng không nên được sử dụng. Tôi biết những rủi ro, tôi nhận thức được tất cả các donwsides, hạn chế cửa hàng ứng dụng vv. Sau khi xem xét cẩn thận và rất nhiều nghiên cứu, nó unfortunatelly vẫn có vẻ là cách tốt nhất để đi trong trường hợp cụ thể này.

+0

Nếu bạn thêm đúng việc kê khai của những phương pháp riêng để một tiêu đề thu hẹp tệp, như thể chúng nằm trong một danh mục (có tên là 'PrivateButImmaUseTheseAnyway'), có hoạt động không? –

+0

@TheParamagneticCroissant Tôi không chắc chắn rằng tôi hiểu ý bạn là gì. Tôi không biết liệu có thể khai báo chỉ một phương thức trong tệp tiêu đề bắc cầu hay không. Tôi đã cố gắng khai báo toàn bộ lớp riêng tư - tôi có một lỗi biên dịch nói rằng lớp không tồn tại nhưng có lẽ tôi đã không làm điều đó một cách chính xác. – drasto

+0

Ý tôi là, bạn khai báo lớp riêng cùng với một thể loại, như sau: '@interface NSPrivateClass (PrivateStuff)', và thêm khai báo các phương thức riêng ở đó. –

Trả lời

7

Bạn có thể nhận các lớp học riêng tư bằng cách sử dụng NSClassFromString: và tương tác với chúng bằng cách sử dụng performSelector.

15

Bạn có thể thực hiện cùng một mẹo mà bạn sẽ làm nếu dự án của bạn nằm trong mục Mục tiêu-C.

Tạo tệp tiêu đề và đặt khai báo danh mục trên lớp, cùng với khai báo phương pháp riêng tư bạn muốn hiển thị. Sau đó, yêu cầu trình biên dịch Swift nhập tiêu đề bắc cầu này.

Vì mục đích trình diễn, tôi sẽ poke xung quanh trong nội bộ của NSBigMutableString, một lớp con riêng tư của NSMutableString và tôi sẽ gọi phương thức _isMarkedAsImmutable của nó.

Lưu ý rằng ở đây, toàn bộ lớp đó là riêng tư, do đó tôi phải khai báo nó là lớp con của siêu lớp thực đầu tiên. Bởi vì điều này, tôi cũng có thể tuyên bố đúng phương pháp trong bản khai của lớp; Tuy nhiên, điều đó sẽ không thể hiện được cách sử dụng loại lừa đảo (Private).

Nếu lớp học của bạn là công khai, thì rõ ràng bạn sẽ chỉ cần danh mục và bạn sẽ không cần phải (lại) khai báo lớp đó.

Bridge.h:

#import <Foundation/Foundation.h> 

@interface NSMutableString (Private) 
- (BOOL)_isMarkedAsImmutable; // this is a lie 
@end 

@interface NSBigMutableString : NSMutableString 
@end 

s.swift:

let s = NSBigMutableString() 
println(s._isMarkedAsImmutable()) 

Biên dịch và chạy:

$ xcrun -sdk macosx swiftc -o foo -import-objc-header Bridge.h s.swift 
$ ./foo 
false 
$ 
Các vấn đề liên quan