2016-03-21 4 views
2

私はSwiftアプリからiOSのプライベートフレームワークを利用したいと思っています。なぜこれが悪い考えであるのかよく分かっていますが、それはテスト中には便利なので、App Storeの制限は問題ではなく、私はかなり徹底的に代替案を検討しました。問題は、これはリンカエラーが発生しますということですSwiftのプライベートiOSフレームワークを使用するにはどうすればよいですか?

dlopen("/Developer/Library/PrivateFrameworks/UIAutomation.framework/UIAutomation".fileSystemRepresentation,RTLD_LOCAL); 

let eventsclass = NSClassFromString("UIASyntheticEvents") as? UIASyntheticEvents.Type 
eventGenerator = eventsclass!.sharedEventGenerator() as! UIASyntheticEvents 

Undefined symbols for architecture x86_64: 
    "_OBJC_CLASS_$_UIASyntheticEvents", referenced from: 
     type metadata accessor for __ObjC.UIASyntheticEvents in Test.o 

私はむしろ、直接フレームワークをリンクする場合は、私がやりたい何

は、この線に沿って何かでありますdlopen()を使用するよりも、シミュレータ上で正常に動作しますが、実際のデバイス用に構築するのに失敗します。SDKに用意されているフレームワークはシミュレータ専用であり、デバイス構築時にはリンクしません。

代わりにObjective-Cでこれらの呼び出しを実行しようとしましたが、問題の原因となったキャスト.Typeキャストの場合に備えて、これは役に立ちません。 Swiftから返されたオブジェクトにアクセスすると、同じエラーが発生します。

Objective-Cでクラスへのすべての呼び出しをまっすぐに渡すラッパーを作成することができますが、これは過剰なようです。この問題にはよりエレガントな解決策がありますか?

+0

静的なフレームワークに対してませんスウィフトリンケージ。 – matt

+0

私はあなたがここで何を意味するか分からない、静的なフレームワークは関与していません。 –

+0

OK、チェックしてください。 – matt

答えて

3

手作業を必要とするソリューションが1つ見つかりましたが、純粋なSwiftで動作します。

トリックは、Objective-Cメソッドと一致するSwiftで@objcプロトコルを作成し、そのプロトコルタイプへの安全でないキャストを行うことです。私の場合、プロトコルは次のようになります。

@objc protocol UIASyntheticEvents { 
    static func sharedEventGenerator() -> UIASyntheticEvents 

    //@property(readonly) struct __IOHIDEventSystemClient *ioSystemClient; // @synthesize ioSystemClient=_ioSystemClient; 
    var voiceOverStyleTouchEventsEnabled: Bool { get set } 
    var activePointCount: UInt64 { get set } 
    //@property(nonatomic) CDStruct_3eca2549 *activePoints; // @synthesize activePoints=_activePoints; 
    var gsScreenScale: Double { get set } 
    var gsScreenSize: CGSize { get set } 
    var screenSize: CGSize { get set } 
    var screen: UIScreen { get set } 
    var onScreenRect: CGRect { get set } 

    func sendPinchCloseWithStartPoint(_: CGPoint, endPoint: CGPoint, duration: Double, inRect: CGRect) 
    func sendPinchOpenWithStartPoint(_: CGPoint, endPoint: CGPoint, duration: Double, inRect: CGRect) 
    func sendDragWithStartPoint(_: CGPoint, endPoint: CGPoint, duration: Double, withFlick: Bool, inRect: CGRect) 
    func sendRotate(_: CGPoint, withRadius: Double, rotation: Double, duration: Double, touchCount: UInt64) 
    func sendMultifingerDragWithPointArray(_: UnsafePointer<CGPoint>, numPoints: Int32, duration: Double, numFingers: Int32) 
    func sendPinchCloseWithStartPoint(_: CGPoint, endPoint: CGPoint, duration: Double) 
    func sendPinchOpenWithStartPoint(_: CGPoint, endPoint: CGPoint, duration: Double) 
    func sendFlickWithStartPoint(_: CGPoint, endPoint: CGPoint, duration: Double) 
    func sendDragWithStartPoint(_: CGPoint, endPoint: CGPoint, duration: Double) 
    func sendTaps(_: Int, location: CGPoint, withNumberOfTouches: Int, inRect: CGRect) 
    func sendDoubleFingerTap(_: CGPoint) 
    func sendDoubleTap(_: CGPoint) 
    func _sendTap(_: CGPoint, withPressure: Double) 
    func sendTap(_: CGPoint) 
    func _setMajorRadiusForAllPoints(_: Double) 
    func _setPressureForAllPoints(_: Double) 
    func moveToPoints(_: UnsafePointer<CGPoint>, touchCount: UInt64, duration: Double) 
    func _moveLastTouchPoint(_: CGPoint) 
    func liftUp(_: CGPoint) 
    func liftUp(_: CGPoint, touchCount: UInt64) 
    func liftUpAtPoints(_: UnsafePointer<CGPoint>, touchCount: UInt64) 
    func touchDown(_: CGPoint) 
    func touchDown(_: CGPoint, touchCount: UInt64) 
    func touchDownAtPoints(_: UnsafePointer<CGPoint>, touchCount: UInt64) 
    func shake() 
    func setRinger(_: Bool) 
    func holdVolumeDown(_: Double) 
    func clickVolumeDown() 
    func holdVolumeUp(_: Double) 
    func clickVolumeUp() 
    func holdLock(_: Double) 
    func clickLock() 
    func lockDevice() 
    func holdMenu(_: Double) 
    func clickMenu() 
    func _sendSimpleEvent(_: Int) 
    func setOrientation(_: Int32) 
    func sendAccelerometerX(_: Double, Y: Double, Z: Double, duration: Double) 
    func sendAccelerometerX(_: Double, Y: Double, Z: Double) 
    func _updateTouchPoints(_: UnsafePointer<CGPoint>, count: UInt64) 
    func _sendHIDVendorDefinedEvent(_: UInt32, usage: UInt32, data: UnsafePointer<UInt8>, dataLength: UInt32) -> Bool 
    func _sendHIDScrollEventX(_: Double, Y: Double, Z: Double) -> Bool 
    func _sendHIDKeyboardEventPage(_: UInt32, usage: UInt32, duration: Double) -> Bool 
    //- (_Bool)_sendHIDEvent:(struct __IOHIDEvent *)arg1; 
    //- (struct __IOHIDEvent *)_UIACreateIOHIDEventType:(unsigned int)arg1; func _isEdgePoint(_: CGPoint) -> Bool 
    func _normalizePoint(_: CGPoint) -> CGPoint 
    //- (void)dealloc; 
    func _initScreenProperties() 
    //- (id)init; 
} 

これは、クラスダンプ出力から手作業で変換されました。誰かがそれを行うより速い方法を知っているなら、私は知りたいと思う。

あなたはこのプロトコルを持っていたら、あなたは、単に次の操作を実行できます。

dlopen("/Developer/Library/PrivateFrameworks/UIAutomation.framework/UIAutomation".fileSystemRepresentation,RTLD_LOCAL) 

    let eventsclass = unsafeBitCast(NSClassFromString("UIASyntheticEvents"), UIASyntheticEvents.Type.self) 
    eventGenerator = eventsclass.sharedEventGenerator() 
関連する問題