2015-01-27 17 views
13

Wie kann ich nicht-öffentliche iOS-Funktionen aufrufen und nicht öffentliche Eigenschaften von Swift aufrufen? Insbesondere möchte ich eine nicht öffentliche Klasse im QuartzCore-Framework verwenden. Eine Lösung, die mir in den Sinn kam, war das Erstellen eines "Bridging" Objective-C-Projekts, das diese nicht-öffentlichen APIs in öffentliche APIs einbinden und dann Objective-C-Funktionen von Swift nennen würde. Allerdings ist meine Lösung jetzt pure Swift und ich würde es lieber so behalten. Gibt es einen stabileren Weg? (zum Beispiel etwas zu Objective-C bridging header file hinzufügen)Zugriff auf private iOS-APIs in Swift?

Hinweis: Ich weiß, was Sie denken, private APIs sind privat, weil sie nicht verwendet werden sollten. Ich kenne die Risiken, ich bin mir der vielen Unwägbarkeiten, App-Store-Beschränkungen usw. bewusst. Nach all dem sorgfältig überlegten und vielen Nachforschungen scheint es unglücklicherweise immer noch der beste Weg zu sein, in diesem speziellen Fall zu gehen.

+0

Wenn Sie richtig die Deklaration der privaten Methoden auf einen Brückenkopf hinzufügen Datei, als ob sie in einer Kategorie wären (zB 'PrivateButImmaUseTeseAnyway'), funktioniert das? –

+0

@TheParamagneticCroissant Ich bin mir nicht sicher, ob ich verstehe, was du meinst. Ich wusste nicht, ob es möglich ist, nur eine Methode zum Überbrücken von Header-Dateien zu deklarieren. Ich habe versucht, die ganze private Klasse zu deklarieren - ich habe einen Kompilierungsfehler, der besagt, dass die Klasse nicht existiert, aber vielleicht habe ich es nicht richtig gemacht. – drasto

+0

Ich meine, Sie deklarieren die private Klasse zusammen mit einer Kategorie wie folgt: '@interface NSPrivateClass (PrivateStuff)', und fügen Sie dort die Deklaration der privaten Methoden hinzu. –

Antwort

7

Sie können private Klassen unter Verwendung NSClassFromString: erhalten und mit ihnen unter Verwendung performSelector interagieren.

15

Sie können den gleichen Trick machen, den Sie tun würden, wenn Ihr Projekt in Objective-C wäre.

Erstellen Sie eine Headerdatei, und fügen Sie die Deklaration einer Kategorie in die Klasse ein, zusammen mit der Deklaration der privaten Methoden, die Sie anzeigen möchten. Dann sagen Sie dem Swift-Compiler, diesen Bridging-Header zu importieren.

Zu Demonstrationszwecken stochere ich in den Interna von NSBigMutableString, eine private Unterklasse von NSMutableString, und ich werde seine _isMarkedAsImmutable Methode aufrufen.

Beachten Sie, dass hier die gesamte Klasse selbst privat ist, daher muss ich sie zuerst als Unterklasse ihrer echten Superklasse deklarieren. Aus diesem Grund hätte ich die Methode auch in der Deklaration der Klasse selbst erklären können; das hätte aber die Verwendung der Trick-Kategorie (Private) nicht gezeigt.

Wenn Ihre Klasse öffentlich ist, benötigen Sie natürlich nur die Kategorie, und Sie müssen die Klasse selbst nicht (erneut) deklarieren.

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

kompilieren und ausführen:

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