如何使用Swift的私有iOS框架?

达格·阿格伦

我想利用Swift应用程序在iOS上使用私有框架。我很清楚为什么这不是一个好主意,但是在测试中将很有用,因此App Store的限制不是问题,我已经详尽地研究了替代方案。

我想做的事情与此类似:

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中创建一个包装器,将所有的调用直接传递给类,但这似乎是多余的。对于这个问题是否有更优雅的解决方案?

达格·阿格伦

我找到了一个解决方案,它需要一些手动工作,但确实可以在纯Swift中工作。

诀窍是在Swift中创建一个与Objective-C方法匹配的@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()

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Swift框架中导入私有框架标头?

swift私有模块映射,尝试从框架内在Swift中使用objC代码

iOS混合动态框架-使用私有模块桥接objc标头

如何在私有仓库中使用Swift Package Manager?

如何将独立的Swift OS X应用程序链接到私有框架(也在Swift中创建)?

如何使用Moq框架在C#中编写私有方法的单元测试?

如何设置迦太基以使用私有存储库(例如Stash(Bitbucket))中的自己的框架?

iOS 在 cocoapods 上发布私有代码框架

iOS8 Swift:如何访问/编辑/删除默认/私有inputAccessoryView高度约束'_UIKBAutolayoutHeightConstraint'

iOS从Swift使用框架导入Swift类

如何隐藏iOS Framework的私有模块?

如何实例化私有/隐藏的Objective C框架类?

什么是“私有.NET框架”?

如何使用ARC在iOS 7中释放私有财产

iOS Xcode 10:具有pod依赖项的私有框架

如何使用AspectJ访问私有字段?

如何使用 pip 更新私有包?

如何在不将私有标头包含到框架中的情况下创建私有模块?

Swift 4:如何使用ios11视觉框架从人脸界标点创建人脸图

某些iOS框架如何使用不带@objc的可选内容定义Swift协议?

ios是否有任何授权的私有或公共框架供ios从屏幕截图中读取/获取文本?

Swift-如何声明私有嵌套结构?

如何在Swift框架中使用Cocoapods?

如何在swift框架中使用cocoapods

使用UIImagePickerController时,iOS 10错误[访问] <私有>

iOS HERE SDK NMAKit私有API使用

在iOS 8中使用私有API打开Siri

在Xcode≥7.3中处理私有框架

Xcode 7.3缺少私有框架