2015-01-27 8 views
13

Как я могу назвать непубличные функции iOS и получить доступ к непубличным объектам из Swift? В частности, я хотел бы использовать один непубличный класс в рамках QuartzCore.Как получить доступ к частным API-интерфейсам iOS в Swift?

Одним из решений, которые пришли мне на ум, является создание «мостикового» проекта Objective-C, который объединит эти непубличные API-интерфейсы в публичные и вызовет эти функции Objective-C из Swift. Тем не менее, теперь мое решение является чистым Swift, и я бы предпочел сохранить его таким образом. Есть ли еще более простой путь? (например, добавление чего-то к Objective-C bridging header file)

Примечание: Я знаю, что вы думаете, частные API-интерфейсы являются частными, потому что они не должны использоваться. Я знаю риски, я знаю обо всех donwsides, ограничениях в магазине приложений и т. Д. После всего, что тщательно рассмотрено и много исследований, это, к сожалению, по-прежнему кажется лучшим способом в этом конкретном случае.

+0

Если добавить правильно декларацию частных методов мостиковым заголовка файл, как если бы они были в категории (называемой, скажем, 'PrivateButImmaUseTheseAnyway'), работает ли это? –

+0

@ TheParamagneticCroissant Я не уверен, что понимаю, что вы имеете в виду. Я не знал, можно ли объявить только метод, соединяющий заголовочный файл. Я попытался объявить весь закрытый класс - у меня возникла ошибка компиляции, говоря, что класс не существует, но, возможно, я не сделал это правильно. – drasto

+0

Я имею в виду, что вы объявляете частный класс вместе с категорией, например: '@interface NSPrivateClass (PrivateStuff)', и добавьте там объявление частных методов. –

ответ

7

Вы можете получить частные классы, используя NSClassFromString: и взаимодействовать с ними, используя performSelector.

15

Вы можете сделать тот же трюк, что и вы, если ваш проект был в Objective-C.

Создайте файл заголовка и поместите объявление категории в класс вместе с объявлением частных методов, которые вы хотите открыть. Затем скажите компилятору Swift, чтобы импортировать заголовок моста.

Для демонстрационных целей я буду выступать в пределах NSBigMutableString, частного подкласса NSMutableString, и я назову его метод _isMarkedAsImmutable.

Обратите внимание, что здесь весь класс является приватным, поэтому я должен сначала объявить его подклассом своего реального суперкласса. Из-за этого я мог бы также объявить метод прямо в объявлении самого класса; что, однако, не продемонстрировало бы использование категории трюков (Private).

Если ваш класс является общедоступным, то, очевидно, вам понадобится только категория, и вам не понадобится (повторно) объявить сам класс.

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()) 

компилировать и запускать:

$ xcrun -sdk macosx swiftc -o foo -import-objc-header Bridge.h s.swift 
$ ./foo 
false 
$ 

 Смежные вопросы

  • Нет связанных вопросов^_^