diff --git a/IOKit.framework/IOKit.tbd b/IOKit.framework/IOKit.tbd new file mode 120000 index 0000000..8632f1c --- /dev/null +++ b/IOKit.framework/IOKit.tbd @@ -0,0 +1 @@ +Versions/A/IOKit.tbd \ No newline at end of file diff --git a/IOKit.framework/Versions/A/IOKit.tbd b/IOKit.framework/Versions/A/IOKit.tbd new file mode 100755 index 0000000..e8f2838 --- /dev/null +++ b/IOKit.framework/Versions/A/IOKit.tbd @@ -0,0 +1,852 @@ +--- +archs: [ armv7, armv7s, arm64 ] +platform: ios +install-name: /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit +current-version: 275.0 +exports: + - archs: [ armv7, armv7s ] + symbols: [ _IOConnectMethodScalarIScalarO, _IOConnectMethodScalarIStructureI, + _IOConnectMethodScalarIStructureO, _IOConnectMethodStructureIStructureO, + _IOMapMemory, _io_async_method_scalarI_scalarO, + _io_async_method_scalarI_structureI, _io_async_method_scalarI_structureO, + _io_async_method_structureI_structureO, _io_catalog_get_data, + _io_catalog_get_gen_count, _io_catalog_module_loaded, + _io_catalog_reset, _io_catalog_send_data, _io_catalog_terminate, + _io_connect_add_client, _io_connect_async_method, + _io_connect_get_notification_semaphore, _io_connect_get_service, + _io_connect_map_memory, _io_connect_map_memory_into_task, + _io_connect_method, _io_connect_method_scalarI_scalarO, + _io_connect_method_scalarI_structureI, _io_connect_method_scalarI_structureO, + _io_connect_method_structureI_structureO, _io_connect_method_var_output, + _io_connect_set_notification_port, _io_connect_set_properties, + _io_connect_unmap_memory, _io_connect_unmap_memory_from_task, + _io_iterator_is_valid, _io_iterator_next, _io_iterator_reset, + _io_object_conforms_to, _io_object_get_bundle_identifier, + _io_object_get_class, _io_object_get_retain_count, + _io_object_get_superclass, _io_registry_create_iterator, + _io_registry_entry_create_iterator, _io_registry_entry_from_path, + _io_registry_entry_from_path_ool, _io_registry_entry_get_child_iterator, + _io_registry_entry_get_location_in_plane, _io_registry_entry_get_name, + _io_registry_entry_get_name_in_plane, _io_registry_entry_get_parent_iterator, + _io_registry_entry_get_path, _io_registry_entry_get_path_ool, + _io_registry_entry_get_properties, _io_registry_entry_get_properties_bin, + _io_registry_entry_get_property, _io_registry_entry_get_property_bin, + _io_registry_entry_get_property_bytes, _io_registry_entry_get_property_recursively, + _io_registry_entry_get_registry_entry_id, _io_registry_entry_in_plane, + _io_registry_entry_set_properties, _io_registry_get_root_entry, + _io_registry_iterator_enter_entry, _io_registry_iterator_exit_entry, + _io_server_version, _io_service_acknowledge_notification, + _io_service_add_interest_notification, _io_service_add_notification, + _io_service_add_notification_bin, _io_service_add_notification_ool, + _io_service_close, _io_service_get_authorization_id, + _io_service_get_busy_state, _io_service_get_matching_service, + _io_service_get_matching_service_bin, _io_service_get_matching_service_ool, + _io_service_get_matching_services, _io_service_get_matching_services_bin, + _io_service_get_matching_services_ool, _io_service_get_state, + _io_service_match_property_table, _io_service_match_property_table_bin, + _io_service_match_property_table_ool, _io_service_open_extended, + _io_service_request_probe, _io_service_set_authorization_id, + _io_service_wait_quiet ] + - archs: [ armv7, armv7s, arm64 ] + symbols: [ _IOAVAudioFormatTypeString, _IOAVAudioGetChannelAllocation, + _IOAVAudioGetChannelAllocationDefault, _IOAVAudioGetChannelLayoutData, + _IOAVAudioGetSpeakerAllocationMask, _IOAVAudioInterfaceCopyChannelLayoutElements, + _IOAVAudioInterfaceCopyDiagnosticsString, _IOAVAudioInterfaceCopyElements, + _IOAVAudioInterfaceCopyProperties, _IOAVAudioInterfaceCopyProperty, + _IOAVAudioInterfaceCreate, _IOAVAudioInterfaceCreateWithService, + _IOAVAudioInterfaceGetLinkData, _IOAVAudioInterfaceGetLinkDataWithSource, + _IOAVAudioInterfaceGetService, _IOAVAudioInterfaceGetTypeID, + _IOAVAudioInterfaceSetLogLevel, _IOAVAudioInterfaceSetLogLevelMask, + _IOAVAudioInterfaceSetProperty, _IOAVAudioInterfaceStartLink, + _IOAVAudioInterfaceStartLinkWithSource, _IOAVAudioInterfaceStopLink, + _IOAVAudioInterfaceStopLinkWithSource, _IOAVAudioSampleRate, + _IOAVAudioSampleRateScalar, _IOAVAudioSampleSize, + _IOAVAudioSpeakerString, _IOAVCommandString, _IOAVControlInterfaceCopyDiagnosticsString, + _IOAVControlInterfaceCopyProperties, _IOAVControlInterfaceCopyProperty, + _IOAVControlInterfaceCreate, _IOAVControlInterfaceCreateWithService, + _IOAVControlInterfaceGetService, _IOAVControlInterfaceGetTypeID, + _IOAVControlInterfaceSetLogLevel, _IOAVControlInterfaceSetLogLevelMask, + _IOAVControlInterfaceSetProperty, _IOAVControllerClearEventLog, + _IOAVControllerCopyDiagnosticsString, _IOAVControllerCopyProperties, + _IOAVControllerCopyProperty, _IOAVControllerCreate, + _IOAVControllerCreateWithLocation, _IOAVControllerCreateWithService, + _IOAVControllerForceHotPlugDetect, _IOAVControllerGetLocation, + _IOAVControllerGetPower, _IOAVControllerGetTypeID, + _IOAVControllerSetEventLogCommandMask, _IOAVControllerSetEventLogEventMask, + _IOAVControllerSetEventLogSize, _IOAVControllerSetLogLevel, + _IOAVControllerSetLogLevelMask, _IOAVControllerSetPower, + _IOAVControllerSetProperty, _IOAVControllerSetProtectionType, + _IOAVControllerSetQualityPattern, _IOAVCreateDiagnosticsReference, + _IOAVCreateDiagnosticsReferenceWithLocation, _IOAVCreateDiagnosticsString, + _IOAVCreateDiagnosticsStringWithLocation, _IOAVCreateStringWithAudioChannelLayoutData, + _IOAVCreateStringWithAudioLinkData, _IOAVCreateStringWithData, + _IOAVCreateStringWithElement, _IOAVCreateStringWithElements, + _IOAVCreateStringWithVideoColorData, _IOAVCreateStringWithVideoLinkData, + _IOAVCreateStringWithVideoTimingData, _IOAVDeviceClearEventLog, + _IOAVDeviceCopyDiagnosticsString, _IOAVDeviceCopyProperties, + _IOAVDeviceCopyProperty, _IOAVDeviceCreate, _IOAVDeviceCreateWithLocation, + _IOAVDeviceCreateWithService, _IOAVDeviceGetController, + _IOAVDeviceGetLinkData, _IOAVDeviceGetLocation, + _IOAVDeviceGetPower, _IOAVDeviceGetProtectionStatus, + _IOAVDeviceGetProtectionType, _IOAVDeviceGetTypeID, + _IOAVDeviceReadI2C, _IOAVDeviceSetEventLogCommandMask, + _IOAVDeviceSetEventLogEventMask, _IOAVDeviceSetEventLogSize, + _IOAVDeviceSetLogLevel, _IOAVDeviceSetLogLevelMask, + _IOAVDeviceSetPower, _IOAVDeviceSetProperty, _IOAVDeviceStartLink, + _IOAVDeviceStopLink, _IOAVDeviceWriteI2C, _IOAVEDIDIsStandard, + _IOAVElementTypeString, _IOAVEventLogEventTypeString, + _IOAVGetCEAVideoShortID, _IOAVGetCEAVideoShortIDWithData, + _IOAVGetCEAVideoShortIDWithDataActive, _IOAVGetCEAVideoTimingData, + _IOAVGetCEAVideoTimingDataWithShortID, _IOAVGetCVTVideoTimingData, + _IOAVGetDMTVideoTimingData, _IOAVGetGTFVideoTimingData, + _IOAVGetSPDInfoFrame, _IOAVGetSupportedVideoTimingDataList, + _IOAVGetTransportSupportsCEA, _IOAVGetTransportSupportsYCbCr, + _IOAVGetVideoTimingData, _IOAVGetVideoTimingITSource, + _IOAVHDMIAudioClockRegenerationDataForLink, _IOAVInfoFrameGetChecksum, + _IOAVInfoFrameTypeString, _IOAVLinkSourceString, + _IOAVLinkTypeString, _IOAVLocationString, _IOAVProtectionStatusString, + _IOAVProtectionTypeString, _IOAVRecoverableError, + _IOAVServiceClearEventLog, _IOAVServiceCopyDiagnosticsString, + _IOAVServiceCopyEDID, _IOAVServiceCopyProperties, + _IOAVServiceCopyProperty, _IOAVServiceCreate, _IOAVServiceCreateWithLocation, + _IOAVServiceCreateWithService, _IOAVServiceGetDevice, + _IOAVServiceGetLinkData, _IOAVServiceGetLinkDataWithSource, + _IOAVServiceGetPower, _IOAVServiceGetProtectionStatus, + _IOAVServiceGetProtectionType, _IOAVServiceGetTypeID, + _IOAVServiceSetEventLogCommandMask, _IOAVServiceSetEventLogEventMask, + _IOAVServiceSetEventLogSize, _IOAVServiceSetLogLevel, + _IOAVServiceSetLogLevelMask, _IOAVServiceSetPower, + _IOAVServiceSetProperty, _IOAVServiceSetVirtualEDIDMode, + _IOAVServiceStartInfoFrame, _IOAVServiceStartInfoFrameWithSource, + _IOAVServiceStartLink, _IOAVServiceStartLinkWithSource, + _IOAVServiceStopInfoFrame, _IOAVServiceStopInfoFrameWithSource, + _IOAVServiceStopLink, _IOAVServiceStopLinkWithSource, + _IOAVServiceSupportsLink, _IOAVStandardTypeString, + _IOAVSupportedVideoTimingDataListTypeString, _IOAVTransportString, + _IOAVVideoActiveFormatAspectRatio, _IOAVVideoAxisString, + _IOAVVideoColorBitDepth, _IOAVVideoColorBitDepthScalar, + _IOAVVideoColorCoefficientString, _IOAVVideoColorDynamicRangeString, + _IOAVVideoColorSpaceString, _IOAVVideoGetPixelClockTolerance, + _IOAVVideoInterfaceCopyColorElements, _IOAVVideoInterfaceCopyDiagnosticsString, + _IOAVVideoInterfaceCopyProperties, _IOAVVideoInterfaceCopyProperty, + _IOAVVideoInterfaceCopyTimingElements, _IOAVVideoInterfaceCreate, + _IOAVVideoInterfaceCreateWithLocation, _IOAVVideoInterfaceCreateWithService, + _IOAVVideoInterfaceGetLinkData, _IOAVVideoInterfaceGetLinkDataWithSource, + _IOAVVideoInterfaceGetService, _IOAVVideoInterfaceGetTypeID, + _IOAVVideoInterfaceSetBounds, _IOAVVideoInterfaceSetColorDitherRemoval, + _IOAVVideoInterfaceSetLogLevel, _IOAVVideoInterfaceSetLogLevelMask, + _IOAVVideoInterfaceSetProperty, _IOAVVideoInterfaceSetRotation, + _IOAVVideoInterfaceStartLink, _IOAVVideoInterfaceStartLinkWithSource, + _IOAVVideoInterfaceStopLink, _IOAVVideoInterfaceStopLinkWithSource, + _IOAVVideoLinkModeString, _IOAVVideoTimingCalculatedTypeString, + _IOAVVideoTimingGetActivePixelClock, _IOAVVideoTimingGetPixelClock, + _IOAVVideoTimingGetSyncRateRounded, _IOAVVideoTimingTypeString, + _IOAllowPowerChange, _IOBSDNameMatching, _IOCFSerialize, + _IOCFURLWriteDataAndPropertiesToResource, _IOCFUnserialize, + _IOCFUnserializeBinary, _IOCFUnserializeWithSize, + _IOCFUnserializeparse, _IOCancelPowerChange, _IOCatalogueGetData, + _IOCatalogueModuleLoaded, _IOCatalogueReset, _IOCatalogueSendData, + _IOCatalogueTerminate, _IOCatlogueGetGenCount, _IOCloseConnection, + _IOCompatibiltyNumber, _IOConnectAddClient, _IOConnectAddRef, + _IOConnectCallAsyncMethod, _IOConnectCallAsyncScalarMethod, + _IOConnectCallAsyncStructMethod, _IOConnectCallMethod, + _IOConnectCallScalarMethod, _IOConnectCallStructMethod, + _IOConnectGetService, _IOConnectMapMemory, _IOConnectMapMemory64, + _IOConnectRelease, _IOConnectSetCFProperties, _IOConnectSetCFProperty, + _IOConnectSetNotificationPort, _IOConnectTrap0, + _IOConnectTrap1, _IOConnectTrap2, _IOConnectTrap3, + _IOConnectTrap4, _IOConnectTrap5, _IOConnectTrap6, + _IOConnectUnmapMemory, _IOConnectUnmapMemory64, + _IOCopySystemLoadAdvisoryDetailed, _IOCreatePlugInInterfaceForService, + _IOCreateReceivePort, _IODPCalculateM, _IODPCommandString, + _IODPCompareLinkTrainingData, _IODPControllerCreate, + _IODPControllerCreateWithLocation, _IODPControllerCreateWithService, + _IODPControllerGetAVController, _IODPControllerGetMaxLaneCount, + _IODPControllerGetMaxLinkRate, _IODPControllerGetMinLaneCount, + _IODPControllerGetMinLinkRate, _IODPControllerGetTypeID, + _IODPControllerSetDownspreadModulationFrequency, + _IODPControllerSetDriveSettings, _IODPControllerSetLaneCount, + _IODPControllerSetLinkRate, _IODPControllerSetMaxLaneCount, + _IODPControllerSetMaxLinkRate, _IODPControllerSetMinLaneCount, + _IODPControllerSetMinLinkRate, _IODPControllerSetSupportsALPM, + _IODPControllerSetSupportsDownspread, _IODPControllerSetSupportsEnhancedMode, + _IODPControllerSetSupportsScrambling, _IODPCreateStringWithLinkTrainingData, + _IODPDeviceCreate, _IODPDeviceCreateWithLocation, + _IODPDeviceCreateWithService, _IODPDeviceGetAVDevice, + _IODPDeviceGetController, _IODPDeviceGetLinkTrainingData, + _IODPDeviceGetMaxLaneCount, _IODPDeviceGetMaxLinkRate, + _IODPDeviceGetRevisionMajor, _IODPDeviceGetRevisionMinor, + _IODPDeviceGetSinkCount, _IODPDeviceGetSupportsDownspread, + _IODPDeviceGetSupportsEnhancedMode, _IODPDeviceGetSymbolErrorCount, + _IODPDeviceGetTypeID, _IODPDeviceReadDPCD, _IODPDeviceSetALPMEnabled, + _IODPDeviceTypeString, _IODPDeviceWriteDPCD, _IODPDriveSettingsAreValid, + _IODPEventLogEventTypeString, _IODPLinkMaxPixelRate, + _IODPLinkRateEnum, _IODPLinkRateIsStandard, _IODPLinkRateScalar, + _IODPLinkSymbolRate, _IODPServiceCreate, _IODPServiceCreateWithLocation, + _IODPServiceCreateWithService, _IODPServiceGetAVService, + _IODPServiceGetDevice, _IODPServiceGetSinkCount, + _IODPServiceGetSymbolErrorCount, _IODPServiceGetTypeID, + _IODPServiceRetrainLink, _IODPServiceSetLinkCheckEnable, + _IODPStreamClockHz, _IODPTrainingPatternLength, + _IODPVideoMinLinkRate, _IODataQueueAllocateNotificationPort, + _IODataQueueDataAvailable, _IODataQueueDequeue, + _IODataQueueEnqueue, _IODataQueuePeek, _IODataQueueSetNotificationPort, + _IODataQueueWaitForAvailableData, _IODeregisterApp, + _IODeregisterForSystemPower, _IODestroyPlugInInterface, + _IODispatchCalloutFromCFMessage, _IODispatchCalloutFromMessage, + _IOEthernetControllerCreate, _IOEthernetControllerGetBSDSocket, + _IOEthernetControllerGetIONetworkInterfaceObject, + _IOEthernetControllerGetTypeID, _IOEthernetControllerReadPacket, + _IOEthernetControllerRegisterBSDAttachCallback, + _IOEthernetControllerRegisterDisableCallback, _IOEthernetControllerRegisterEnableCallback, + _IOEthernetControllerRegisterPacketAvailableCallback, + _IOEthernetControllerScheduleWithRunLoop, _IOEthernetControllerSetDispatchQueue, + _IOEthernetControllerSetLinkStatus, _IOEthernetControllerSetPowerSavings, + _IOEthernetControllerUnscheduleFromRunLoop, _IOEthernetControllerWritePacket, + _IOGetSystemLoadAdvisory, _IOHIDCopyCFTypeParameter, + _IOHIDCreateSharedMemory, _IOHIDDeviceClose, _IOHIDDeviceConformsTo, + _IOHIDDeviceCopyMatchingElements, _IOHIDDeviceCopyValueMultiple, + _IOHIDDeviceCopyValueMultipleWithCallback, _IOHIDDeviceCreate, + _IOHIDDeviceGetProperty, _IOHIDDeviceGetReport, + _IOHIDDeviceGetReportWithCallback, _IOHIDDeviceGetService, + _IOHIDDeviceGetTypeID, _IOHIDDeviceGetValue, _IOHIDDeviceGetValueWithCallback, + _IOHIDDeviceOpen, _IOHIDDeviceRegisterInputReportCallback, + _IOHIDDeviceRegisterInputReportWithTimeStampCallback, + _IOHIDDeviceRegisterInputValueCallback, _IOHIDDeviceRegisterRemovalCallback, + _IOHIDDeviceScheduleWithRunLoop, _IOHIDDeviceSetInputValueMatching, + _IOHIDDeviceSetInputValueMatchingMultiple, _IOHIDDeviceSetProperty, + _IOHIDDeviceSetReport, _IOHIDDeviceSetReportWithCallback, + _IOHIDDeviceSetValue, _IOHIDDeviceSetValueMultiple, + _IOHIDDeviceSetValueMultipleWithCallback, _IOHIDDeviceSetValueWithCallback, + _IOHIDDeviceUnscheduleFromRunLoop, _IOHIDElementAttach, + _IOHIDElementCopyAttached, _IOHIDElementCreateWithDictionary, + _IOHIDElementDetach, _IOHIDElementGetChildren, _IOHIDElementGetCollectionType, + _IOHIDElementGetCookie, _IOHIDElementGetDevice, + _IOHIDElementGetDuplicateIndex, _IOHIDElementGetLogicalMax, + _IOHIDElementGetLogicalMin, _IOHIDElementGetName, + _IOHIDElementGetParent, _IOHIDElementGetPhysicalMax, + _IOHIDElementGetPhysicalMin, _IOHIDElementGetProperty, + _IOHIDElementGetReportCount, _IOHIDElementGetReportID, + _IOHIDElementGetReportSize, _IOHIDElementGetType, + _IOHIDElementGetTypeID, _IOHIDElementGetUnit, _IOHIDElementGetUnitExponent, + _IOHIDElementGetUsage, _IOHIDElementGetUsagePage, + _IOHIDElementHasNullState, _IOHIDElementHasPreferredState, + _IOHIDElementIsArray, _IOHIDElementIsNonLinear, + _IOHIDElementIsRelative, _IOHIDElementIsVirtual, + _IOHIDElementIsWrapping, _IOHIDElementSetProperty, + _IOHIDEventAppendEvent, _IOHIDEventConformsTo, _IOHIDEventConformsToWithOptions, + _IOHIDEventCreate, _IOHIDEventCreateAccelerometerEvent, + _IOHIDEventCreateAccelerometerEventWithType, _IOHIDEventCreateAmbientLightSensorEvent, + _IOHIDEventCreateAtmosphericPressureEvent, _IOHIDEventCreateBiometricEvent, + _IOHIDEventCreateBoundaryScrollEvent, _IOHIDEventCreateButtonEvent, + _IOHIDEventCreateButtonEventWithPressure, _IOHIDEventCreateCompassEvent, + _IOHIDEventCreateCompassEventWithType, _IOHIDEventCreateCopy, + _IOHIDEventCreateData, _IOHIDEventCreateDigitizerEvent, + _IOHIDEventCreateDigitizerFingerEvent, _IOHIDEventCreateDigitizerFingerEventWithQuality, + _IOHIDEventCreateDigitizerStylusEvent, _IOHIDEventCreateDigitizerStylusEventWithPolarOrientation, + _IOHIDEventCreateDockSwipeEvent, _IOHIDEventCreateFluidTouchGestureEvent, + _IOHIDEventCreateForceEvent, _IOHIDEventCreateGyroEvent, + _IOHIDEventCreateGyroEventWithType, _IOHIDEventCreateKeyboardEvent, + _IOHIDEventCreateLEDEvent, _IOHIDEventCreateMotionActivtyEvent, + _IOHIDEventCreateMotionGestureEvent, _IOHIDEventCreateMouseEvent, + _IOHIDEventCreateNavigationSwipeEvent, _IOHIDEventCreateOrientationEvent, + _IOHIDEventCreatePolarOrientationEvent, _IOHIDEventCreateProgressEvent, + _IOHIDEventCreateProximtyEvent, _IOHIDEventCreateRelativePointerEvent, + _IOHIDEventCreateRotationEvent, _IOHIDEventCreateScaleEvent, + _IOHIDEventCreateScrollEvent, _IOHIDEventCreateSwipeEvent, + _IOHIDEventCreateSymbolicHotKeyEvent, _IOHIDEventCreateTranslationEvent, + _IOHIDEventCreateUnicodeEvent, _IOHIDEventCreateUnicodeEventWithQuality, + _IOHIDEventCreateVelocityEvent, _IOHIDEventCreateVendorDefinedEvent, + _IOHIDEventCreateWithBytes, _IOHIDEventCreateWithData, + _IOHIDEventCreateZoomToggleEvent, _IOHIDEventGetAttributeData, + _IOHIDEventGetAttributeDataLength, _IOHIDEventGetAttributeDataPtr, + _IOHIDEventGetChildren, _IOHIDEventGetDataLength, + _IOHIDEventGetDataValue, _IOHIDEventGetDataValueWithOptions, + _IOHIDEventGetEvent, _IOHIDEventGetEventFlags, _IOHIDEventGetEventWithOptions, + _IOHIDEventGetFloatMultiple, _IOHIDEventGetFloatMultipleWithOptions, + _IOHIDEventGetFloatValue, _IOHIDEventGetFloatValueWithOptions, + _IOHIDEventGetIntegerMultiple, _IOHIDEventGetIntegerMultipleWithOptions, + _IOHIDEventGetIntegerValue, _IOHIDEventGetIntegerValueWithOptions, + _IOHIDEventGetLatency, _IOHIDEventGetParent, _IOHIDEventGetPhase, + _IOHIDEventGetPosition, _IOHIDEventGetPositionWithOptions, + _IOHIDEventGetSenderID, _IOHIDEventGetTimeStamp, + _IOHIDEventGetType, _IOHIDEventGetTypeID, _IOHIDEventGetTypeString, + _IOHIDEventGetVendorDefinedData, _IOHIDEventIsAbsolute, + _IOHIDEventIsRepeat, _IOHIDEventQueueCreate, _IOHIDEventQueueCreateWithVM, + _IOHIDEventQueueDequeueCopy, _IOHIDEventQueueEnqueue, + _IOHIDEventQueueGetMemoryHandle, _IOHIDEventQueueGetNotificationPort, + _IOHIDEventQueueGetTypeID, _IOHIDEventQueueIsActive, + _IOHIDEventQueueSetNotificationPort, _IOHIDEventQueueStart, + _IOHIDEventQueueStop, _IOHIDEventReadBytes, _IOHIDEventRemoveEvent, + _IOHIDEventServerCreate, _IOHIDEventServerGetTypeID, + _IOHIDEventServerScheduleWithDispatchQueue, _IOHIDEventServerUnscheduleFromDispatchQueue, + _IOHIDEventSetAttributeData, _IOHIDEventSetEventFlags, + _IOHIDEventSetFloatMultiple, _IOHIDEventSetFloatMultipleWithOptions, + _IOHIDEventSetFloatValue, _IOHIDEventSetFloatValueWithOptions, + _IOHIDEventSetIntegerMultiple, _IOHIDEventSetIntegerMultipleWithOptions, + _IOHIDEventSetIntegerValue, _IOHIDEventSetIntegerValueWithOptions, + _IOHIDEventSetPhase, _IOHIDEventSetPosition, _IOHIDEventSetPositionWithOptions, + _IOHIDEventSetRepeat, _IOHIDEventSetSenderID, _IOHIDEventSetTimeStamp, + _IOHIDEventSystemClient, _IOHIDEventSystemClientCopyProperty, + _IOHIDEventSystemClientCopyServiceForRegistryID, + _IOHIDEventSystemClientCopyServices, _IOHIDEventSystemClientCreate, + _IOHIDEventSystemClientCreateWithType, _IOHIDEventSystemClientDispatchEvent, + _IOHIDEventSystemClientGetTypeID, _IOHIDEventSystemClientGetTypeString, + _IOHIDEventSystemClientRegisterDeviceMatchingBlock, + _IOHIDEventSystemClientRegisterDeviceMatchingCallback, + _IOHIDEventSystemClientRegisterEventBlock, _IOHIDEventSystemClientRegisterEventCallback, + _IOHIDEventSystemClientRegisterEventFilterBlock, + _IOHIDEventSystemClientRegisterEventFilterBlockWithPriority, + _IOHIDEventSystemClientRegisterEventFilterCallback, + _IOHIDEventSystemClientRegisterEventFilterCallbackWithPriority, + _IOHIDEventSystemClientRegisterPropertyChangedCallback, + _IOHIDEventSystemClientRegisterResetCallback, _IOHIDEventSystemClientRegistryIDConformsTo, + _IOHIDEventSystemClientScheduleWithDispatchQueue, + _IOHIDEventSystemClientScheduleWithRunLoop, _IOHIDEventSystemClientSetMatching, + _IOHIDEventSystemClientSetMatchingMultiple, _IOHIDEventSystemClientSetProperty, + _IOHIDEventSystemClientUnregisterDeviceMatchingBlock, + _IOHIDEventSystemClientUnregisterDeviceMatchingCallback, + _IOHIDEventSystemClientUnregisterEventBlock, _IOHIDEventSystemClientUnregisterEventCallback, + _IOHIDEventSystemClientUnregisterEventFilterBlock, + _IOHIDEventSystemClientUnregisterEventFilterCallback, + _IOHIDEventSystemClientUnregisterPropertyChangedCallback, + _IOHIDEventSystemClientUnregisterResetCallback, + _IOHIDEventSystemClientUnscheduleFromDispatchQueue, + _IOHIDEventSystemClientUnscheduleWithRunLoop, _IOHIDEventSystemClose, + _IOHIDEventSystemConnectionDispatchEvent, _IOHIDEventSystemConnectionGetAttribute, + _IOHIDEventSystemConnectionGetTask, _IOHIDEventSystemConnectionGetType, + _IOHIDEventSystemConnectionGetTypeID, _IOHIDEventSystemConnectionGetTypeString, + _IOHIDEventSystemCopyConnections, _IOHIDEventSystemCopyEvent, + _IOHIDEventSystemCopyMatchingServices, _IOHIDEventSystemCopyService, + _IOHIDEventSystemCopyServices, _IOHIDEventSystemCreate, + _IOHIDEventSystemGetProperty, _IOHIDEventSystemGetTypeID, + _IOHIDEventSystemOpen, _IOHIDEventSystemRegisterConnectionAdditionCallback, + _IOHIDEventSystemRegisterConnectionRemovalCallback, + _IOHIDEventSystemRegisterServicesCallback, _IOHIDEventSystemSetCallback, + _IOHIDEventSystemSetProperty, _IOHIDEventSystemUnregisterConnectionAdditionCallback, + _IOHIDEventSystemUnregisterConnectionRemovalCallback, + _IOHIDEventSystemUnregisterServicesCallback, _IOHIDEventTypeGetName, + _IOHIDGetAccelerationWithKey, _IOHIDGetActivityState, + _IOHIDGetButtonEventNum, _IOHIDGetModifierLockState, + _IOHIDGetMouseAcceleration, _IOHIDGetMouseButtonMode, + _IOHIDGetParameter, _IOHIDGetScrollAcceleration, + _IOHIDGetStateForSelector, _IOHIDManagerClose, _IOHIDManagerCopyDevices, + _IOHIDManagerCreate, _IOHIDManagerGetProperty, _IOHIDManagerGetTypeID, + _IOHIDManagerOpen, _IOHIDManagerRegisterDeviceMatchingCallback, + _IOHIDManagerRegisterDeviceRemovalCallback, _IOHIDManagerRegisterInputReportCallback, + _IOHIDManagerRegisterInputValueCallback, _IOHIDManagerSaveToPropertyDomain, + _IOHIDManagerScheduleWithRunLoop, _IOHIDManagerSetDeviceMatching, + _IOHIDManagerSetDeviceMatchingMultiple, _IOHIDManagerSetInputValueMatching, + _IOHIDManagerSetInputValueMatchingMultiple, _IOHIDManagerSetProperty, + _IOHIDManagerUnscheduleFromRunLoop, _IOHIDNotificationCreate, + _IOHIDNotificationGetClientCallback, _IOHIDNotificationGetClientRefcon, + _IOHIDNotificationGetClientTarget, _IOHIDNotificationGetOwnerCallback, + _IOHIDNotificationGetOwnerRefcon, _IOHIDNotificationGetOwnerTarget, + _IOHIDNotificationGetTypeID, _IOHIDPostEvent, _IOHIDQueueAddElement, + _IOHIDQueueContainsElement, _IOHIDQueueCopyNextValue, + _IOHIDQueueCopyNextValueWithTimeout, _IOHIDQueueCreate, + _IOHIDQueueGetDepth, _IOHIDQueueGetDevice, _IOHIDQueueGetTypeID, + _IOHIDQueueRegisterValueAvailableCallback, _IOHIDQueueRemoveElement, + _IOHIDQueueScheduleWithRunLoop, _IOHIDQueueSetDepth, + _IOHIDQueueStart, _IOHIDQueueStop, _IOHIDQueueUnscheduleFromRunLoop, + _IOHIDRegisterVirtualDisplay, _IOHIDServiceClientConformsTo, + _IOHIDServiceClientCopyEvent, _IOHIDServiceClientCopyProperty, + _IOHIDServiceClientGetRegistryID, _IOHIDServiceClientGetTypeID, + _IOHIDServiceClientRegisterRemovalBlock, _IOHIDServiceClientRegisterRemovalCallback, + _IOHIDServiceClientSetElementValue, _IOHIDServiceClientSetProperty, + _IOHIDServiceConformsTo, _IOHIDServiceConnectionCacheContainsKey, + _IOHIDServiceConnectionCacheCopyValueForKey, _IOHIDServiceConnectionCacheCreate, + _IOHIDServiceConnectionCacheGetReportDeadline, _IOHIDServiceConnectionCacheGetTypeID, + _IOHIDServiceConnectionCacheGetUnresponsiveness, + _IOHIDServiceConnectionCacheSetReportDeadline, _IOHIDServiceConnectionCacheSetUnresponsiveness, + _IOHIDServiceConnectionCacheSetValueForKey, _IOHIDServiceCopyEvent, + _IOHIDServiceCopyProperty, _IOHIDServiceCreatePropertyChangedNotification, + _IOHIDServiceCreateRemovalNotification, _IOHIDServiceFilterClose, + _IOHIDServiceFilterCopyPropertyForClient, _IOHIDServiceFilterCreate, + _IOHIDServiceFilterFilterCopyEvent, _IOHIDServiceFilterFilterEvent, + _IOHIDServiceFilterGetType, _IOHIDServiceFilterGetTypeID, + _IOHIDServiceFilterMatch, _IOHIDServiceFilterOpen, + _IOHIDServiceFilterSchedule, _IOHIDServiceFilterSetEventCallback, + _IOHIDServiceFilterSetOutputEvent, _IOHIDServiceFilterSetPropertyForClient, + _IOHIDServiceFilterUnschedule, _IOHIDServiceGetProperty, + _IOHIDServiceGetRegistryID, _IOHIDServiceGetTypeID, + _IOHIDServiceMatchPropertyTable, _IOHIDServiceSetElementValue, + _IOHIDServiceSetOutputEvent, _IOHIDServiceSetProperty, + _IOHIDSessionAddService, _IOHIDSessionClose, _IOHIDSessionCopyEvent, + _IOHIDSessionCreate, _IOHIDSessionFilterClose, _IOHIDSessionFilterCopyEvent, + _IOHIDSessionFilterCreate, _IOHIDSessionFilterFilterCopyEvent, + _IOHIDSessionFilterFilterEvent, _IOHIDSessionFilterGetPropertyForClient, + _IOHIDSessionFilterGetType, _IOHIDSessionFilterGetTypeID, + _IOHIDSessionFilterOpen, _IOHIDSessionFilterRegisterService, + _IOHIDSessionFilterScheduleWithDispatchQueue, _IOHIDSessionFilterSetPropertyForClient, + _IOHIDSessionFilterUnregisterService, _IOHIDSessionFilterUnscheduleFromDispatchQueue, + _IOHIDSessionGetProperty, _IOHIDSessionGetTypeID, + _IOHIDSessionOpen, _IOHIDSessionRemoveService, _IOHIDSessionSetProperty, + _IOHIDSetAccelerationWithKey, _IOHIDSetCFTypeParameter, + _IOHIDSetCursorBounds, _IOHIDSetCursorEnable, _IOHIDSetEventsEnable, + _IOHIDSetFixedMouseLocation, _IOHIDSetModifierLockState, + _IOHIDSetMouseAcceleration, _IOHIDSetMouseButtonMode, + _IOHIDSetMouseLocation, _IOHIDSetOnScreenCursorBounds, + _IOHIDSetParameter, _IOHIDSetScrollAcceleration, + _IOHIDSetStateForSelector, _IOHIDSetVirtualDisplayBounds, + _IOHIDTransactionAddElement, _IOHIDTransactionClear, + _IOHIDTransactionCommit, _IOHIDTransactionCommitWithCallback, + _IOHIDTransactionContainsElement, _IOHIDTransactionCreate, + _IOHIDTransactionGetDevice, _IOHIDTransactionGetDirection, + _IOHIDTransactionGetTypeID, _IOHIDTransactionGetValue, + _IOHIDTransactionRemoveElement, _IOHIDTransactionScheduleWithRunLoop, + _IOHIDTransactionSetDirection, _IOHIDTransactionSetValue, + _IOHIDTransactionUnscheduleFromRunLoop, _IOHIDUnregisterVirtualDisplay, + _IOHIDUserDeviceCreate, _IOHIDUserDeviceCreateWithOptions, + _IOHIDUserDeviceGetTypeID, _IOHIDUserDeviceHandleReport, + _IOHIDUserDeviceHandleReportAsync, _IOHIDUserDeviceHandleReportAsyncWithTimeStamp, + _IOHIDUserDeviceHandleReportWithTimeStamp, _IOHIDUserDeviceRegisterGetReportCallback, + _IOHIDUserDeviceRegisterGetReportWithReturnLengthCallback, + _IOHIDUserDeviceRegisterSetReportCallback, _IOHIDUserDeviceScheduleWithDispatchQueue, + _IOHIDUserDeviceScheduleWithRunLoop, _IOHIDUserDeviceUnscheduleFromDispatchQueue, + _IOHIDUserDeviceUnscheduleFromRunLoop, _IOHIDValueCreateWithBytes, + _IOHIDValueCreateWithBytesNoCopy, _IOHIDValueCreateWithIntegerValue, + _IOHIDValueGetBytePtr, _IOHIDValueGetElement, _IOHIDValueGetIntegerValue, + _IOHIDValueGetLength, _IOHIDValueGetScaledValue, + _IOHIDValueGetTimeStamp, _IOHIDValueGetTypeID, _IOInitContainerClasses, + _IOIteratorIsValid, _IOIteratorNext, _IOIteratorReset, + _IOKitGetBusyState, _IOKitWaitQuiet, _IOMIGMachPortCacheAdd, + _IOMIGMachPortCacheCopy, _IOMIGMachPortCacheRemove, + _IOMIGMachPortCreate, _IOMIGMachPortGetPort, _IOMIGMachPortGetTypeID, + _IOMIGMachPortRegisterDemuxCallback, _IOMIGMachPortRegisterTerminationCallback, + _IOMIGMachPortScheduleWithDispatchQueue, _IOMIGMachPortScheduleWithRunLoop, + _IOMIGMachPortUnscheduleFromDispatchQueue, _IOMIGMachPortUnscheduleFromRunLoop, + _IOMasterPort, _IONetworkClose, _IONetworkGetDataCapacity, + _IONetworkGetDataHandle, _IONetworkGetPacketFiltersMask, + _IONetworkOpen, _IONetworkReadData, _IONetworkResetData, + _IONetworkSetPacketFiltersMask, _IONetworkWriteData, + _IONotificationPortCreate, _IONotificationPortDestroy, + _IONotificationPortGetMachPort, _IONotificationPortGetRunLoopSource, + _IONotificationPortSetDispatchQueue, _IOObjectConformsTo, + _IOObjectCopyBundleIdentifierForClass, _IOObjectCopyClass, + _IOObjectCopySuperclassForClass, _IOObjectGetClass, + _IOObjectGetKernelRetainCount, _IOObjectGetRetainCount, + _IOObjectGetUserRetainCount, _IOObjectIsEqualTo, + _IOObjectRelease, _IOObjectRetain, _IOOpenConnection, + _IOOpenFirmwarePathMatching, _IOPMActivateSystemPowerSettings, + _IOPMAllowsBackgroundTask, _IOPMAllowsPushServiceTask, + _IOPMAssertionCopyProperties, _IOPMAssertionCreate, + _IOPMAssertionCreateWithDescription, _IOPMAssertionCreateWithName, + _IOPMAssertionCreateWithProperties, _IOPMAssertionDeclareNotificationEvent, + _IOPMAssertionDeclareSystemActivity, _IOPMAssertionDeclareUserActivity, + _IOPMAssertionNotify, _IOPMAssertionRelease, _IOPMAssertionRetain, + _IOPMAssertionSetBTCollection, _IOPMAssertionSetProperty, + _IOPMAssertionSetTimeout, _IOPMCancelAllRepeatingPowerEvents, + _IOPMCancelAllScheduledPowerEvents, _IOPMCancelScheduledPowerEvent, + _IOPMChangeSystemActivityAssertionBehavior, _IOPMClaimSystemWakeEvent, + _IOPMConnectionAcknowledgeEvent, _IOPMConnectionAcknowledgeEventWithOptions, + _IOPMConnectionCreate, _IOPMConnectionGetSystemCapabilities, + _IOPMConnectionRelease, _IOPMConnectionScheduleWithRunLoop, + _IOPMConnectionSetDispatchQueue, _IOPMConnectionSetNotification, + _IOPMConnectionUnscheduleFromRunLoop, _IOPMCopyActivePMPreferences, + _IOPMCopyActivePowerProfiles, _IOPMCopyAssertionActivityAggregate, + _IOPMCopyAssertionActivityAggregateWithAllocator, + _IOPMCopyAssertionActivityLog, _IOPMCopyAssertionActivityLogWithAllocator, + _IOPMCopyAssertionActivityUpdate, _IOPMCopyAssertionActivityUpdateWithAllocator, + _IOPMCopyAssertionsByProcess, _IOPMCopyAssertionsByProcessWithAllocator, + _IOPMCopyAssertionsByType, _IOPMCopyAssertionsStatus, + _IOPMCopyBatteryInfo, _IOPMCopyCPUPowerStatus, _IOPMCopyConnectionStatus, + _IOPMCopyCustomPMPreferences, _IOPMCopyHIDPostEventHistory, + _IOPMCopyPMPreferences, _IOPMCopyPowerHistory, _IOPMCopyPowerHistoryDetailed, + _IOPMCopyPowerProfiles, _IOPMCopyPowerStateInfo, + _IOPMCopyRepeatingPowerEvents, _IOPMCopyScheduledPowerEvents, + _IOPMCopySleepPreventersList, _IOPMCopySleepWakeFailure, + _IOPMCopySystemPowerSettings, _IOPMCopyUPSShutdownLevels, + _IOPMCopyUnabridgedActivePMPreferences, _IOPMCopyUserActivityLevelDescription, + _IOPMCtlAssertionType, _IOPMDebugTracePoint, _IOPMDeclareNetworkClientActivity, + _IOPMFeatureIsAvailable, _IOPMFeatureIsAvailableWithSupportedTable, + _IOPMFindPowerManagement, _IOPMGetActivePushConnectionState, + _IOPMGetAggressiveness, _IOPMGetCapabilitiesDescription, + _IOPMGetDarkWakeThermalEmergencyCount, _IOPMGetLastWakeTime, + _IOPMGetPerformanceWarningLevel, _IOPMGetSleepServicesActive, + _IOPMGetThermalWarningLevel, _IOPMGetUUID, _IOPMGetUserActivityLevel, + _IOPMGetValueInt, _IOPMIsADarkWake, _IOPMIsASilentWake, + _IOPMIsASleep, _IOPMIsAUserWake, _IOPMOverrideDefaultPMPreferences, + _IOPMPerformBlockWithAssertion, _IOPMPrefsNotificationCreateRunLoopSource, + _IOPMRequestSysWake, _IOPMRevertPMPreferences, _IOPMSchedulePowerEvent, + _IOPMScheduleRepeatingPowerEvent, _IOPMScheduleUserActiveChangedNotification, + _IOPMScheduleUserActivityLevelNotification, _IOPMSetActivePowerProfiles, + _IOPMSetActivePushConnectionState, _IOPMSetAggressiveness, + _IOPMSetAssertionActivityAggregate, _IOPMSetAssertionActivityLog, + _IOPMSetBTWakeInterval, _IOPMSetCustomPMPreferences, + _IOPMSetDWLingerInterval, _IOPMSetDebugFlags, _IOPMSetPMPreferences, + _IOPMSetReservePowerMode, _IOPMSetSleepServicesWakeTimeCap, + _IOPMSetSystemPowerSetting, _IOPMSetUPSShutdownLevels, + _IOPMSetValueInt, _IOPMSleepEnabled, _IOPMSleepSystem, + _IOPMSleepSystemWithOptions, _IOPMSleepWakeCopyUUID, + _IOPMSleepWakeSetUUID, _IOPMUnregisterNotification, + _IOPMUserDidChangeCallback, _IOPMUserIsActive, _IOPSAccCreateAttachNotification, + _IOPSAccCreateLimitedPowerNotification, _IOPSAccNotificationCreateRunLoopSource, + _IOPSCopyChargeLog, _IOPSCopyExternalPowerAdapterDetails, + _IOPSCopyInternalBatteriesArray, _IOPSCopyPowerSourcesByType, + _IOPSCopyPowerSourcesInfo, _IOPSCopyPowerSourcesList, + _IOPSCopyUPSArray, _IOPSCreateLimitedPowerNotification, + _IOPSCreatePowerSource, _IOPSDrawingUnlimitedPower, + _IOPSGetActiveBattery, _IOPSGetActiveUPS, _IOPSGetBatteryWarningLevel, + _IOPSGetPercentRemaining, _IOPSGetPowerSourceDescription, + _IOPSGetProvidingPowerSourceType, _IOPSGetSupportedPowerSources, + _IOPSGetTimeRemainingEstimate, _IOPSNotificationCreateRunLoopSource, + _IOPSPowerSourceSupported, _IOPSReleasePowerSource, + _IOPSRequestBatteryUpdate, _IOPSSetPowerSourceDetails, + _IORegisterApp, _IORegisterClient, _IORegisterForSystemPower, + _IORegistryCreateEnumerator, _IORegistryCreateIterator, + _IORegistryDisposeEnumerator, _IORegistryEntryCopyFromPath, + _IORegistryEntryCopyPath, _IORegistryEntryCreateCFProperties, + _IORegistryEntryCreateCFProperty, _IORegistryEntryCreateIterator, + _IORegistryEntryFromPath, _IORegistryEntryGetChildEntry, + _IORegistryEntryGetChildIterator, _IORegistryEntryGetLocationInPlane, + _IORegistryEntryGetName, _IORegistryEntryGetNameInPlane, + _IORegistryEntryGetParentEntry, _IORegistryEntryGetParentIterator, + _IORegistryEntryGetPath, _IORegistryEntryGetProperty, + _IORegistryEntryGetRegistryEntryID, _IORegistryEntryIDMatching, + _IORegistryEntryInPlane, _IORegistryEntrySearchCFProperty, + _IORegistryEntrySetCFProperties, _IORegistryEntrySetCFProperty, + _IORegistryEnumeratorNextConforming, _IORegistryEnumeratorReset, + _IORegistryGetRootEntry, _IORegistryIteratorEnterEntry, + _IORegistryIteratorExitEntry, _IOServiceAddInterestNotification, + _IOServiceAddMatchingNotification, _IOServiceAddNotification, + _IOServiceAuthorize, _IOServiceClose, _IOServiceGetBusyState, + _IOServiceGetBusyStateAndTime, _IOServiceGetMatchingService, + _IOServiceGetMatchingServices, _IOServiceGetState, + _IOServiceMatchPropertyTable, _IOServiceMatching, + _IOServiceNameMatching, _IOServiceOFPathToBSDName, + _IOServiceOpen, _IOServiceOpenAsFileDescriptor, + _IOServiceRequestProbe, _IOServiceWaitQuiet, _IOSetNotificationPort, + _IOURLCreateDataAndPropertiesFromResource, _IOURLCreatePropertyFromResource, + _IOUSBDevicDeviceDescriptionGetTypeID, _IOUSBDeviceControllerCreate, + _IOUSBDeviceControllerCreateDefaultDescription, + _IOUSBDeviceControllerCreateWithService, _IOUSBDeviceControllerForceOffBus, + _IOUSBDeviceControllerGetService, _IOUSBDeviceControllerGetTypeID, + _IOUSBDeviceControllerGoOffAndOnBus, _IOUSBDeviceControllerRegisterArrivalCallback, + _IOUSBDeviceControllerRemoveArrivalCallback, _IOUSBDeviceControllerSendCommand, + _IOUSBDeviceControllerSetDescription, _IOUSBDeviceControllerSetPreferredConfiguration, + _IOUSBDeviceDataCreate, _IOUSBDeviceDataGetBytePtr, + _IOUSBDeviceDataGetCapacity, _IOUSBDeviceDataGetMapToken, + _IOUSBDeviceDataGetTypeID, _IOUSBDeviceDescriptionAppendConfiguration, + _IOUSBDeviceDescriptionAppendConfigurationWithInterface, + _IOUSBDeviceDescriptionAppendConfigurationWithInterfaces, + _IOUSBDeviceDescriptionAppendConfigurationWithoutAttributes, + _IOUSBDeviceDescriptionAppendInterfaceToConfiguration, + _IOUSBDeviceDescriptionAppendInterfacesToConfiguration, + _IOUSBDeviceDescriptionCopyInterfaces, _IOUSBDeviceDescriptionCreate, + _IOUSBDeviceDescriptionCreateFromController, _IOUSBDeviceDescriptionCreateFromControllerWithType, + _IOUSBDeviceDescriptionCreateFromDefaults, _IOUSBDeviceDescriptionCreateFromDefaultsAndController, + _IOUSBDeviceDescriptionCreateWithConfigurationInterfaces, + _IOUSBDeviceDescriptionCreateWithType, _IOUSBDeviceDescriptionGetAllowOverride, + _IOUSBDeviceDescriptionGetClass, _IOUSBDeviceDescriptionGetManufacturerString, + _IOUSBDeviceDescriptionGetMatchingConfiguration, + _IOUSBDeviceDescriptionGetProductID, _IOUSBDeviceDescriptionGetProductString, + _IOUSBDeviceDescriptionGetProtocol, _IOUSBDeviceDescriptionGetSerialString, + _IOUSBDeviceDescriptionGetSubClass, _IOUSBDeviceDescriptionGetVendorID, + _IOUSBDeviceDescriptionGetVersion, _IOUSBDeviceDescriptionRemoveAllConfigurations, + _IOUSBDeviceDescriptionSetAllowOverride, _IOUSBDeviceDescriptionSetClass, + _IOUSBDeviceDescriptionSetProductID, _IOUSBDeviceDescriptionSetProtocol, + _IOUSBDeviceDescriptionSetSerialString, _IOUSBDeviceDescriptionSetSubClass, + _IOUSBDeviceDescriptionSetVendorID, _NXClickTime, + _NXCloseEventStatus, _NXEventSystemInfo, _NXGetClickSpace, + _NXGetKeyMapping, _NXKeyMappingLength, _NXKeyRepeatInterval, + _NXKeyRepeatThreshold, _NXOpenEventStatus, _NXResetKeyboard, + _NXResetMouse, _NXSetClickSpace, _NXSetClickTime, + _NXSetKeyMapping, _NXSetKeyRepeatInterval, _NXSetKeyRepeatThreshold, + _OSGetNotificationFromMessage, _OSKextAuthenticate, + _OSKextAuthenticateDependencies, _OSKextCopyAllDependencies, + _OSKextCopyAllRequestedIdentifiers, _OSKextCopyArchitectures, + _OSKextCopyContainerForPluginKext, _OSKextCopyDeclaredDependencies, + _OSKextCopyDependents, _OSKextCopyDiagnostics, _OSKextCopyExecutableForArchitecture, + _OSKextCopyIndirectDependencies, _OSKextCopyInfoDictionary, + _OSKextCopyKextsWithIdentifier, _OSKextCopyKextsWithIdentifiers, + _OSKextCopyLinkDependencies, _OSKextCopyLoadList, + _OSKextCopyLoadListForKexts, _OSKextCopyLoadedKextInfo, + _OSKextCopyPersonalitiesArray, _OSKextCopyPersonalitiesOfKexts, + _OSKextCopyPlugins, _OSKextCopyResource, _OSKextCopyUUIDForArchitecture, + _OSKextCreate, _OSKextCreateKextsFromMkextData, + _OSKextCreateKextsFromMkextFile, _OSKextCreateKextsFromURL, + _OSKextCreateKextsFromURLs, _OSKextCreateLoadedKextInfo, + _OSKextCreateMkext, _OSKextCreateWithIdentifier, + _OSKextDeclaresExecutable, _OSKextDependenciesAreLoadableInSafeBoot, + _OSKextDependsOnKext, _OSKextFilterRequiredKexts, + _OSKextFindLinkDependencies, _OSKextFlushDependencies, + _OSKextFlushDiagnostics, _OSKextFlushInfoDictionary, + _OSKextFlushLoadInfo, _OSKextGetActualSafeBoot, + _OSKextGetAllKexts, _OSKextGetArchitecture, _OSKextGetCompatibleKextWithIdentifier, + _OSKextGetCompatibleVersion, _OSKextGetIdentifier, + _OSKextGetKextWithIdentifier, _OSKextGetKextWithIdentifierAndVersion, + _OSKextGetKextWithURL, _OSKextGetLoadAddress, _OSKextGetLoadTag, + _OSKextGetLoadedKextWithIdentifier, _OSKextGetLogFilter, + _OSKextGetRecordsDiagnostics, _OSKextGetRunningKernelArchitecture, + _OSKextGetSimulatedSafeBoot, _OSKextGetSystemExtensionsFolderURLs, + _OSKextGetTypeID, _OSKextGetURL, _OSKextGetUsesCaches, + _OSKextGetValueForInfoDictionaryKey, _OSKextGetVersion, + _OSKextHasLogOrDebugFlags, _OSKextIsAuthentic, _OSKextIsCompatibleWithVersion, + _OSKextIsFromMkext, _OSKextIsInterface, _OSKextIsKernelComponent, + _OSKextIsLibrary, _OSKextIsLoadable, _OSKextIsLoadableInSafeBoot, + _OSKextIsLoaded, _OSKextIsLoggingEnabled, _OSKextIsPlugin, + _OSKextIsStarted, _OSKextIsValid, _OSKextLoad, _OSKextLoadWithOptions, + _OSKextLog, _OSKextLogCFString, _OSKextLogDependencyGraph, + _OSKextLogDiagnostics, _OSKextMatchesRequiredFlags, + _OSKextOtherVersionIsLoaded, _OSKextParseVersionCFString, + _OSKextParseVersionString, _OSKextReadLoadedKextInfo, + _OSKextRemoveKextPersonalitiesFromKernel, _OSKextRemovePersonalitiesForIdentifierFromKernel, + _OSKextResolveDependencies, _OSKextSendKextPersonalitiesToKernel, + _OSKextSendPersonalitiesOfKextsToKernel, _OSKextSendPersonalitiesToKernel, + _OSKextSetArchitecture, _OSKextSetLoadAddress, _OSKextSetLogFilter, + _OSKextSetLogOutputFunction, _OSKextSetLoggingEnabled, + _OSKextSetRecordsDiagnostics, _OSKextSetSimulatedSafeBoot, + _OSKextSetUsesCaches, _OSKextStart, _OSKextStop, + _OSKextSupportsArchitecture, _OSKextUnload, _OSKextUnloadKextWithIdentifier, + _OSKextVLog, _OSKextVLogCFString, _OSKextValidate, + _OSKextValidateDependencies, _OSKextVersionGetString, + __CFURLCopyAbsolutePath, __IOAVStringAppendIndendationAndFormat, + __IODataQueueEnqueueWithReadCallback, __IODispatchCalloutWithDispatch, + __IOHIDCallbackApplier, __IOHIDCopyServiceIDs, __IOHIDCreateBinaryData, + __IOHIDDeviceGetIOCFPlugInInterface, __IOHIDElementCreateWithElement, + __IOHIDElementCreateWithParentAndData, __IOHIDElementGetCalibrationInfo, + __IOHIDElementGetFlags, __IOHIDElementGetLength, + __IOHIDElementGetValue, __IOHIDElementSetDevice, + __IOHIDElementSetDeviceInterface, __IOHIDElementSetValue, + __IOHIDEventCopyCFTypeContext, __IOHIDEventGetContext, + __IOHIDEventSetCFTypeContext, __IOHIDEventSetContext, + __IOHIDEventSystemAddConnection, __IOHIDEventSystemAddService, + __IOHIDEventSystemAddServiceForConnection, __IOHIDEventSystemClientCopyClientRecords, + __IOHIDEventSystemClientCopyEventForService, __IOHIDEventSystemClientCopyPropertyForService, + __IOHIDEventSystemClientCopyServiceRecords, __IOHIDEventSystemClientDispatchEventFilter, + __IOHIDEventSystemClientDispatchPropertiesChanged, + __IOHIDEventSystemClientRegisterClientRecordsChangedBlock, + __IOHIDEventSystemClientRegisterClientRecordsChangedCallback, + __IOHIDEventSystemClientRegisterServiceRecordsChangedBlock, + __IOHIDEventSystemClientRegisterServiceRecordsChangedCallback, + __IOHIDEventSystemClientServiceConformsTo, __IOHIDEventSystemClientSetElementValueForService, + __IOHIDEventSystemClientSetPropertyForService, __IOHIDEventSystemClientUnregisterClientRecordsChangedBlock, + __IOHIDEventSystemClientUnregisterClientRecordsChangedCallback, + __IOHIDEventSystemClientUnregisterServiceRecordsChangedBlock, + __IOHIDEventSystemClientUnregisterServiceRecordsChangedCallback, + __IOHIDEventSystemConnectionAddNotification, __IOHIDEventSystemConnectionAddServices, + __IOHIDEventSystemConnectionContainsEntitlement, + __IOHIDEventSystemConnectionContainsService, __IOHIDEventSystemConnectionCopyQueue, + __IOHIDEventSystemConnectionCopyRecord, __IOHIDEventSystemConnectionCopyServices, + __IOHIDEventSystemConnectionCreate, __IOHIDEventSystemConnectionEventFilterCompare, + __IOHIDEventSystemConnectionFilterEvent, __IOHIDEventSystemConnectionGetEventFilterPriority, + __IOHIDEventSystemConnectionGetExecutablePath, __IOHIDEventSystemConnectionGetPID, + __IOHIDEventSystemConnectionGetPort, __IOHIDEventSystemConnectionGetReplyPort, + __IOHIDEventSystemConnectionGetSystem, __IOHIDEventSystemConnectionPropertyChanged, + __IOHIDEventSystemConnectionQueueStart, __IOHIDEventSystemConnectionQueueStop, + __IOHIDEventSystemConnectionRecordClientChanged, + __IOHIDEventSystemConnectionRecordServiceChanged, + __IOHIDEventSystemConnectionRegisterDemuxCallback, + __IOHIDEventSystemConnectionRegisterEventFilter, + __IOHIDEventSystemConnectionRegisterPropertyChangedNotification, + __IOHIDEventSystemConnectionRegisterRecordClientChanged, + __IOHIDEventSystemConnectionRegisterRecordServiceChanged, + __IOHIDEventSystemConnectionRegisterTerminationCallback, + __IOHIDEventSystemConnectionRemoveAllServices, __IOHIDEventSystemConnectionRemoveNotification, + __IOHIDEventSystemConnectionRemoveService, __IOHIDEventSystemConnectionScheduleAsync, + __IOHIDEventSystemConnectionSetQueue, __IOHIDEventSystemConnectionUnregisterEventFilter, + __IOHIDEventSystemConnectionUnregisterPropertyChangedNotification, + __IOHIDEventSystemConnectionUnregisterRecordClientChanged, + __IOHIDEventSystemConnectionUnregisterRecordServiceChanged, + __IOHIDEventSystemConnectionUnscheduleAsync, __IOHIDEventSystemCopyRecord, + __IOHIDEventSystemDispatchEvent, __IOHIDEventSystemGetPropertyForConnection, + __IOHIDEventSystemPropertyChanged, __IOHIDEventSystemRegisterEventFilter, + __IOHIDEventSystemRegisterRecordClientChanged, __IOHIDEventSystemRegisterRecordServiceChanged, + __IOHIDEventSystemRemoveConnection, __IOHIDEventSystemRemoveService, + __IOHIDEventSystemRemoveServicesForConnection, __IOHIDEventSystemSetPropertyForConnection, + __IOHIDEventSystemUnregisterEventFilter, __IOHIDEventSystemUnregisterRecordClientChanged, + __IOHIDEventSystemUnregisterRecordServiceChanged, + __IOHIDHasEntitlement, __IOHIDLoadBundles, __IOHIDLog, + __IOHIDQueueCopyElements, __IOHIDSerialize, __IOHIDServiceAddConnection, + __IOHIDServiceClientCreate, __IOHIDServiceClientDispatchServiceRemoval, + __IOHIDServiceClientRefresh, __IOHIDServiceClose, + __IOHIDServiceContainsReportInterval, __IOHIDServiceContainsReportIntervalForClient, + __IOHIDServiceCopyConnections, __IOHIDServiceCopyDebugDescriptionForClient, + __IOHIDServiceCopyDispatchQueue, __IOHIDServiceCopyPropertyForClient, + __IOHIDServiceCopyRecordForClient, __IOHIDServiceCreate, + __IOHIDServiceCreateVirtual, __IOHIDServiceGetEventDeadlineForClient, + __IOHIDServiceGetOwner, __IOHIDServiceGetReportInterval, + __IOHIDServiceGetReportIntervalForClient, __IOHIDServiceIsInactive, + __IOHIDServiceOpen, __IOHIDServiceRemoveConnection, + __IOHIDServiceRemovePropertiesForClient, __IOHIDServiceScheduleAsync, + __IOHIDServiceSetBatchIntervalForClient, __IOHIDServiceSetEventCallback, + __IOHIDServiceSetEventDeadlineForClient, __IOHIDServiceSetPropertyForClient, + __IOHIDServiceSetReportIntervalForClient, __IOHIDServiceUnscheduleAsync, + __IOHIDSessionDispatchEvent, __IOHIDSessionGetPropertyForClient, + __IOHIDSessionSetPropertyForClient, __IOHIDStringAppendIndendationAndFormat, + __IOHIDUnserializeAndVMDealloc, __IOHIDUnserializeAndVMDeallocWithTypeID, + __IOHIDValueCopyToElementValuePtr, __IOHIDValueCreateWithElementValuePtr, + __IOHIDValueCreateWithStruct, __IOObjectCFRelease, + __IOObjectCFRetain, __IOObjectConformsTo, __IOObjectCopyClass, + __IOObjectGetClass, __IOReadBytesFromFile, __IOServiceGetAuthorizationID, + __IOServiceSetAuthorizationID, __IOUSBDeviceDescriptionGetInfo, + __IOWriteBytesToFile, __OSKextCopyKernelRequests, + __OSKextCreateFolderForCacheURL, __OSKextReadCache, + __OSKextReadFromIdentifierCacheForFolder, __OSKextSendResource, + __OSKextSetStrictRecordingByLastOpened, __OSKextWriteCache, + __OSKextWriteIdentifierCacheForKextsInDirectory, + ___CachedPropertiesRefreshApplierFunction, ___ConnectionFunctionPickBatchInterval, + ___GDBIOHIDEventSystemDump, ___IOHIDApplyPropertiesToDeviceFromDictionary, + ___IOHIDApplyPropertyToDeviceSet, ___IOHIDDeviceGetRootKey, + ___IOHIDDeviceGetUUIDKey, ___IOHIDDeviceGetUUIDString, + ___IOHIDDeviceLoadProperties, ___IOHIDDeviceSaveProperties, + ___IOHIDElementGetRootKey, ___IOHIDElementLoadProperties, + ___IOHIDElementRegister, ___IOHIDElementSaveProperties, + ___IOHIDEventSystemClientRefresh, ___IOHIDEventSystemClientRefreshServiceCallback, + ___IOHIDEventSystemClientServiceReplaceCallback, + ___IOHIDEventSystem_debug, ___IOHIDLoadElementSet, + ___IOHIDManagerGetRootKey, ___IOHIDManagerLoadProperties, + ___IOHIDManagerRegister, ___IOHIDManagerSaveProperties, + ___IOHIDNotificationRegister, ___IOHIDPropertyLoadDictionaryFromKey, + ___IOHIDPropertyLoadFromKeyWithSpecialKeys, ___IOHIDPropertySaveToKeyWithSpecialKeys, + ___IOHIDPropertySaveWithContext, ___IOHIDQueueRegister, + ___IOHIDSaveDeviceSet, ___IOHIDSaveElementSet, ___IOHIDServicePickBatchInterval, + ___IOHIDSession, ___IOHIDSessionRef, ___IOHIDTransactionRegister, + ___IOHIDValueRegister, ___IOUSBDeviceDescriptionRegister, + ___OSKextBundleIDCompare, ___OSKextCacheNeedsUpdate, + ___OSKextCheckURL, ___OSKextClearHasAllDependenciesOnKext, + ___OSKextCompareIdentifiers, ___OSKextCopyExecutableRelativePath, + ___OSKextCreateCacheFileURL, ___OSKextCreateCompositeKey, + ___OSKextCreateFromIdentifierCacheDict, ___OSKextCreateIdentifierCacheDict, + ___OSKextCreateKextRequest, ___OSKextDeallocateMmapBuffer, + ___OSKextGetBleedthroughFlag, ___OSKextLogDependencyGraphApplierFunction, + ___OSKextLogKernelMessages, ___OSKextMapExecutable, + ___OSKextProcessKextRequestResults, ___OSKextReadRegistryNumberProperty, + ___OSKextRealize, ___OSKextRealizeKextsWithIdentifier, + ___OSKextRemoveIdentifierCacheForKext, ___OSKextRemovePersonalities, + ___OSKextSendKextRequest, ___OSKextSetLoadAddress, + ___OSKextStatURL, ___OSKextStatURLsOrURL, ___OSKextURLIsSystemFolder, + ___OSKextUUIDCallback, ___OSKextUnload, ___SetNumPropertyForService, + ___absPathOnVolume, ___kOSKextDiagnosticsFlagAllImplemented, + ___sOSKextDefaultLogFunction, ___sOSKextLogOutputFunction, + ___uuid_callback, __io_hideventsystem_clear_service_cache, + __io_hideventsystem_copy_client_records, __io_hideventsystem_copy_event_for_service, + __io_hideventsystem_copy_matching_services, __io_hideventsystem_copy_property, + __io_hideventsystem_copy_property_for_service, __io_hideventsystem_copy_service_records, + __io_hideventsystem_dispatch_event, __io_hideventsystem_open, + __io_hideventsystem_queue_create, __io_hideventsystem_queue_start, + __io_hideventsystem_queue_stop, __io_hideventsystem_register_event_filter, + __io_hideventsystem_register_property_changed_notification, + __io_hideventsystem_register_record_client_changed_notification, + __io_hideventsystem_register_record_service_changed_notification, + __io_hideventsystem_release_notification, __io_hideventsystem_service_conforms_to, + __io_hideventsystem_set_element_value_for_service, + __io_hideventsystem_set_properties, __io_hideventsystem_set_properties_for_service, + __io_hideventsystem_unregister_event_filter, __io_hideventsystem_unregister_property_changed_notification, + __io_hideventsystem_unregister_record_client_changed_notification, + __io_hideventsystem_unregister_record_service_changed_notification, + __io_kSCCompAnyRegex, __io_kSCDynamicStoreDomainState, + __iohideventsystem_client_dispatch_client_records_changed, + __iohideventsystem_client_dispatch_event_filter, + __iohideventsystem_client_dispatch_notification_results, + __iohideventsystem_client_dispatch_properties_changed, + __iohideventsystem_client_dispatch_service_records_changed, + __iohideventsystem_client_dispatch_service_removal, + __iohideventsystem_client_subsystem, __iohideventsystem_subsystem, + __isArray, __isDictionary, __isString, __pm_connect, + __pm_disconnect, _createCFStringForData, _createCFStringForPlist_new, + _createUTF8CStringForCFString, _defaultSettings, + _ev_try_lock, _ev_unlock, _fat_iterator_close, _fat_iterator_file_end, + _fat_iterator_file_start, _fat_iterator_find_arch, + _fat_iterator_find_fat_arch, _fat_iterator_find_host_arch, + _fat_iterator_for_data, _fat_iterator_is_iterable, + _fat_iterator_next_arch, _fat_iterator_num_arches, + _fat_iterator_open, _fat_iterator_reset, _gIOCFPlugInInterfaceID, + _gIOKitLibSerializeOptions, _gIOKitLibServerVersion, + _getEffectivePageSize, _hid_dispatch_pthread_root_queue_create, + _hid_dispatch_queue_create, _hid_dispatch_queue_release, + _hid_pthread_attr_init, _io_hideventsystem_clear_service_cache, + _io_hideventsystem_copy_client_records, _io_hideventsystem_copy_event_for_service, + _io_hideventsystem_copy_matching_services, _io_hideventsystem_copy_property, + _io_hideventsystem_copy_property_for_service, _io_hideventsystem_copy_service_records, + _io_hideventsystem_dispatch_event, _io_hideventsystem_open, + _io_hideventsystem_queue_create, _io_hideventsystem_queue_start, + _io_hideventsystem_queue_stop, _io_hideventsystem_register_event_filter, + _io_hideventsystem_register_property_changed_notification, + _io_hideventsystem_register_record_client_changed_notification, + _io_hideventsystem_register_record_service_changed_notification, + _io_hideventsystem_release_notification, _io_hideventsystem_service_conforms_to, + _io_hideventsystem_set_element_value_for_service, + _io_hideventsystem_set_properties, _io_hideventsystem_set_properties_for_service, + _io_hideventsystem_unregister_event_filter, _io_hideventsystem_unregister_property_changed_notification, + _io_hideventsystem_unregister_record_client_changed_notification, + _io_hideventsystem_unregister_record_service_changed_notification, + _io_pm_assertion_activity_aggregate, _io_pm_assertion_activity_log, + _io_pm_assertion_copy_details, _io_pm_assertion_create, + _io_pm_assertion_notify, _io_pm_assertion_retain_release, + _io_pm_assertion_set_properties, _io_pm_cancel_repeat_events, + _io_pm_change_sa_assertion_behavior, _io_pm_connection_acknowledge_event, + _io_pm_connection_copy_status, _io_pm_connection_create, + _io_pm_connection_release, _io_pm_connection_schedule_notification, + _io_pm_ctl_assertion_type, _io_pm_declare_network_client_active, + _io_pm_declare_system_active, _io_pm_declare_user_active, + _io_pm_force_active_settings, _io_pm_get_capability_bits, + _io_pm_get_uuid, _io_pm_get_value_int, _io_pm_hid_event_copy_history, + _io_pm_hid_event_report_activity, _io_pm_last_wake_time, + _io_pm_schedule_power_event, _io_pm_schedule_repeat_event, + _io_pm_set_active_profile, _io_pm_set_bt_wake_interval, + _io_pm_set_debug_flags, _io_pm_set_dw_linger_interval, + _io_pm_set_sleepservice_wake_time_cap, _io_pm_set_value_int, + _io_ps_copy_chargelog, _io_ps_copy_powersources_info, + _io_ps_new_pspowersource, _io_ps_release_pspowersource, + _io_ps_update_pspowersource, _iohideventsystem_client_dispatch_client_records_changed, + _iohideventsystem_client_dispatch_event_filter, + _iohideventsystem_client_dispatch_notification_results, + _iohideventsystem_client_dispatch_properties_changed, + _iohideventsystem_client_dispatch_service_records_changed, + _iohideventsystem_client_dispatch_service_removal, + _iohideventsystem_client_server, _iohideventsystem_client_server_routine, + _iohideventsystem_server, _iohideventsystem_server_routine, + _iokit_user_client_trap, _isCrossLinking, _kIOEthernetHardwareAddress, + _kIOHIDEventSystemConnectionDispatchFilterWaitTimeoutMS, + _kIOHIDFilterPluginArrayCallBacks, _kIOHIDServerConnectionRootQueue, + _kIOHIDServiceEnumerationRootQueue, _kIOHIDServiceInterruptRootQueue, + _kIOMasterPortDefault, _kIOUserEthernetInterfaceMergeProperties, + _kIOUserEthernetInterfaceRole, _kOSKextDependencyCircularReference, + _kOSKextDependencyCompatibleVersionUndeclared, _kOSKextDependencyInauthentic, + _kOSKextDependencyIndirectDependencyUnresolvable, + _kOSKextDependencyIneligibleInSafeBoot, _kOSKextDependencyInvalid, + _kOSKextDependencyLoadedCompatibleVersionUndeclared, + _kOSKextDependencyLoadedIsIncompatible, _kOSKextDependencyMultipleVersionsDetected, + _kOSKextDependencyNoCompatibleVersion, _kOSKextDependencyRawAndComponentKernel, + _kOSKextDependencyUnavailable, _kOSKextDiagnosticBadPropertyListXMLKey, + _kOSKextDiagnosticBadSystemPropertyKey, _kOSKextDiagnosticBundleIdentifierMismatchKey, + _kOSKextDiagnosticBundleVersionMismatchKey, _kOSKextDiagnosticCodelessWithLibrariesKey, + _kOSKextDiagnosticCompatibleVersionLaterThanVersionKey, + _kOSKextDiagnosticDeclaresBothKernelAndKPIDependenciesKey, + _kOSKextDiagnosticDeclaresNoKPIsWarningKey, _kOSKextDiagnosticDeclaresNonKPIDependenciesKey, + _kOSKextDiagnosticDeprecatedPropertyKey, _kOSKextDiagnosticExecutableArchNotFoundKey, + _kOSKextDiagnosticExecutableBadKey, _kOSKextDiagnosticExecutableMissingKey, + _kOSKextDiagnosticFileAccessKey, _kOSKextDiagnosticFileNotFoundKey, + _kOSKextDiagnosticIdentifierOrVersionTooLongKey, + _kOSKextDiagnosticIneligibleInSafeBoot, _kOSKextDiagnosticKernelComponentNotInterfaceKey, + _kOSKextDiagnosticMissingPropertyKey, _kOSKextDiagnosticNoExplicitKernelDependencyKey, + _kOSKextDiagnosticNoFileKey, _kOSKextDiagnosticNonAppleKextDeclaresPrivateKPIDependencyKey, + _kOSKextDiagnosticNonuniqueIOResourcesMatchKey, + _kOSKextDiagnosticNotABundleKey, _kOSKextDiagnosticNotSignedKey, + _kOSKextDiagnosticOwnerPermissionKey, _kOSKextDiagnosticPersonalityHasDifferentBundleIdentifierKey, + _kOSKextDiagnosticPersonalityHasNoBundleIdentifierKey, + _kOSKextDiagnosticPersonalityNamesKextWithNoExecutableKey, + _kOSKextDiagnosticPersonalityNamesNonloadableKextKey, + _kOSKextDiagnosticPersonalityNamesUnknownKextKey, + _kOSKextDiagnosticPropertyIsIllegalTypeKey, _kOSKextDiagnosticPropertyIsIllegalValueKey, + _kOSKextDiagnosticRawKernelDependency, _kOSKextDiagnosticSharedExecutableAndExecutableKey, + _kOSKextDiagnosticSharedExecutableKextMissingKey, + _kOSKextDiagnosticStatFailureKey, _kOSKextDiagnosticSymlinkKey, + _kOSKextDiagnosticTypeWarningKey, _kOSKextDiagnosticURLConversionKey, + _kOSKextDiagnosticsAuthenticationKey, _kOSKextDiagnosticsBootLevelKey, + _kOSKextDiagnosticsDependenciesKey, _kOSKextDiagnosticsDependencyNotOSBundleRequired, + _kOSKextDiagnosticsInterfaceDependencyCount, _kOSKextDiagnosticsValidationKey, + _kOSKextDiagnosticsWarningsKey, _kOSKextLoadNotification, + _kOSKextUnloadNotification, _macho_find_dysymtab, + _macho_find_section_numbered, _macho_find_source_version, + _macho_find_symbol, _macho_find_symtab, _macho_find_uuid, + _macho_get_section_by_name, _macho_get_section_by_name_64, + _macho_get_segment_by_name, _macho_get_segment_by_name_64, + _macho_remove_linkedit, _macho_scan_load_commands, + _macho_swap, _macho_trim_linkedit, _macho_unswap, + _previouslySerialized, _printPList_new, _recordObjectInIDRefDictionary, + _roundPageCrossSafe, _roundPageCrossSafeFixedWidth, + _setCrossLinkPageSize, _showPList_new ] +... diff --git a/IOKit.framework/Versions/Current b/IOKit.framework/Versions/Current new file mode 120000 index 0000000..8c7e5a6 --- /dev/null +++ b/IOKit.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/PTFakeTouch.xcodeproj/project.pbxproj b/PTFakeTouch.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1c848d6 --- /dev/null +++ b/PTFakeTouch.xcodeproj/project.pbxproj @@ -0,0 +1,489 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 15BBDF041D61AD5B0098330F /* PTFakeTouch.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BBDEF91D61AD5B0098330F /* PTFakeTouch.framework */; }; + 15BBDF091D61AD5B0098330F /* PTFakeTouchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 15BBDF081D61AD5B0098330F /* PTFakeTouchTests.m */; }; + 15BBDF161D61AD920098330F /* PTFakeMetaTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF131D61AD920098330F /* PTFakeMetaTouch.h */; }; + 15BBDF171D61AD920098330F /* PTFakeMetaTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = 15BBDF141D61AD920098330F /* PTFakeMetaTouch.m */; }; + 15BBDF1A1D61ADE00098330F /* PTFakeTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF191D61ADE00098330F /* PTFakeTouch.h */; }; + 15BBDF1D1D61AE470098330F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15BBDF1C1D61AE470098330F /* IOKit.framework */; }; + 15BBDF291D61AECA0098330F /* UIApplication-KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF1F1D61AECA0098330F /* UIApplication-KIFAdditions.h */; }; + 15BBDF2A1D61AECA0098330F /* UIApplication-KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 15BBDF201D61AECA0098330F /* UIApplication-KIFAdditions.m */; }; + 15BBDF2B1D61AECA0098330F /* UIEvent+KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF211D61AECA0098330F /* UIEvent+KIFAdditions.h */; }; + 15BBDF2C1D61AECA0098330F /* UIEvent+KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 15BBDF221D61AECA0098330F /* UIEvent+KIFAdditions.m */; }; + 15BBDF2D1D61AECA0098330F /* UITouch-KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF231D61AECA0098330F /* UITouch-KIFAdditions.h */; }; + 15BBDF2E1D61AECA0098330F /* UITouch-KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 15BBDF241D61AECA0098330F /* UITouch-KIFAdditions.m */; }; + 15BBDF2F1D61AECA0098330F /* UIView-KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF251D61AECA0098330F /* UIView-KIFAdditions.h */; }; + 15BBDF301D61AECA0098330F /* UIView-KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 15BBDF261D61AECA0098330F /* UIView-KIFAdditions.m */; }; + 15BBDF311D61AECA0098330F /* UIWindow-KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF271D61AECA0098330F /* UIWindow-KIFAdditions.h */; }; + 15BBDF321D61AECA0098330F /* UIWindow-KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 15BBDF281D61AECA0098330F /* UIWindow-KIFAdditions.m */; }; + 15BBDF351D61AF010098330F /* IOHIDEvent+KIF.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF331D61AF010098330F /* IOHIDEvent+KIF.h */; }; + 15BBDF361D61AF010098330F /* IOHIDEvent+KIF.m in Sources */ = {isa = PBXBuildFile; fileRef = 15BBDF341D61AF010098330F /* IOHIDEvent+KIF.m */; }; + 15BBDF381D61AF540098330F /* FixCategoryBug.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF371D61AF540098330F /* FixCategoryBug.h */; }; + 15BBDF3A1D61AFC50098330F /* LoadableCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 15BBDF391D61AFC50098330F /* LoadableCategory.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 15BBDF051D61AD5B0098330F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 15BBDEF01D61AD5B0098330F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 15BBDEF81D61AD5B0098330F; + remoteInfo = PTFakeTouch; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 15BBDEF91D61AD5B0098330F /* PTFakeTouch.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PTFakeTouch.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 15BBDEFE1D61AD5B0098330F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 15BBDF031D61AD5B0098330F /* PTFakeTouchTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PTFakeTouchTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 15BBDF081D61AD5B0098330F /* PTFakeTouchTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PTFakeTouchTests.m; sourceTree = ""; }; + 15BBDF0A1D61AD5B0098330F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 15BBDF131D61AD920098330F /* PTFakeMetaTouch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PTFakeMetaTouch.h; sourceTree = ""; }; + 15BBDF141D61AD920098330F /* PTFakeMetaTouch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PTFakeMetaTouch.m; sourceTree = ""; }; + 15BBDF191D61ADE00098330F /* PTFakeTouch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PTFakeTouch.h; sourceTree = ""; }; + 15BBDF1C1D61AE470098330F /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = IOKit.framework; sourceTree = ""; }; + 15BBDF1F1D61AECA0098330F /* UIApplication-KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIApplication-KIFAdditions.h"; path = "addition/UIApplication-KIFAdditions.h"; sourceTree = ""; }; + 15BBDF201D61AECA0098330F /* UIApplication-KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIApplication-KIFAdditions.m"; path = "addition/UIApplication-KIFAdditions.m"; sourceTree = ""; }; + 15BBDF211D61AECA0098330F /* UIEvent+KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIEvent+KIFAdditions.h"; path = "addition/UIEvent+KIFAdditions.h"; sourceTree = ""; }; + 15BBDF221D61AECA0098330F /* UIEvent+KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIEvent+KIFAdditions.m"; path = "addition/UIEvent+KIFAdditions.m"; sourceTree = ""; }; + 15BBDF231D61AECA0098330F /* UITouch-KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UITouch-KIFAdditions.h"; path = "addition/UITouch-KIFAdditions.h"; sourceTree = ""; }; + 15BBDF241D61AECA0098330F /* UITouch-KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UITouch-KIFAdditions.m"; path = "addition/UITouch-KIFAdditions.m"; sourceTree = ""; }; + 15BBDF251D61AECA0098330F /* UIView-KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView-KIFAdditions.h"; path = "addition/UIView-KIFAdditions.h"; sourceTree = ""; }; + 15BBDF261D61AECA0098330F /* UIView-KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView-KIFAdditions.m"; path = "addition/UIView-KIFAdditions.m"; sourceTree = ""; }; + 15BBDF271D61AECA0098330F /* UIWindow-KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIWindow-KIFAdditions.h"; path = "addition/UIWindow-KIFAdditions.h"; sourceTree = ""; }; + 15BBDF281D61AECA0098330F /* UIWindow-KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIWindow-KIFAdditions.m"; path = "addition/UIWindow-KIFAdditions.m"; sourceTree = ""; }; + 15BBDF331D61AF010098330F /* IOHIDEvent+KIF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "IOHIDEvent+KIF.h"; path = "addition/IOHIDEvent+KIF.h"; sourceTree = ""; }; + 15BBDF341D61AF010098330F /* IOHIDEvent+KIF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "IOHIDEvent+KIF.m"; path = "addition/IOHIDEvent+KIF.m"; sourceTree = ""; }; + 15BBDF371D61AF540098330F /* FixCategoryBug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FixCategoryBug.h; sourceTree = ""; }; + 15BBDF391D61AFC50098330F /* LoadableCategory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LoadableCategory.h; path = addition/LoadableCategory.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 15BBDEF51D61AD5B0098330F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 15BBDF1D1D61AE470098330F /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 15BBDF001D61AD5B0098330F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 15BBDF041D61AD5B0098330F /* PTFakeTouch.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 15BBDEEF1D61AD5B0098330F = { + isa = PBXGroup; + children = ( + 15BBDEFB1D61AD5B0098330F /* PTFakeTouch */, + 15BBDF071D61AD5B0098330F /* PTFakeTouchTests */, + 15BBDEFA1D61AD5B0098330F /* Products */, + 15BBDF1B1D61AE310098330F /* Frameworks */, + ); + sourceTree = ""; + }; + 15BBDEFA1D61AD5B0098330F /* Products */ = { + isa = PBXGroup; + children = ( + 15BBDEF91D61AD5B0098330F /* PTFakeTouch.framework */, + 15BBDF031D61AD5B0098330F /* PTFakeTouchTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 15BBDEFB1D61AD5B0098330F /* PTFakeTouch */ = { + isa = PBXGroup; + children = ( + 15BBDF131D61AD920098330F /* PTFakeMetaTouch.h */, + 15BBDF141D61AD920098330F /* PTFakeMetaTouch.m */, + 15BBDF191D61ADE00098330F /* PTFakeTouch.h */, + 15BBDF371D61AF540098330F /* FixCategoryBug.h */, + 15BBDF391D61AFC50098330F /* LoadableCategory.h */, + 15BBDEFE1D61AD5B0098330F /* Info.plist */, + 15BBDF1E1D61AE580098330F /* Addition */, + ); + path = PTFakeTouch; + sourceTree = ""; + }; + 15BBDF071D61AD5B0098330F /* PTFakeTouchTests */ = { + isa = PBXGroup; + children = ( + 15BBDF081D61AD5B0098330F /* PTFakeTouchTests.m */, + 15BBDF0A1D61AD5B0098330F /* Info.plist */, + ); + path = PTFakeTouchTests; + sourceTree = ""; + }; + 15BBDF1B1D61AE310098330F /* Frameworks */ = { + isa = PBXGroup; + children = ( + 15BBDF1C1D61AE470098330F /* IOKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 15BBDF1E1D61AE580098330F /* Addition */ = { + isa = PBXGroup; + children = ( + 15BBDF331D61AF010098330F /* IOHIDEvent+KIF.h */, + 15BBDF341D61AF010098330F /* IOHIDEvent+KIF.m */, + 15BBDF1F1D61AECA0098330F /* UIApplication-KIFAdditions.h */, + 15BBDF201D61AECA0098330F /* UIApplication-KIFAdditions.m */, + 15BBDF211D61AECA0098330F /* UIEvent+KIFAdditions.h */, + 15BBDF221D61AECA0098330F /* UIEvent+KIFAdditions.m */, + 15BBDF231D61AECA0098330F /* UITouch-KIFAdditions.h */, + 15BBDF241D61AECA0098330F /* UITouch-KIFAdditions.m */, + 15BBDF251D61AECA0098330F /* UIView-KIFAdditions.h */, + 15BBDF261D61AECA0098330F /* UIView-KIFAdditions.m */, + 15BBDF271D61AECA0098330F /* UIWindow-KIFAdditions.h */, + 15BBDF281D61AECA0098330F /* UIWindow-KIFAdditions.m */, + ); + name = Addition; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 15BBDEF61D61AD5B0098330F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 15BBDF381D61AF540098330F /* FixCategoryBug.h in Headers */, + 15BBDF2F1D61AECA0098330F /* UIView-KIFAdditions.h in Headers */, + 15BBDF311D61AECA0098330F /* UIWindow-KIFAdditions.h in Headers */, + 15BBDF351D61AF010098330F /* IOHIDEvent+KIF.h in Headers */, + 15BBDF3A1D61AFC50098330F /* LoadableCategory.h in Headers */, + 15BBDF2B1D61AECA0098330F /* UIEvent+KIFAdditions.h in Headers */, + 15BBDF161D61AD920098330F /* PTFakeMetaTouch.h in Headers */, + 15BBDF291D61AECA0098330F /* UIApplication-KIFAdditions.h in Headers */, + 15BBDF1A1D61ADE00098330F /* PTFakeTouch.h in Headers */, + 15BBDF2D1D61AECA0098330F /* UITouch-KIFAdditions.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 15BBDEF81D61AD5B0098330F /* PTFakeTouch */ = { + isa = PBXNativeTarget; + buildConfigurationList = 15BBDF0D1D61AD5B0098330F /* Build configuration list for PBXNativeTarget "PTFakeTouch" */; + buildPhases = ( + 15BBDEF41D61AD5B0098330F /* Sources */, + 15BBDEF51D61AD5B0098330F /* Frameworks */, + 15BBDEF61D61AD5B0098330F /* Headers */, + 15BBDEF71D61AD5B0098330F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PTFakeTouch; + productName = PTFakeTouch; + productReference = 15BBDEF91D61AD5B0098330F /* PTFakeTouch.framework */; + productType = "com.apple.product-type.framework"; + }; + 15BBDF021D61AD5B0098330F /* PTFakeTouchTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 15BBDF101D61AD5B0098330F /* Build configuration list for PBXNativeTarget "PTFakeTouchTests" */; + buildPhases = ( + 15BBDEFF1D61AD5B0098330F /* Sources */, + 15BBDF001D61AD5B0098330F /* Frameworks */, + 15BBDF011D61AD5B0098330F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 15BBDF061D61AD5B0098330F /* PBXTargetDependency */, + ); + name = PTFakeTouchTests; + productName = PTFakeTouchTests; + productReference = 15BBDF031D61AD5B0098330F /* PTFakeTouchTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 15BBDEF01D61AD5B0098330F /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0710; + ORGANIZATIONNAME = tangxuan; + TargetAttributes = { + 15BBDEF81D61AD5B0098330F = { + CreatedOnToolsVersion = 7.1; + }; + 15BBDF021D61AD5B0098330F = { + CreatedOnToolsVersion = 7.1; + }; + }; + }; + buildConfigurationList = 15BBDEF31D61AD5B0098330F /* Build configuration list for PBXProject "PTFakeTouch" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 15BBDEEF1D61AD5B0098330F; + productRefGroup = 15BBDEFA1D61AD5B0098330F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 15BBDEF81D61AD5B0098330F /* PTFakeTouch */, + 15BBDF021D61AD5B0098330F /* PTFakeTouchTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 15BBDEF71D61AD5B0098330F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 15BBDF011D61AD5B0098330F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 15BBDEF41D61AD5B0098330F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 15BBDF2E1D61AECA0098330F /* UITouch-KIFAdditions.m in Sources */, + 15BBDF361D61AF010098330F /* IOHIDEvent+KIF.m in Sources */, + 15BBDF2C1D61AECA0098330F /* UIEvent+KIFAdditions.m in Sources */, + 15BBDF301D61AECA0098330F /* UIView-KIFAdditions.m in Sources */, + 15BBDF171D61AD920098330F /* PTFakeMetaTouch.m in Sources */, + 15BBDF321D61AECA0098330F /* UIWindow-KIFAdditions.m in Sources */, + 15BBDF2A1D61AECA0098330F /* UIApplication-KIFAdditions.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 15BBDEFF1D61AD5B0098330F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 15BBDF091D61AD5B0098330F /* PTFakeTouchTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 15BBDF061D61AD5B0098330F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 15BBDEF81D61AD5B0098330F /* PTFakeTouch */; + targetProxy = 15BBDF051D61AD5B0098330F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 15BBDF0B1D61AD5B0098330F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 15BBDF0C1D61AD5B0098330F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 15BBDF0E1D61AD5B0098330F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); + GCC_PREFIX_HEADER = PTFakeTouch/PTFakeTouch.h; + INFOPLIST_FILE = PTFakeTouch/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = nilname.PTFakeTouch; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + 15BBDF0F1D61AD5B0098330F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); + GCC_PREFIX_HEADER = PTFakeTouch/PTFakeTouch.h; + INFOPLIST_FILE = PTFakeTouch/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + PRODUCT_BUNDLE_IDENTIFIER = nilname.PTFakeTouch; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; + 15BBDF111D61AD5B0098330F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = PTFakeTouchTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = nilname.PTFakeTouchTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 15BBDF121D61AD5B0098330F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = PTFakeTouchTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = nilname.PTFakeTouchTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 15BBDEF31D61AD5B0098330F /* Build configuration list for PBXProject "PTFakeTouch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 15BBDF0B1D61AD5B0098330F /* Debug */, + 15BBDF0C1D61AD5B0098330F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 15BBDF0D1D61AD5B0098330F /* Build configuration list for PBXNativeTarget "PTFakeTouch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 15BBDF0E1D61AD5B0098330F /* Debug */, + 15BBDF0F1D61AD5B0098330F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 15BBDF101D61AD5B0098330F /* Build configuration list for PBXNativeTarget "PTFakeTouchTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 15BBDF111D61AD5B0098330F /* Debug */, + 15BBDF121D61AD5B0098330F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 15BBDEF01D61AD5B0098330F /* Project object */; +} diff --git a/PTFakeTouch.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/PTFakeTouch.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..fd7a47d --- /dev/null +++ b/PTFakeTouch.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/PTFakeTouch.xcodeproj/project.xcworkspace/xcuserdata/tangxuan.xcuserdatad/UserInterfaceState.xcuserstate b/PTFakeTouch.xcodeproj/project.xcworkspace/xcuserdata/tangxuan.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..a10e82b Binary files /dev/null and b/PTFakeTouch.xcodeproj/project.xcworkspace/xcuserdata/tangxuan.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/PTFakeTouch.xcodeproj/xcuserdata/tangxuan.xcuserdatad/xcschemes/PTFakeTouch.xcscheme b/PTFakeTouch.xcodeproj/xcuserdata/tangxuan.xcuserdatad/xcschemes/PTFakeTouch.xcscheme new file mode 100644 index 0000000..5d6f81d --- /dev/null +++ b/PTFakeTouch.xcodeproj/xcuserdata/tangxuan.xcuserdatad/xcschemes/PTFakeTouch.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PTFakeTouch.xcodeproj/xcuserdata/tangxuan.xcuserdatad/xcschemes/xcschememanagement.plist b/PTFakeTouch.xcodeproj/xcuserdata/tangxuan.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..72b867e --- /dev/null +++ b/PTFakeTouch.xcodeproj/xcuserdata/tangxuan.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,27 @@ + + + + + SchemeUserState + + PTFakeTouch.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 15BBDEF81D61AD5B0098330F + + primary + + + 15BBDF021D61AD5B0098330F + + primary + + + + + diff --git a/PTFakeTouch/FixCategoryBug.h b/PTFakeTouch/FixCategoryBug.h new file mode 100755 index 0000000..79da9ef --- /dev/null +++ b/PTFakeTouch/FixCategoryBug.h @@ -0,0 +1,33 @@ +// +// FixCategoryBug.h +// FakeTouch +// +// Created by 唐炫 on 16/4/7. +// Copyright © 2016年 唐炫. All rights reserved. +// + +#ifndef MainLib_FixCategoryBug_h +#define MainLib_FixCategoryBug_h + +#define __kw_to_string_1(x) #x +#define __kw_to_string(x) __kw_to_string_1(x) + +// 需要在有category的头文件中调用,例如 KW_FIX_CATEGORY_BUG_H(NSString_Extented) +#define KW_FIX_CATEGORY_BUG_H(name) \ +@interface KW_FIX_CATEGORY_BUG_##name : NSObject \ ++(void)print; \ +@end + +// 需要在有category的源文件中调用,例如 KW_FIX_CATEGORY_BUG_M(NSString_Extented) +#define KW_FIX_CATEGORY_BUG_M(name) \ +@implementation KW_FIX_CATEGORY_BUG_##name \ ++ (void)print { \ +NSLog(@"[Enable]"); \ +} \ +@end \ + + +// 在target中启用这个宏,其实就是调用下category中定义的类的print方法。 +#define KW_ENABLE_CATEGORY(name) [KW_FIX_CATEGORY_BUG_##name print] + +#endif \ No newline at end of file diff --git a/PTFakeTouch/Info.plist b/PTFakeTouch/Info.plist new file mode 100644 index 0000000..d3de8ee --- /dev/null +++ b/PTFakeTouch/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/PTFakeTouch/PTFakeMetaTouch.h b/PTFakeTouch/PTFakeMetaTouch.h new file mode 100755 index 0000000..62befc1 --- /dev/null +++ b/PTFakeTouch/PTFakeMetaTouch.h @@ -0,0 +1,30 @@ +// +// HJFakeMetaTouch.h +// HJFakeTouch +// +// Created by 唐炫 on 16/4/20. +// Copyright © 2016年 唐炫. All rights reserved. +// + +#import +#import + +@interface HJFakeMetaTouch : NSObject +/** + * 构造一个触屏基础操作 + * + * @param pointId 触屏操作的序列号 + * @param point 操作的目的位置 + * @param phase 操作的类别 + * + * @return 返回操作的序列号 + */ ++ (NSInteger)fakeTouchId:(NSInteger)pointId AtPoint:(CGPoint)point withTouchPhase:(UITouchPhase)phase; +/** + * 获取一个没有使用过的触屏序列号 + * + * @return 返回序列号 + */ ++ (NSInteger)getAvailablePointId; + +@end diff --git a/PTFakeTouch/PTFakeMetaTouch.m b/PTFakeTouch/PTFakeMetaTouch.m new file mode 100755 index 0000000..94829dc --- /dev/null +++ b/PTFakeTouch/PTFakeMetaTouch.m @@ -0,0 +1,87 @@ +// +// HJFakeMetaTouch.m +// HJFakeTouch +// +// Created by 唐炫 on 16/4/20. +// Copyright © 2016年 唐炫. All rights reserved. +// + +#import "PTFakeMetaTouch.h" +#import "UITouch-KIFAdditions.h" +#import "UIApplication-KIFAdditions.h" +#import "UIEvent+KIFAdditions.h" +static NSMutableArray *touchAry; +@implementation HJFakeMetaTouch + ++ (void)load{ + KW_ENABLE_CATEGORY(UITouch_KIFAdditions); + KW_ENABLE_CATEGORY(UIEvent_KIFAdditions); + touchAry = [[NSMutableArray alloc] init]; + for (NSInteger i = 0; i<100; i++) { + UITouch *touch = [[UITouch alloc] initTouch]; + [touch setPhaseAndUpdateTimestamp:UITouchPhaseEnded]; + [touchAry addObject:touch]; + } +} + +//构造触屏操作 ++ (NSInteger)fakeTouchId:(NSInteger)pointId AtPoint:(CGPoint)point withTouchPhase:(UITouchPhase)phase{ + //DLog(@"4. fakeTouchId , phase : %ld ",(long)phase); + if (pointId==0) { + //随机一个没有使用的pointId + pointId = [self getAvailablePointId]; + if (pointId==0) { + DLog(@"FakeTouch---pointId 耗尽"); + return 0; + } + } + pointId = pointId - 1; + UITouch *touch = [touchAry objectAtIndex:pointId]; + if (phase == UITouchPhaseBegan) { + touch = nil; + touch = [[UITouch alloc] initAtPoint:point inWindow:[UIApplication sharedApplication].keyWindow]; + [touchAry replaceObjectAtIndex:pointId withObject:touch]; + [touch setLocationInWindow:point]; + }else{ + [touch setLocationInWindow:point]; + [touch setPhaseAndUpdateTimestamp:phase]; + } + + + + UIEvent *event = [self eventWithTouches:touchAry]; + [[UIApplication sharedApplication] sendEvent:event]; + if ((touch.phase==UITouchPhaseBegan)||touch.phase==UITouchPhaseMoved) { + [touch setPhaseAndUpdateTimestamp:UITouchPhaseStationary]; + } + return (pointId+1); +} + + ++ (UIEvent *)eventWithTouches:(NSArray *)touches +{ + // _touchesEvent is a private selector, interface is exposed in UIApplication(KIFAdditionsPrivate) + UIEvent *event = [[UIApplication sharedApplication] _touchesEvent]; + [event _clearTouches]; + [event kif_setEventWithTouches:touches]; + + for (UITouch *aTouch in touches) { + [event _addTouch:aTouch forDelayedDelivery:NO]; + } + + return event; +} + ++ (NSInteger)getAvailablePointId{ + NSInteger availablePointId=0; + NSMutableArray *availableIds = [[NSMutableArray alloc]init]; + for (NSInteger i=0; i + + +//! Project version number for HJGameController. +FOUNDATION_EXPORT double HJGameControllerVersionNumber; + +//! Project version string for HJGameController. +FOUNDATION_EXPORT const unsigned char HJGameControllerVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import +#import + +#ifdef DEBUG +#define RLog(fmt, ...) +#define DLog(fmt, ...) NSLog((@"HJhelper " fmt), ##__VA_ARGS__); +#else +#define DLog(fmt, ...) +#define RLog(fmt, ...) NSLog((@"HJhelper " fmt), ##__VA_ARGS__); +#endif \ No newline at end of file diff --git a/PTFakeTouch/addition/CALayer-KIFAdditions.h b/PTFakeTouch/addition/CALayer-KIFAdditions.h new file mode 100755 index 0000000..711daa1 --- /dev/null +++ b/PTFakeTouch/addition/CALayer-KIFAdditions.h @@ -0,0 +1,31 @@ +// +// CALayer-KIFAdditions.h +// Pods +// +// Created by Radu Ciobanu on 28/01/2016. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. +// + +#import + +@interface CALayer (KIFAdditions) + +/** + * @method hasAnimations + * @abstract Traverses self's hierarchy of layers and checks whether any + * visible sublayers or self have ongoing anymations. + * @return YES if an animated layer has been found, NO otherwise. + */ +- (BOOL)hasAnimations; + +/*! + @method performBlockOnDescendentLayers: + @abstract Calls a block on the layer itself and on all its descendent layers. + @param block The block that will be called on the layers. Stop the traversation + of the layers by assigning YES to the stop-parameter of the block. + */ +- (void)performBlockOnDescendentLayers:(void (^)(CALayer *layer, BOOL *stop))block; + +@end diff --git a/PTFakeTouch/addition/CALayer-KIFAdditions.m b/PTFakeTouch/addition/CALayer-KIFAdditions.m new file mode 100755 index 0000000..ff42f28 --- /dev/null +++ b/PTFakeTouch/addition/CALayer-KIFAdditions.m @@ -0,0 +1,52 @@ +// +// CALayer-KIFAdditions.m +// Pods +// +// Created by Radu Ciobanu on 28/01/2016. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. +// + +#import "CALayer-KIFAdditions.h" + +@implementation CALayer (KIFAdditions) + +- (BOOL)hasAnimations +{ + __block BOOL result = NO; + [self performBlockOnDescendentLayers:^(CALayer *layer, BOOL *stop) { + // explicitly exclude _UIParallaxMotionEffect as it is used in alertviews, and we don't want every alertview to be paused) + BOOL hasAnimation = layer.animationKeys.count != 0 && ![layer.animationKeys isEqualToArray:@[@"_UIParallaxMotionEffect"]]; + if (hasAnimation && !layer.hidden) { + result = YES; + if (stop != NULL) { + *stop = YES; + } + } + }]; + return result; +} + +- (void)performBlockOnDescendentLayers:(void (^)(CALayer *layer, BOOL *stop))block +{ + BOOL stop = NO; + [self performBlockOnDescendentLayers:block stop:&stop]; +} + +- (void)performBlockOnDescendentLayers:(void (^)(CALayer *, BOOL *))block stop:(BOOL *)stop +{ + block(self, stop); + if (*stop) { + return; + } + + for (CALayer *layer in self.sublayers) { + [layer performBlockOnDescendentLayers:block stop:stop]; + if (*stop) { + return; + } + } +} + +@end diff --git a/PTFakeTouch/addition/CGGeometry-KIFAdditions.h b/PTFakeTouch/addition/CGGeometry-KIFAdditions.h new file mode 100755 index 0000000..a1e94fb --- /dev/null +++ b/PTFakeTouch/addition/CGGeometry-KIFAdditions.h @@ -0,0 +1,18 @@ +// +// CGGeometry-KIFAdditions.h +// KIF +// +// Created by Eric Firestone on 5/22/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import + +CG_INLINE CGPoint CGPointCenteredInRect(CGRect bounds) { + return CGPointMake(bounds.origin.x + bounds.size.width * 0.5f, bounds.origin.y + bounds.size.height * 0.5f); +} + +CG_INLINE CGPoint CGPointMidPoint(CGPoint point1, CGPoint point2) { + return CGPointMake((point1.x + point2.x) / 2.0f, (point1.y + point2.y) / 2.0f); +} diff --git a/PTFakeTouch/addition/CGGeometry-KIFAdditions.m b/PTFakeTouch/addition/CGGeometry-KIFAdditions.m new file mode 100755 index 0000000..bb4062b --- /dev/null +++ b/PTFakeTouch/addition/CGGeometry-KIFAdditions.m @@ -0,0 +1,11 @@ +// +// CGGeometry-KIFAdditions.m +// KIF +// +// Created by Eric Firestone on 5/22/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import "CGGeometry-KIFAdditions.h" + diff --git a/PTFakeTouch/addition/IOHIDEvent+KIF.h b/PTFakeTouch/addition/IOHIDEvent+KIF.h new file mode 100755 index 0000000..c497064 --- /dev/null +++ b/PTFakeTouch/addition/IOHIDEvent+KIF.h @@ -0,0 +1,11 @@ +// +// IOHIDEvent+KIF.h +// testAnything +// +// Created by 唐炫 on 16/4/1. +// Copyright © 2016年 唐炫. All rights reserved. +// + + +typedef struct __IOHIDEvent * IOHIDEventRef; +IOHIDEventRef kif_IOHIDEventWithTouches(NSArray *touches) CF_RETURNS_RETAINED; \ No newline at end of file diff --git a/PTFakeTouch/addition/IOHIDEvent+KIF.m b/PTFakeTouch/addition/IOHIDEvent+KIF.m new file mode 100755 index 0000000..c9182c1 --- /dev/null +++ b/PTFakeTouch/addition/IOHIDEvent+KIF.m @@ -0,0 +1,180 @@ +// +// IOHIDEvent+KIF.m +// testAnything +// +// Created by 唐炫 on 16/4/1. +// Copyright © 2016年 唐炫. All rights reserved. +// + +#import +#import "IOHIDEvent+KIF.h" +#import +#define IOHIDEventFieldBase(type) (type << 16) +#ifdef __LP64__ +typedef double IOHIDFloat; +#else +typedef float IOHIDFloat; +#endif +typedef UInt32 IOOptionBits; +typedef uint32_t IOHIDDigitizerTransducerType; +typedef uint32_t IOHIDEventField; +typedef uint32_t IOHIDEventType; + +void IOHIDEventAppendEvent(IOHIDEventRef event, IOHIDEventRef childEvent); +void IOHIDEventSetIntegerValue(IOHIDEventRef event, IOHIDEventField field, int value); +void IOHIDEventSetSenderID(IOHIDEventRef event, uint64_t sender); + +enum { + kIOHIDDigitizerTransducerTypeStylus = 0, + kIOHIDDigitizerTransducerTypePuck, + kIOHIDDigitizerTransducerTypeFinger, + kIOHIDDigitizerTransducerTypeHand +}; +enum { + kIOHIDEventTypeNULL, // 0 + kIOHIDEventTypeVendorDefined, + kIOHIDEventTypeButton, + kIOHIDEventTypeKeyboard, + kIOHIDEventTypeTranslation, + kIOHIDEventTypeRotation, // 5 + kIOHIDEventTypeScroll, + kIOHIDEventTypeScale, + kIOHIDEventTypeZoom, + kIOHIDEventTypeVelocity, + kIOHIDEventTypeOrientation, // 10 + kIOHIDEventTypeDigitizer, + kIOHIDEventTypeAmbientLightSensor, + kIOHIDEventTypeAccelerometer, + kIOHIDEventTypeProximity, + kIOHIDEventTypeTemperature, // 15 + kIOHIDEventTypeNavigationSwipe, + kIOHIDEventTypePointer, + kIOHIDEventTypeProgress, + kIOHIDEventTypeMultiAxisPointer, + kIOHIDEventTypeGyro, // 20 + kIOHIDEventTypeCompass, + kIOHIDEventTypeZoomToggle, + kIOHIDEventTypeDockSwipe, // just like kIOHIDEventTypeNavigationSwipe, but intended for consumption by Dock + kIOHIDEventTypeSymbolicHotKey, + kIOHIDEventTypePower, // 25 + kIOHIDEventTypeLED, + kIOHIDEventTypeFluidTouchGesture, // This will eventually superseed Navagation and Dock swipes + kIOHIDEventTypeBoundaryScroll, + kIOHIDEventTypeBiometric, + kIOHIDEventTypeUnicode, // 30 + kIOHIDEventTypeAtmosphericPressure, + kIOHIDEventTypeUndefined, + kIOHIDEventTypeCount, // This should always be last + // DEPRECATED: + kIOHIDEventTypeSwipe = kIOHIDEventTypeNavigationSwipe, + kIOHIDEventTypeMouse = kIOHIDEventTypePointer +}; +enum { + kIOHIDDigitizerEventRange = 0x00000001, + kIOHIDDigitizerEventTouch = 0x00000002, + kIOHIDDigitizerEventPosition = 0x00000004, + kIOHIDDigitizerEventStop = 0x00000008, + kIOHIDDigitizerEventPeak = 0x00000010, + kIOHIDDigitizerEventIdentity = 0x00000020, + kIOHIDDigitizerEventAttribute = 0x00000040, + kIOHIDDigitizerEventCancel = 0x00000080, + kIOHIDDigitizerEventStart = 0x00000100, + kIOHIDDigitizerEventResting = 0x00000200, + kIOHIDDigitizerEventSwipeUp = 0x01000000, + kIOHIDDigitizerEventSwipeDown = 0x02000000, + kIOHIDDigitizerEventSwipeLeft = 0x04000000, + kIOHIDDigitizerEventSwipeRight = 0x08000000, + kIOHIDDigitizerEventSwipeMask = 0xFF000000, +}; +enum { + kIOHIDEventFieldDigitizerX = IOHIDEventFieldBase(kIOHIDEventTypeDigitizer), + kIOHIDEventFieldDigitizerY, + kIOHIDEventFieldDigitizerZ, + kIOHIDEventFieldDigitizerButtonMask, + kIOHIDEventFieldDigitizerType, + kIOHIDEventFieldDigitizerIndex, + kIOHIDEventFieldDigitizerIdentity, + kIOHIDEventFieldDigitizerEventMask, + kIOHIDEventFieldDigitizerRange, + kIOHIDEventFieldDigitizerTouch, + kIOHIDEventFieldDigitizerPressure, + kIOHIDEventFieldDigitizerAuxiliaryPressure, //BarrelPressure + kIOHIDEventFieldDigitizerTwist, + kIOHIDEventFieldDigitizerTiltX, + kIOHIDEventFieldDigitizerTiltY, + kIOHIDEventFieldDigitizerAltitude, + kIOHIDEventFieldDigitizerAzimuth, + kIOHIDEventFieldDigitizerQuality, + kIOHIDEventFieldDigitizerDensity, + kIOHIDEventFieldDigitizerIrregularity, + kIOHIDEventFieldDigitizerMajorRadius, + kIOHIDEventFieldDigitizerMinorRadius, + kIOHIDEventFieldDigitizerCollection, + kIOHIDEventFieldDigitizerCollectionChord, + kIOHIDEventFieldDigitizerChildEventMask, + kIOHIDEventFieldDigitizerIsDisplayIntegrated, + kIOHIDEventFieldDigitizerQualityRadiiAccuracy, +}; +IOHIDEventRef IOHIDEventCreateDigitizerEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDDigitizerTransducerType type, + uint32_t index, uint32_t identity, uint32_t eventMask, uint32_t buttonMask, + IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOHIDFloat tipPressure, IOHIDFloat barrelPressure, + Boolean range, Boolean touch, IOOptionBits options); +IOHIDEventRef IOHIDEventCreateDigitizerFingerEventWithQuality(CFAllocatorRef allocator, AbsoluteTime timeStamp, + uint32_t index, uint32_t identity, uint32_t eventMask, + IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOHIDFloat tipPressure, IOHIDFloat twist, + IOHIDFloat minorRadius, IOHIDFloat majorRadius, IOHIDFloat quality, IOHIDFloat density, IOHIDFloat irregularity, + Boolean range, Boolean touch, IOOptionBits options); + + + +IOHIDEventRef kif_IOHIDEventWithTouches(NSArray *touches) { + uint64_t abTime = mach_absolute_time(); + AbsoluteTime timeStamp; + timeStamp.hi = (UInt32)(abTime >> 32); + timeStamp.lo = (UInt32)(abTime); + IOHIDEventRef handEvent = IOHIDEventCreateDigitizerEvent(kCFAllocatorDefault, // allocator 内存分配器 + timeStamp, // timestamp 时间戳 + kIOHIDDigitizerTransducerTypeHand, // type + 0, // index + 0, // identity + kIOHIDDigitizerEventTouch, // eventMask + 0, // buttonMask + 0, // x + 0, // y + 0, // z + 0, // tipPressure + 0, // barrelPressure + 0, // range + true, // touch + 0); // options + IOHIDEventSetIntegerValue(handEvent, kIOHIDEventFieldDigitizerIsDisplayIntegrated, true); + for (UITouch *touch in touches) + { + uint32_t eventMask = (touch.phase == UITouchPhaseMoved) ? kIOHIDDigitizerEventPosition : (kIOHIDDigitizerEventRange | kIOHIDDigitizerEventTouch); + uint32_t isTouching = (touch.phase == UITouchPhaseEnded) ? 0 : 1; + CGPoint touchLocation = [touch locationInView:touch.window]; + IOHIDEventRef fingerEvent = IOHIDEventCreateDigitizerFingerEventWithQuality(kCFAllocatorDefault, // allocator + timeStamp, // timestamp + (UInt32)[touches indexOfObject:touch] + 1, //index + 2, // identity + eventMask, // eventMask + (IOHIDFloat)touchLocation.x, // x + (IOHIDFloat)touchLocation.y, // y + 0.0, // z + 0, // tipPressure + 0, // twist + 5.0, // minor radius + 5.0, // major radius + 1.0, // quality + 1.0, // density + 1.0, // irregularity + (IOHIDFloat)isTouching, // range + (IOHIDFloat)isTouching, // touch + 0); // options + IOHIDEventSetIntegerValue(fingerEvent, kIOHIDEventFieldDigitizerIsDisplayIntegrated, 1); + IOHIDEventAppendEvent(handEvent, fingerEvent); + CFRelease(fingerEvent); + } + return handEvent; +} + diff --git a/PTFakeTouch/addition/LoadableCategory.h b/PTFakeTouch/addition/LoadableCategory.h new file mode 100755 index 0000000..92259bb --- /dev/null +++ b/PTFakeTouch/addition/LoadableCategory.h @@ -0,0 +1,18 @@ +// +// LoadableCategory.h +// KIF +// +// Created by Karl Stenerud on 7/16/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +/** Make all categories in the current file loadable without using -load-all. + * + * Normally, compilers will skip linking files that contain only categories. + * Adding a call to this macro adds a dummy class, which causes the linker + * to add the file. + * + * @param UNIQUE_NAME A globally unique name. + */ +#define MAKE_CATEGORIES_LOADABLE(UNIQUE_NAME) @interface FORCELOAD_##UNIQUE_NAME : NSObject @end @implementation FORCELOAD_##UNIQUE_NAME @end diff --git a/PTFakeTouch/addition/NSBundle-KIFAdditions.h b/PTFakeTouch/addition/NSBundle-KIFAdditions.h new file mode 100755 index 0000000..60cbe68 --- /dev/null +++ b/PTFakeTouch/addition/NSBundle-KIFAdditions.h @@ -0,0 +1,15 @@ +// +// NSBundle+KIFAdditions.h +// KIF +// +// Created by Brian Nickel on 7/27/13. +// +// + +#import + +@interface NSBundle (KIFAdditions) + ++ (NSBundle *)KIFTestBundle; + +@end diff --git a/PTFakeTouch/addition/NSBundle-KIFAdditions.m b/PTFakeTouch/addition/NSBundle-KIFAdditions.m new file mode 100755 index 0000000..8b34f69 --- /dev/null +++ b/PTFakeTouch/addition/NSBundle-KIFAdditions.m @@ -0,0 +1,27 @@ +// +// NSBundle+KIFAdditions.m +// KIF +// +// Created by Brian Nickel on 7/27/13. +// +// + +#import "NSBundle-KIFAdditions.h" +#import "KIFTestCase.h" +#import "LoadableCategory.h" + +MAKE_CATEGORIES_LOADABLE(NSBundle_KIFAdditions) + +@implementation NSBundle (KIFAdditions) + ++ (NSBundle *)KIFTestBundle +{ + static NSBundle *bundle; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + bundle = [self bundleForClass:[KIFTestCase class]]; + }); + return bundle; +} + +@end diff --git a/PTFakeTouch/addition/NSError-KIFAdditions.h b/PTFakeTouch/addition/NSError-KIFAdditions.h new file mode 100755 index 0000000..9232560 --- /dev/null +++ b/PTFakeTouch/addition/NSError-KIFAdditions.h @@ -0,0 +1,16 @@ +// +// NSError+KIFAdditions.h +// KIF +// +// Created by Brian Nickel on 7/27/13. +// +// + +#import + +@interface NSError (KIFAdditions) + ++ (instancetype)KIFErrorWithUnderlyingError:(NSError *)underlyingError format:(NSString *)format, ... NS_FORMAT_FUNCTION(2,3); ++ (instancetype)KIFErrorWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2); + +@end diff --git a/PTFakeTouch/addition/NSError-KIFAdditions.m b/PTFakeTouch/addition/NSError-KIFAdditions.m new file mode 100755 index 0000000..226309f --- /dev/null +++ b/PTFakeTouch/addition/NSError-KIFAdditions.m @@ -0,0 +1,39 @@ +// +// NSError+KIFAdditions.m +// KIF +// +// Created by Brian Nickel on 7/27/13. +// +// + +#import "NSError-KIFAdditions.h" +#import "LoadableCategory.h" +#import "KIFTestActor.h" + +MAKE_CATEGORIES_LOADABLE(NSError_KIFAdditions) + +@implementation NSError (KIFAdditions) + ++ (instancetype)KIFErrorWithFormat:(NSString *)format, ... +{ + va_list args; + va_start(args, format); + NSString *description = [[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + return [self errorWithDomain:@"KIFTest" code:KIFTestStepResultFailure userInfo:@{NSLocalizedDescriptionKey: description}]; +} + ++ (instancetype)KIFErrorWithUnderlyingError:(NSError *)underlyingError format:(NSString *)format, ... +{ + va_list args; + va_start(args, format); + NSString *description = [[NSString alloc] initWithFormat:format arguments:args]; + va_end(args); + + NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:description, NSLocalizedDescriptionKey, underlyingError, NSUnderlyingErrorKey, nil]; + + return [self errorWithDomain:@"KIFTest" code:KIFTestStepResultFailure userInfo:userInfo]; +} + +@end diff --git a/PTFakeTouch/addition/NSException-KIFAdditions.h b/PTFakeTouch/addition/NSException-KIFAdditions.h new file mode 100755 index 0000000..487fc0b --- /dev/null +++ b/PTFakeTouch/addition/NSException-KIFAdditions.h @@ -0,0 +1,15 @@ +// +// NSException-KIFAdditions.h +// KIF +// +// Created by Tony DiPasquale on 12/20/13. +// +// + +#import + +@interface NSException (KIFAdditions) + ++ (NSException *)failureInFile:(NSString *)file atLine:(NSInteger)line withDescription:(NSString *)formatString, ...; + +@end diff --git a/PTFakeTouch/addition/NSException-KIFAdditions.m b/PTFakeTouch/addition/NSException-KIFAdditions.m new file mode 100755 index 0000000..55bcc21 --- /dev/null +++ b/PTFakeTouch/addition/NSException-KIFAdditions.m @@ -0,0 +1,28 @@ +// +// NSException-KIFAdditions.m +// KIF +// +// Created by Tony DiPasquale on 12/20/13. +// +// + +#import "NSException-KIFAdditions.h" + +@implementation NSException (KIFAdditions) + ++ (NSException *)failureInFile:(NSString *)file atLine:(NSInteger)line withDescription:(NSString *)formatString, ... +{ + va_list argumentList; + va_start(argumentList, formatString); + + NSString *reason = [[NSString alloc] initWithFormat:formatString arguments:argumentList]; + + va_end(argumentList); + + return [NSException exceptionWithName:@"KIFFailureException" + reason: reason + userInfo:@{@"FilenameKey": file, + @"LineNumberKey": @(line)}]; +} + +@end diff --git a/PTFakeTouch/addition/NSFileManager-KIFAdditions.h b/PTFakeTouch/addition/NSFileManager-KIFAdditions.h new file mode 100755 index 0000000..5875d54 --- /dev/null +++ b/PTFakeTouch/addition/NSFileManager-KIFAdditions.h @@ -0,0 +1,18 @@ +// +// NSFileManager-KIFAdditions.h +// KIF +// +// Created by Michael Thole on 6/1/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import + + +@interface NSFileManager (KIFAdditions) + +- (NSString *)createUserDirectory:(NSSearchPathDirectory)searchPath; +- (BOOL)recursivelyCreateDirectory:(NSString *)path; + +@end diff --git a/PTFakeTouch/addition/NSFileManager-KIFAdditions.m b/PTFakeTouch/addition/NSFileManager-KIFAdditions.m new file mode 100755 index 0000000..b41f4a5 --- /dev/null +++ b/PTFakeTouch/addition/NSFileManager-KIFAdditions.m @@ -0,0 +1,67 @@ +// +// NSFileManager-KIFAdditions.m +// KIF +// +// Created by Michael Thole on 6/1/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import "NSFileManager-KIFAdditions.h" +#import "LoadableCategory.h" + + +MAKE_CATEGORIES_LOADABLE(NSFileManager_KIFAdditions) + + +@implementation NSFileManager (KIFAdditions) + +#pragma mark Public Methods + +- (NSString *)createUserDirectory:(NSSearchPathDirectory)searchPath; +{ + NSArray *paths = NSSearchPathForDirectoriesInDomains(searchPath, NSUserDomainMask, YES); + if (!paths.count) { + return nil; + } + + NSString *rootDirectory = paths[0]; + + BOOL isDir; + BOOL created = NO; + if ([self fileExistsAtPath:rootDirectory isDirectory:&isDir] && isDir) { + created = YES; + } else { + created = [self recursivelyCreateDirectory:rootDirectory]; + } + + return created ? rootDirectory : nil; +} + +- (BOOL)recursivelyCreateDirectory:(NSString *)path; +{ + BOOL isDir = NO; + BOOL isParentADir = NO; + NSString *parentDir = nil; + + if (![self fileExistsAtPath:path isDirectory:&isDir]) { + // if file doesn't exist, first create parent + parentDir = [path stringByDeletingLastPathComponent]; + + if (!parentDir.length || [parentDir isEqualToString:@"/"]) { + isParentADir = YES; + } else { + isParentADir = [self recursivelyCreateDirectory:parentDir]; + } + + if (isParentADir) { + isDir = [self createDirectoryAtPath:path withIntermediateDirectories:NO attributes:nil error:nil]; + } else { + return NO; + } + } + + return isDir; +} + +@end diff --git a/PTFakeTouch/addition/NSPredicate+KIFAdditions.h b/PTFakeTouch/addition/NSPredicate+KIFAdditions.h new file mode 100755 index 0000000..98f06f0 --- /dev/null +++ b/PTFakeTouch/addition/NSPredicate+KIFAdditions.h @@ -0,0 +1,18 @@ +// +// NSPredicate+KIFAdditions.h +// KIF +// +// Created by Alex Odawa on 2/3/15. +// +// + +#import + +@interface NSPredicate (KIFAdditions) + +@property NSString *kifPredicateDescription; + +- (NSArray *)flatten; +- (NSCompoundPredicate *)minusSubpredicatesFrom:(NSPredicate *)otherPredicate; + +@end diff --git a/PTFakeTouch/addition/NSPredicate+KIFAdditions.m b/PTFakeTouch/addition/NSPredicate+KIFAdditions.m new file mode 100755 index 0000000..d2f3fc2 --- /dev/null +++ b/PTFakeTouch/addition/NSPredicate+KIFAdditions.m @@ -0,0 +1,72 @@ +// +// NSPredicate+KIFAdditions.m +// KIF +// +// Created by Alex Odawa on 2/3/15. +// +// + +#import +#import "NSPredicate+KIFAdditions.h" + +@implementation NSPredicate (KIFAdditions) + +- (NSArray *)flatten +{ + NSMutableArray *result = [[NSMutableArray alloc] init]; + + if ([self isKindOfClass:[NSCompoundPredicate class]]) { + for (NSPredicate *predicate in ((NSCompoundPredicate *)self).subpredicates) { + [result addObjectsFromArray:[predicate flatten]]; + } + } else { + [result addObject:self]; + } + + return result; +} + +- (NSCompoundPredicate *)minusSubpredicatesFrom:(NSPredicate *)otherPredicate; +{ + if (self == otherPredicate) { + return nil; + } + NSMutableSet *subpredicates = [NSMutableSet setWithArray:[self flatten]]; + NSMutableSet *otherSubpredicates = [NSMutableSet setWithArray:[otherPredicate flatten]]; + [subpredicates minusSet:otherSubpredicates]; + return [[NSCompoundPredicate alloc] initWithType:NSAndPredicateType + subpredicates:[subpredicates allObjects]]; +} + +- (void)setKifPredicateDescription:(NSString *)description; +{ + NSString *desc = description.copy; + objc_setAssociatedObject(self, @selector(kifPredicateDescription), desc, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (NSString *)kifPredicateDescription; +{ + id object = objc_getAssociatedObject(self, @selector(kifPredicateDescription)); + if (object) { + return object; + } + // Compound predicates containing subpredicates with the kifPredicateDescription set should still get our pretty formatting. + if ([self isKindOfClass:[NSCompoundPredicate class]]) { + NSArray *subpredicates = [self flatten]; + NSString *description = @""; + + for (NSPredicate *predicate in subpredicates) { + if (description.length > 0) { + description = [description stringByAppendingString:@", "]; + } + description = [description stringByAppendingString:predicate.kifPredicateDescription]; + } + if (description.length > 0) { + return description; + } + } + + return self.description; +} + +@end diff --git a/PTFakeTouch/addition/NSString+KIFAdditions.h b/PTFakeTouch/addition/NSString+KIFAdditions.h new file mode 100755 index 0000000..1cbacf6 --- /dev/null +++ b/PTFakeTouch/addition/NSString+KIFAdditions.h @@ -0,0 +1,16 @@ +// +// NSString+KIFAdditions.h +// KIF +// +// Created by Alex Odawa on 1/28/16. +// +// + +#import + +#pragma mark - NSString +@interface NSString (KIFAdditions) + +- (BOOL)KIF_isEqualToStringOrAttributedString:(id)aString; + +@end diff --git a/PTFakeTouch/addition/NSString+KIFAdditions.m b/PTFakeTouch/addition/NSString+KIFAdditions.m new file mode 100755 index 0000000..c20fc3e --- /dev/null +++ b/PTFakeTouch/addition/NSString+KIFAdditions.m @@ -0,0 +1,24 @@ +// +// NSString+KIFAdditions.m +// KIF +// +// Created by Alex Odawa on 1/28/16. +// +// + +#import "NSString+KIFAdditions.h" + +#pragma mark - NSString +@implementation NSString (KIFAdditions) + +- (BOOL)KIF_isEqualToStringOrAttributedString:(id)aString; +{ + // Somtimes Accessibility Elements will return an AXAttributedString. + // This compares the raw backing string against a vanilla NSString, ignoring any attributes. + if ([aString respondsToSelector:@selector(string)]) { + return [self isEqualToString:[(id)aString string]]; + } + return [self isEqualToString:aString]; +} + +@end diff --git a/PTFakeTouch/addition/UIAccessibilityElement-KIFAdditions.h b/PTFakeTouch/addition/UIAccessibilityElement-KIFAdditions.h new file mode 100755 index 0000000..552996a --- /dev/null +++ b/PTFakeTouch/addition/UIAccessibilityElement-KIFAdditions.h @@ -0,0 +1,75 @@ +// +// UIAccessibilityElement-KIFAdditions.h +// KIF +// +// Created by Eric Firestone on 5/23/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import + + +@interface UIAccessibilityElement (KIFAdditions) + +/*! + @abstract Finds the first view that the accessibility element is part of. + @discussion There is not always a one-to-one mapping between views and accessibility elements. Accessibility elements may not even map to the view you will expect. For instance, table view cell accessibility elements return the @c UITableView and keyboard keys map to the keyboard as a whole. + + @param element The accessibility element. + @return The first matching @c UIView as determined by the accessibility API. + */ ++ (UIView *)viewContainingAccessibilityElement:(UIAccessibilityElement *)element; + +/*! + @abstract Finds an accessibility element and view with a matching label, value, and traits, optionally passing a tappability test. + @discussion This method combines @c +accessibilityElementWithLabel:value:traits:error: and @c +viewContainingAccessibilityElement:tappable:error: for convenience. + @param foundElement The found accessibility element or @c nil if the method returns @c NO. Can be @c NULL. + @param foundView The first matching view for @c foundElement as determined by the accessibility API or @c nil if the view is hidden or fails the tappability test. Can be @c NULL. + @param label The accessibility label of the element to wait for. + @param value The accessibility value of the element to tap. + @param traits The accessibility traits of the element to wait for. Elements that do not include at least these traits are ignored. + @param error A reference to an error object to be populated when no matching element or view is found. Can be @c NULL. + @result @c YES if the element and view were found. Otherwise @c NO. + */ ++ (BOOL)accessibilityElement:(out UIAccessibilityElement **)foundElement view:(out UIView **)foundView withLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits tappable:(BOOL)mustBeTappable error:(out NSError **)error; + +/*! + @abstract Finds an accessibility element with a matching label, value, and traits. + @discussion This functionality is identical to -[UIApplication accessibilityElementWithLabel:accessibilityValue:traits:] except that it detailed error messaging in the case where the element cannot be found. + @param label The accessibility label of the element to wait for. + @param value The accessibility value of the element to tap. + @param traits The accessibility traits of the element to wait for. Elements that do not include at least these traits are ignored. + @param error A reference to an error object to be populated when no element is found. Can be @c NULL. + @return The found accessibility element. If @c nil see the @c error for a detailed reason. + */ ++ (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits error:(out NSError **)error; + +/*! + @abstract Finds an accessibility element and view where the element passes the predicate, optionally passing a tappability test. + @param foundElement The found accessibility element or @c nil if the method returns @c NO. Can be @c NULL. + @param foundView The first matching view for @c foundElement as determined by the accessibility API or @c nil if the view is hidden or fails the tappability test. Can be @c NULL. + @param predicate The predicate to test the accessibility element on. + @param error A reference to an error object to be populated when no matching element or view is found. Can be @c NULL. + @result @c YES if the element and view were found. Otherwise @c NO. + */ ++ (BOOL)accessibilityElement:(out UIAccessibilityElement **)foundElement view:(out UIView **)foundView withElementMatchingPredicate:(NSPredicate *)predicate tappable:(BOOL)mustBeTappable error:(out NSError **)error; + +/*! + @abstract Finds and attempts to make visible a view for a given accessibility element. + @discussion If the element is found, off screen, and is inside a scroll view, this method will attempt to programmatically scroll the view onto the screen before performing any logic as to if the view is tappable. + + @param element The accessibility element. + @param mustBeTappable If @c YES, a tappability test will be performed. + @param error A reference to an error object to be populated when no element is found. Can be @c NULL. + @return The first matching view as determined by the accessibility API or nil if the view is hidden or fails the tappability test. + */ ++ (UIView *)viewContainingAccessibilityElement:(UIAccessibilityElement *)element tappable:(BOOL)mustBeTappable error:(NSError **)error; + +/*! + @abstract Returns a human readable string of UIAccessiblityTrait names, derived from UIAccessibilityConstants.h. + @param traits The accessibility traits to list. +*/ ++ (NSString *)stringFromAccessibilityTraits:(UIAccessibilityTraits)traits; + +@end diff --git a/PTFakeTouch/addition/UIAccessibilityElement-KIFAdditions.m b/PTFakeTouch/addition/UIAccessibilityElement-KIFAdditions.m new file mode 100755 index 0000000..b073ec2 --- /dev/null +++ b/PTFakeTouch/addition/UIAccessibilityElement-KIFAdditions.m @@ -0,0 +1,292 @@ +// +// UIAccessibilityElement-KIFAdditions.m +// KIF +// +// Created by Eric Firestone on 5/23/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import "NSError-KIFAdditions.h" +#import "NSPredicate+KIFAdditions.h" +#import "UIAccessibilityElement-KIFAdditions.h" +#import "UIApplication-KIFAdditions.h" +#import "UIScrollView-KIFAdditions.h" +#import "UIView-KIFAdditions.h" +#import "LoadableCategory.h" +#import "KIFTestActor.h" + +MAKE_CATEGORIES_LOADABLE(UIAccessibilityElement_KIFAdditions) + + +@implementation UIAccessibilityElement (KIFAdditions) + ++ (UIView *)viewContainingAccessibilityElement:(UIAccessibilityElement *)element; +{ + while (element && ![element isKindOfClass:[UIView class]]) { + // Sometimes accessibilityContainer will return a view that's too far up the view hierarchy + // UIAccessibilityElement instances will sometimes respond to view, so try to use that and then fall back to accessibilityContainer + id view = [element respondsToSelector:@selector(view)] ? [(id)element view] : nil; + + if (view) { + element = view; + } else { + element = [element accessibilityContainer]; + } + } + + return (UIView *)element; +} + ++ (BOOL)accessibilityElement:(out UIAccessibilityElement **)foundElement view:(out UIView **)foundView withLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits tappable:(BOOL)mustBeTappable error:(out NSError **)error; +{ + UIAccessibilityElement *element = [self accessibilityElementWithLabel:label value:value traits:traits error:error]; + if (!element) { + return NO; + } + + UIView *view = [self viewContainingAccessibilityElement:element tappable:mustBeTappable error:error]; + if (!view) { + return NO; + } + + if (foundElement) { *foundElement = element; } + if (foundView) { *foundView = view; } + return YES; +} + ++ (BOOL)accessibilityElement:(out UIAccessibilityElement **)foundElement view:(out UIView **)foundView withElementMatchingPredicate:(NSPredicate *)predicate tappable:(BOOL)mustBeTappable error:(out NSError **)error; +{ + UIAccessibilityElement *element = [[UIApplication sharedApplication] accessibilityElementMatchingBlock:^BOOL(UIAccessibilityElement *element) { + return [predicate evaluateWithObject:element]; + }]; + + if (!element) { + if (error) { + *error = [self errorForFailingPredicate:predicate]; + } + return NO; + } + + UIView *view = [UIAccessibilityElement viewContainingAccessibilityElement:element tappable:mustBeTappable error:error]; + if (!view) { + return NO; + } + + if (foundElement) { *foundElement = element; } + if (foundView) { *foundView = view; } + return YES; +} + ++ (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label value:(NSString *)value traits:(UIAccessibilityTraits)traits error:(out NSError **)error; +{ + UIAccessibilityElement *element = [[UIApplication sharedApplication] accessibilityElementWithLabel:label accessibilityValue:value traits:traits]; + if (element || !error) { + return element; + } + + element = [[UIApplication sharedApplication] accessibilityElementWithLabel:label accessibilityValue:nil traits:traits]; + // For purposes of a better error message, see if we can find the view, just not a view with the specified value. + if (value && element) { + *error = [NSError KIFErrorWithFormat:@"Found an accessibility element with the label \"%@\", but with the value \"%@\", not \"%@\"", label, element.accessibilityValue, value]; + return nil; + } + + // Check the traits, too. + element = [[UIApplication sharedApplication] accessibilityElementWithLabel:label accessibilityValue:nil traits:UIAccessibilityTraitNone]; + if (traits != UIAccessibilityTraitNone && element) { + *error = [NSError KIFErrorWithFormat:@"Found an accessibility element with the label \"%@\", but not with the traits \"%llu\"", label, traits]; + return nil; + } + + *error = [NSError KIFErrorWithFormat:@"Failed to find accessibility element with the label \"%@\"", label]; + return nil; +} + ++ (UIView *)viewContainingAccessibilityElement:(UIAccessibilityElement *)element tappable:(BOOL)mustBeTappable error:(NSError **)error; +{ + // Small safety mechanism. If someone calls this method after a failing call to accessibilityElementWithLabel:..., we don't want to wipe out the error message. + if (!element && error && *error) { + return nil; + } + + // Make sure the element is visible + UIView *view = [UIAccessibilityElement viewContainingAccessibilityElement:element]; + if (!view) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Cannot find view containing accessibility element with the label \"%@\"", element.accessibilityLabel]; + } + return nil; + } + + // Scroll the view (and superviews) to be visible if necessary + UIView *superview = (UIScrollView *)view; + while (superview) { + // Fix for iOS7 table view cells containing scroll views + if ([superview.superview isKindOfClass:[UITableViewCell class]]) { + break; + } + + if ([superview isKindOfClass:[UIScrollView class]]) { + UIScrollView *scrollView = (UIScrollView *)superview; + + if (((UIAccessibilityElement *)view == element) && ![view isKindOfClass:[UITableViewCell class]]) { + [scrollView scrollViewToVisible:view animated:YES]; + } else { + CGRect elementFrame = [view.window convertRect:element.accessibilityFrame toView:scrollView]; + CGRect visibleRect = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, CGRectGetWidth(scrollView.bounds), CGRectGetHeight(scrollView.bounds)); + + // Only call scrollRectToVisible if the element isn't already visible + // iOS 8 will sometimes incorrectly scroll table views so the element scrolls out of view + if (!CGRectContainsRect(visibleRect, elementFrame)) { + [scrollView scrollRectToVisible:elementFrame animated:YES]; + } + } + + // Give the scroll view a small amount of time to perform the scroll. + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.3, false); + } + + superview = superview.superview; + } + + if ([[UIApplication sharedApplication] isIgnoringInteractionEvents]) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Application is ignoring interaction events"]; + } + return nil; + } + + // If we don't require tappability, at least make sure it's not hidden + if ([view isHidden]) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Accessibility element with label \"%@\" is hidden.", element.accessibilityLabel]; + } + return nil; + } + + if (mustBeTappable && !view.isProbablyTappable) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Accessibility element with label \"%@\" is not tappable. It may be blocked by other views.", element.accessibilityLabel]; + } + return nil; + } + + return view; +} + ++ (NSError *)errorForFailingPredicate:(NSPredicate*)failingPredicate; +{ + NSPredicate *closestMatchingPredicate = [self findClosestMatchingPredicate:failingPredicate]; + if (closestMatchingPredicate) { + return [NSError KIFErrorWithFormat:@"Found element with %@ but not %@", \ + closestMatchingPredicate.kifPredicateDescription, \ + [failingPredicate minusSubpredicatesFrom:closestMatchingPredicate].kifPredicateDescription]; + } + return [NSError KIFErrorWithFormat:@"Could not find element with %@", failingPredicate.kifPredicateDescription]; +} + ++ (NSPredicate *)findClosestMatchingPredicate:(NSPredicate *)aPredicate; +{ + if (!aPredicate) { + return nil; + } + + UIAccessibilityElement *match = [[UIApplication sharedApplication] accessibilityElementMatchingBlock:^BOOL (UIAccessibilityElement *element) { + return [aPredicate evaluateWithObject:element]; + }]; + if (match) { + return aPredicate; + } + + // Breadth-First algorithm to match as many subpredicates as possible + NSMutableArray *queue = [NSMutableArray arrayWithObject:aPredicate]; + while (queue.count > 0) { + // Dequeuing + NSPredicate *predicate = [queue firstObject]; + [queue removeObject:predicate]; + + // Remove one subpredicate at a time an then check if an element would match this resulting predicate + for (NSPredicate *subpredicate in [predicate flatten]) { + NSPredicate *predicateMinusOneCondition = [predicate minusSubpredicatesFrom:subpredicate]; + if (predicateMinusOneCondition) { + UIAccessibilityElement *match = [[UIApplication sharedApplication] accessibilityElementMatchingBlock:^BOOL (UIAccessibilityElement *element) { + return [predicateMinusOneCondition evaluateWithObject:element]; + }]; + if (match) { + return predicateMinusOneCondition; + } + [queue addObject:predicateMinusOneCondition]; + } + } + } + return nil; +} + ++ (NSString *)stringFromAccessibilityTraits:(UIAccessibilityTraits)traits; +{ + if (traits == UIAccessibilityTraitNone) { + return @"UIAccessibilityTraitNone"; + } + + NSString *string = @""; + + NSArray *allTraits = @[ + @(UIAccessibilityTraitButton), + @(UIAccessibilityTraitLink), + @(UIAccessibilityTraitHeader), + @(UIAccessibilityTraitSearchField), + @(UIAccessibilityTraitImage), + @(UIAccessibilityTraitSelected), + @(UIAccessibilityTraitPlaysSound), + @(UIAccessibilityTraitKeyboardKey), + @(UIAccessibilityTraitStaticText), + @(UIAccessibilityTraitSummaryElement), + @(UIAccessibilityTraitNotEnabled), + @(UIAccessibilityTraitUpdatesFrequently), + @(UIAccessibilityTraitStartsMediaSession), + @(UIAccessibilityTraitAdjustable), + @(UIAccessibilityTraitAllowsDirectInteraction), + @(UIAccessibilityTraitCausesPageTurn) + ]; + + NSArray *traitNames = @[ + @"UIAccessibilityTraitButton", + @"UIAccessibilityTraitLink", + @"UIAccessibilityTraitHeader", + @"UIAccessibilityTraitSearchField", + @"UIAccessibilityTraitImage", + @"UIAccessibilityTraitSelected", + @"UIAccessibilityTraitPlaysSound", + @"UIAccessibilityTraitKeyboardKey", + @"UIAccessibilityTraitStaticText", + @"UIAccessibilityTraitSummaryElement", + @"UIAccessibilityTraitNotEnabled", + @"UIAccessibilityTraitUpdatesFrequently", + @"UIAccessibilityTraitStartsMediaSession", + @"UIAccessibilityTraitAdjustable", + @"UIAccessibilityTraitAllowsDirectInteraction", + @"UIAccessibilityTraitCausesPageTurn" + ]; + + + for (NSNumber *trait in allTraits) { + if ((traits & trait.longLongValue) == trait.longLongValue) { + NSString *name = [traitNames objectAtIndex:[allTraits indexOfObject:trait]]; + if (string.length > 0) { + string = [string stringByAppendingString:@", "]; + } + string = [string stringByAppendingString:name]; + traits &= ~trait.longLongValue; + } + } + if (traits != UIAccessibilityTraitNone) { + if (string.length > 0) { + string = [string stringByAppendingString:@", "]; + } + string = [string stringByAppendingFormat:@"UNKNOWN ACCESSIBILITY TRAIT: %llu", traits]; + } + return string; +} + +@end diff --git a/PTFakeTouch/addition/UIApplication-KIFAdditions.h b/PTFakeTouch/addition/UIApplication-KIFAdditions.h new file mode 100755 index 0000000..5c9525e --- /dev/null +++ b/PTFakeTouch/addition/UIApplication-KIFAdditions.h @@ -0,0 +1,115 @@ +// +// UIApplication-KIFAdditions.h +// KIF +// +// Created by Eric Firestone on 5/20/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import + +#define UIApplicationCurrentRunMode ([[UIApplication sharedApplication] currentRunLoopMode]) + +/*! + @abstract When mocking @c -openURL:, this notification is posted. + */ +UIKIT_EXTERN NSString *const UIApplicationDidMockOpenURLNotification; + +/*! + @abstract When mocking @c -canOpenURL:, this notification is posted. + */ +UIKIT_EXTERN NSString *const UIApplicationDidMockCanOpenURLNotification; + +/*! + @abstract The key for the opened URL in the @c UIApplicationDidMockOpenURLNotification notification. + */ +UIKIT_EXTERN NSString *const UIApplicationOpenedURLKey; + +@interface UIApplication (KIFAdditions) + +/*! + @abstract Finds an accessibility element with a matching label, value, and traits across all windows in the application starting at the frontmost window. + @param label The accessibility label of the element to search for. + @param value The accessibility value of the element to search for. If @c nil, all values will be accepted. + @param traits The accessibility traits of the element to search for. Elements that do not include at least these traits are ignored. + @return The found accessibility element or @c nil if the element could not be found. + */ +- (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label accessibilityValue:(NSString *)value traits:(UIAccessibilityTraits)traits; + +/*! + @abstract Finds an accessibility element where @c matchBlock returns @c YES, across all windows in the application starting at the fronmost window. + @discussion This method should be used if @c accessibilityElementWithLabel:accessibilityValue:traits: does not meet your requirements. For example, if you are searching for an element that begins with a pattern or if of a certain view type. + @param matchBlock A block to be performed on each element to see if it passes. + */ +- (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessibilityElement *))matchBlock; + +/*! + @returns The window containing the keyboard or @c nil if the keyboard is not visible. + */ +- (UIWindow *)keyboardWindow; + +/*! + @returns The topmost window containing a @c UIDatePicker. + */ +- (UIWindow *)datePickerWindow; + +/*! + @returns The topmost window containing a @c UIPickerView. + */ +- (UIWindow *)pickerViewWindow; + +/*! + @returns The topmost window containing a @c UIDimmingView. + */ +- (UIWindow *)dimmingViewWindow; + +/*! + @returns All windows in the application, including the key window even if it does not appear in @c -windows. + */ +- (NSArray *)windowsWithKeyWindow; + +/*! + @abstract Writes a screenshot to disk. + @discussion This method only works if the @c KIF_SCREENSHOTS environment variable is set. + @param lineNumber The line number in the code at which the screenshot was taken. + @param filename The name of the file in which the screenshot was taken. + @param description An optional description of the scene being captured. + @param error If the method returns @c YES, this optional parameter provides additional information as to why it failed. + @returns @c YES if the screenshot was written to disk, otherwise @c NO. + */ +- (BOOL)writeScreenshotForLine:(NSUInteger)lineNumber inFile:(NSString *)filename description:(NSString *)description error:(NSError **)error; + +/*! + @returns The current run loop mode. + */ +- (CFStringRef)currentRunLoopMode; + +/*! + @abstract Swizzles the run loop modes so KIF can better switch between them. + */ ++ (void)swizzleRunLoop; + +/*! + @abstract Starts mocking requests to @c -openURL:, announcing all requests with a notification. + @discussion After calling this method, whenever @c -openURL: is called a notification named @c UIApplicationDidMockOpenURLNotification with the URL in the @c UIApplicationOpenedURL will be raised and the normal behavior will be cancelled. + @param returnValue The value to return when @c -openURL: is called. + */ ++ (void)startMockingOpenURLWithReturnValue:(BOOL)returnValue; + +/*! + @abstract Stops the application from mocking requests to @c -openURL:. + */ ++ (void)stopMockingOpenURL; + +@end + +@interface UIApplication (Private) +- (UIWindow *)statusBarWindow; +@property(getter=isStatusBarHidden) BOOL statusBarHidden; +@end + +@interface UIApplication (KIFAdditionsPrivate) +- (UIEvent *)_touchesEvent; +@end + diff --git a/PTFakeTouch/addition/UIApplication-KIFAdditions.m b/PTFakeTouch/addition/UIApplication-KIFAdditions.m new file mode 100755 index 0000000..f478dc3 --- /dev/null +++ b/PTFakeTouch/addition/UIApplication-KIFAdditions.m @@ -0,0 +1,303 @@ +// +// UIApplication-KIFAdditions.m +// KIF +// +// Created by Eric Firestone on 5/20/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import "UIApplication-KIFAdditions.h" +#import "LoadableCategory.h" +#import "UIView-KIFAdditions.h" +#import "NSError-KIFAdditions.h" +#import +#import +#import + +MAKE_CATEGORIES_LOADABLE(UIApplication_KIFAdditions) + +static BOOL _KIF_UIApplicationMockOpenURL = NO; +static BOOL _KIF_UIApplicationMockOpenURL_returnValue = NO; + +@interface UIApplication (Undocumented) +- (void)pushRunLoopMode:(id)arg1; +- (void)pushRunLoopMode:(id)arg1 requester:(id)requester; +- (void)popRunLoopMode:(id)arg1; +- (void)popRunLoopMode:(id)arg1 requester:(id)requester; +@end + +NSString *const UIApplicationDidMockOpenURLNotification = @"UIApplicationDidMockOpenURLNotification"; +NSString *const UIApplicationDidMockCanOpenURLNotification = @"UIApplicationDidMockCanOpenURLNotification"; +NSString *const UIApplicationOpenedURLKey = @"UIApplicationOpenedURL"; +static const void *KIFRunLoopModesKey = &KIFRunLoopModesKey; + +@implementation UIApplication (KIFAdditions) + +#pragma mark - Finding elements + +- (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label accessibilityValue:(NSString *)value traits:(UIAccessibilityTraits)traits; +{ + // Go through the array of windows in reverse order to process the frontmost window first. + // When several elements with the same accessibilitylabel are present the one in front will be picked. + for (UIWindow *window in [self.windowsWithKeyWindow reverseObjectEnumerator]) { + UIAccessibilityElement *element = [window accessibilityElementWithLabel:label accessibilityValue:value traits:traits]; + if (element) { + return element; + } + } + + return nil; +} + +- (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessibilityElement *))matchBlock; +{ + for (UIWindow *window in [self.windowsWithKeyWindow reverseObjectEnumerator]) { + UIAccessibilityElement *element = [window accessibilityElementMatchingBlock:matchBlock]; + if (element) { + return element; + } + } + + return nil; +} + +#pragma mark - Interesting windows + +- (UIWindow *)keyboardWindow; +{ + for (UIWindow *window in self.windowsWithKeyWindow) { + if ([NSStringFromClass([window class]) isEqual:@"UITextEffectsWindow"]) { + return window; + } + } + + return nil; +} + +- (UIWindow *)datePickerWindow; +{ + return [self getWindowForSubviewClass:@"UIDatePicker"]; +} + +- (UIWindow *)pickerViewWindow; +{ + return [self getWindowForSubviewClass:@"UIPickerView"]; +} + +- (UIWindow *)dimmingViewWindow; +{ + return [self getWindowForSubviewClass:@"UIDimmingView"]; +} + +- (UIWindow *)getWindowForSubviewClass:(NSString*)className; +{ + for (UIWindow *window in self.windowsWithKeyWindow) { + NSArray *subViews = [window subviewsWithClassNameOrSuperClassNamePrefix:className]; + if (subViews.count > 0) { + return window; + } + } + + return nil; +} + +- (NSArray *)windowsWithKeyWindow +{ + NSMutableArray *windows = self.windows.mutableCopy; + UIWindow *keyWindow = self.keyWindow; + if (![windows containsObject:keyWindow]) { + [windows addObject:keyWindow]; + } + return windows; +} + +#pragma mark - Screenshotting + +- (BOOL)writeScreenshotForLine:(NSUInteger)lineNumber inFile:(NSString *)filename description:(NSString *)description error:(NSError **)error; +{ + NSString *outputPath = [[[NSProcessInfo processInfo] environment] objectForKey:@"KIF_SCREENSHOTS"]; + if (!outputPath) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Screenshot path not defined. Please set KIF_SCREENSHOTS environment variable."]; + } + return NO; + } + + NSArray *windows = [self windowsWithKeyWindow]; + if (windows.count == 0) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Could not take screenshot. No windows were available."]; + } + return NO; + } + + if (!filename.length) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Missing screenshot filename."]; + } + return NO; + } + + UIGraphicsBeginImageContextWithOptions([[windows objectAtIndex:0] bounds].size, YES, 0); + for (UIWindow *window in windows) { + //avoid https://github.com/kif-framework/KIF/issues/679 + if (window.hidden) { + continue; + } + + if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) { + [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES]; + } else { + [window.layer renderInContext:UIGraphicsGetCurrentContext()]; + } + } + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + outputPath = [outputPath stringByExpandingTildeInPath]; + + NSError *directoryCreationError = nil; + if (![[NSFileManager defaultManager] createDirectoryAtPath:outputPath withIntermediateDirectories:YES attributes:nil error:&directoryCreationError]) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Couldn't create directory at path %@ (details: %@)", outputPath, directoryCreationError]; + } + return NO; + } + + NSString *imageName = [self imageNameForFile:filename lineNumber:lineNumber description:description]; + + outputPath = [outputPath stringByAppendingPathComponent:imageName]; + outputPath = [outputPath stringByAppendingPathExtension:@"png"]; + + if (![UIImagePNGRepresentation(image) writeToFile:outputPath atomically:YES]) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Could not write file at path %@", outputPath]; + } + return NO; + } + + return YES; +} + +- (NSString *)imageNameForFile:(NSString *)filename lineNumber:(NSUInteger)lineNumber description:(NSString *)description { + if (!filename.length) { + return nil; + } + + NSString *imageName = [filename lastPathComponent]; + + if (lineNumber > 0) { + imageName = [imageName stringByAppendingFormat:@", line %lu", (unsigned long)lineNumber]; + } + + if (description.length) { + imageName = [imageName stringByAppendingFormat:@", %@", description]; + } + + return imageName; +} + +#pragma mark - Run loop monitoring + +- (NSMutableArray *)KIF_runLoopModes; +{ + NSMutableArray *modes = objc_getAssociatedObject(self, KIFRunLoopModesKey); + if (!modes) { + modes = [NSMutableArray arrayWithObject:(id)kCFRunLoopDefaultMode]; + objc_setAssociatedObject(self, KIFRunLoopModesKey, modes, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return modes; +} + +- (CFStringRef)currentRunLoopMode; +{ + return (__bridge CFStringRef)[self KIF_runLoopModes].lastObject; +} + +- (void)KIF_pushRunLoopMode:(NSString *)mode; +{ + [[self KIF_runLoopModes] addObject:mode]; + [self KIF_pushRunLoopMode:mode]; +} + +- (void)KIF_pushRunLoopMode:(NSString *)mode requester:(id)requester; +{ + [[self KIF_runLoopModes] addObject:mode]; + [self KIF_pushRunLoopMode:mode requester:requester]; +} + +- (void)KIF_popRunLoopMode:(NSString *)mode; +{ + [[self KIF_runLoopModes] removeLastObject]; + [self KIF_popRunLoopMode:mode]; +} + + +- (void)KIF_popRunLoopMode:(NSString *)mode requester:(id)requester; +{ + [[self KIF_runLoopModes] removeLastObject]; + [self KIF_popRunLoopMode:mode requester:requester]; +} + +- (BOOL)KIF_openURL:(NSURL *)URL; +{ + if (_KIF_UIApplicationMockOpenURL) { + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidMockOpenURLNotification object:self userInfo:@{UIApplicationOpenedURLKey: URL}]; + return _KIF_UIApplicationMockOpenURL_returnValue; + } else { + return [self KIF_openURL:URL]; + } +} + +- (BOOL)KIF_canOpenURL:(NSURL *)URL; +{ + if (_KIF_UIApplicationMockOpenURL) { + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidMockCanOpenURLNotification object:self userInfo:@{UIApplicationOpenedURLKey: URL}]; + return _KIF_UIApplicationMockOpenURL_returnValue; + } else { + return [self KIF_canOpenURL:URL]; + } +} + +static inline void Swizzle(Class c, SEL orig, SEL new) +{ + Method origMethod = class_getInstanceMethod(c, orig); + Method newMethod = class_getInstanceMethod(c, new); + if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) + class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); + else + method_exchangeImplementations(origMethod, newMethod); +} + ++ (void)swizzleRunLoop; +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Swizzle(self, @selector(pushRunLoopMode:), @selector(KIF_pushRunLoopMode:)); + Swizzle(self, @selector(pushRunLoopMode:requester:), @selector(KIF_pushRunLoopMode:requester:)); + Swizzle(self, @selector(popRunLoopMode:), @selector(KIF_popRunLoopMode:)); + Swizzle(self, @selector(popRunLoopMode:requester:), @selector(KIF_popRunLoopMode:requester:)); + }); +} + +#pragma mark - openURL mocking + ++ (void)startMockingOpenURLWithReturnValue:(BOOL)returnValue; +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Swizzle(self, @selector(openURL:), @selector(KIF_openURL:)); + Swizzle(self, @selector(canOpenURL:), @selector(KIF_canOpenURL:)); + }); + + _KIF_UIApplicationMockOpenURL = YES; + _KIF_UIApplicationMockOpenURL_returnValue = returnValue; +} + ++ (void)stopMockingOpenURL; +{ + _KIF_UIApplicationMockOpenURL = NO; +} + +@end diff --git a/PTFakeTouch/addition/UIEvent+KIFAdditions.h b/PTFakeTouch/addition/UIEvent+KIFAdditions.h new file mode 100755 index 0000000..eaeb257 --- /dev/null +++ b/PTFakeTouch/addition/UIEvent+KIFAdditions.h @@ -0,0 +1,21 @@ +// +// UIEvent+KIFAdditions.h +// KIF +// +// Created by Thomas on 3/1/15. +// +// + +#import +#import "FixCategoryBug.h" +KW_FIX_CATEGORY_BUG_H(UIEvent_KIFAdditions) + +// Exposes methods of UITouchesEvent so that the compiler doesn't complain +@interface UIEvent (KIFAdditionsPrivateHeaders) +- (void)_addTouch:(UITouch *)touch forDelayedDelivery:(BOOL)arg2; +- (void)_clearTouches; +@end + +@interface UIEvent (KIFAdditions) +- (void)kif_setEventWithTouches:(NSArray *)touches; +@end \ No newline at end of file diff --git a/PTFakeTouch/addition/UIEvent+KIFAdditions.m b/PTFakeTouch/addition/UIEvent+KIFAdditions.m new file mode 100755 index 0000000..c60bf65 --- /dev/null +++ b/PTFakeTouch/addition/UIEvent+KIFAdditions.m @@ -0,0 +1,94 @@ +// +// UIEvent+KIFAdditions.m +// KIF +// +// Created by Thomas on 3/1/15. +// +// + +#import "UIEvent+KIFAdditions.h" +#import "LoadableCategory.h" +#import "IOHIDEvent+KIF.h" + +KW_FIX_CATEGORY_BUG_M(UIEvent_KIFAdditions) + +MAKE_CATEGORIES_LOADABLE(UIEvent_KIFAdditions) + + +// +// GSEvent is an undeclared object. We don't need to use it ourselves but some +// Apple APIs (UIScrollView in particular) require the x and y fields to be present. +// +@interface KIFGSEventProxy : NSObject +{ +@public + unsigned int flags; + unsigned int type; + unsigned int ignored1; + float x1; + float y1; + float x2; + float y2; + unsigned int ignored2[10]; + unsigned int ignored3[7]; + float sizeX; + float sizeY; + float x3; + float y3; + unsigned int ignored4[3]; +} +@end + +@implementation KIFGSEventProxy +@end + +typedef struct __GSEvent * GSEventRef; + +@interface UIEvent (KIFAdditionsMorePrivateHeaders) +- (void)_setGSEvent:(GSEventRef)event; +- (void)_setHIDEvent:(IOHIDEventRef)event; +- (void)_setTimestamp:(NSTimeInterval)timestemp; +@end + +@implementation UIEvent (KIFAdditions) + +- (void)kif_setEventWithTouches:(NSArray *)touches +{ + NSOperatingSystemVersion iOS8 = {8, 0, 0}; + if ([NSProcessInfo instancesRespondToSelector:@selector(isOperatingSystemAtLeastVersion:)] + && [[NSProcessInfo new] isOperatingSystemAtLeastVersion:iOS8]) { + [self kif_setIOHIDEventWithTouches:touches]; + } else { + [self kif_setGSEventWithTouches:touches]; + } +} + +- (void)kif_setGSEventWithTouches:(NSArray *)touches +{ + UITouch *touch = touches[0]; + CGPoint location = [touch locationInView:touch.window]; + KIFGSEventProxy *gsEventProxy = [[KIFGSEventProxy alloc] init]; + gsEventProxy->x1 = location.x; + gsEventProxy->y1 = location.y; + gsEventProxy->x2 = location.x; + gsEventProxy->y2 = location.y; + gsEventProxy->x3 = location.x; + gsEventProxy->y3 = location.y; + gsEventProxy->sizeX = 1.0; + gsEventProxy->sizeY = 1.0; + gsEventProxy->flags = ([touch phase] == UITouchPhaseEnded) ? 0x1010180 : 0x3010180; + gsEventProxy->type = 3001; + + [self _setGSEvent:(GSEventRef)gsEventProxy]; + + [self _setTimestamp:(((UITouch*)touches[0]).timestamp)]; +} + +- (void)kif_setIOHIDEventWithTouches:(NSArray *)touches +{ + IOHIDEventRef event = kif_IOHIDEventWithTouches(touches); + [self _setHIDEvent:event]; + CFRelease(event); +} + +@end \ No newline at end of file diff --git a/PTFakeTouch/addition/UIScreen+KIFAdditions.h b/PTFakeTouch/addition/UIScreen+KIFAdditions.h new file mode 100755 index 0000000..e51d023 --- /dev/null +++ b/PTFakeTouch/addition/UIScreen+KIFAdditions.h @@ -0,0 +1,15 @@ +// +// UIScreen+KIFAdditions.h +// KIF +// +// Created by Steven King on 25/02/2016. +// +// + +#import + +@interface UIScreen (KIFAdditions) + +@property (nonatomic, readonly) CGFloat majorSwipeDisplacement; + +@end diff --git a/PTFakeTouch/addition/UIScreen+KIFAdditions.m b/PTFakeTouch/addition/UIScreen+KIFAdditions.m new file mode 100755 index 0000000..0cf213a --- /dev/null +++ b/PTFakeTouch/addition/UIScreen+KIFAdditions.m @@ -0,0 +1,17 @@ +// +// UIScreen+KIFAdditions.m +// KIF +// +// Created by Steven King on 25/02/2016. +// +// + +#import "UIScreen+KIFAdditions.h" + +@implementation UIScreen (KIFAdditions) + +- (CGFloat)majorSwipeDisplacement { + return self.bounds.size.width * 0.625; +} + +@end diff --git a/PTFakeTouch/addition/UIScrollView-KIFAdditions.h b/PTFakeTouch/addition/UIScrollView-KIFAdditions.h new file mode 100755 index 0000000..a97480e --- /dev/null +++ b/PTFakeTouch/addition/UIScrollView-KIFAdditions.h @@ -0,0 +1,17 @@ +// +// UIScrollView-KIFAdditions.h +// KIF +// +// Created by Eric Firestone on 5/22/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import + + +@interface UIScrollView (KIFAdditions) + +- (void)scrollViewToVisible:(UIView *)view animated:(BOOL)animated; + +@end diff --git a/PTFakeTouch/addition/UIScrollView-KIFAdditions.m b/PTFakeTouch/addition/UIScrollView-KIFAdditions.m new file mode 100755 index 0000000..a1e2245 --- /dev/null +++ b/PTFakeTouch/addition/UIScrollView-KIFAdditions.m @@ -0,0 +1,44 @@ +// +// UIScrollView-KIFAdditions.m +// KIF +// +// Created by Eric Firestone on 5/22/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import "UIScrollView-KIFAdditions.h" +#import "LoadableCategory.h" +#import "UIApplication-KIFAdditions.h" +#import "UIView-KIFAdditions.h" + + +MAKE_CATEGORIES_LOADABLE(UIScrollView_KIFAdditions) + + +@implementation UIScrollView (KIFAdditions) + +- (void)scrollViewToVisible:(UIView *)view animated:(BOOL)animated; +{ + CGRect viewFrame = [self convertRect:view.bounds fromView:view]; + CGPoint contentOffset = self.contentOffset; + + if (CGRectGetMaxX(viewFrame) > self.contentOffset.x + CGRectGetWidth(self.bounds)) { + contentOffset.x = MIN(CGRectGetMaxX(viewFrame) - CGRectGetWidth(self.bounds), CGRectGetMinX(viewFrame)); + } else if (CGRectGetMinX(viewFrame) < self.contentOffset.x) { + contentOffset.x = MAX(CGRectGetMaxX(viewFrame) - CGRectGetWidth(self.bounds), CGRectGetMinX(viewFrame)); + } + + if (CGRectGetMaxY(viewFrame) > self.contentOffset.y + CGRectGetHeight(self.bounds)) { + contentOffset.y = MIN(CGRectGetMaxY(viewFrame) - CGRectGetHeight(self.bounds), CGRectGetMinY(viewFrame)); + } else if (CGRectGetMinY(viewFrame) < self.contentOffset.y) { + contentOffset.y = MAX(CGRectGetMaxY(viewFrame) - CGRectGetHeight(self.bounds), CGRectGetMinY(viewFrame)); + } + + if (!CGPointEqualToPoint(contentOffset, self.contentOffset)) { + [self setContentOffset:contentOffset animated:animated]; + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.2, false); + } +} + +@end diff --git a/PTFakeTouch/addition/UITableView-KIFAdditions.h b/PTFakeTouch/addition/UITableView-KIFAdditions.h new file mode 100755 index 0000000..5dfc987 --- /dev/null +++ b/PTFakeTouch/addition/UITableView-KIFAdditions.h @@ -0,0 +1,16 @@ +// +// UITableView-KIFAdditions.h +// KIF +// +// Created by Hilton Campbell on 4/12/14. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import + +@interface UITableView (KIFAdditions) + +- (BOOL)dragCell:(UITableViewCell *)cell toIndexPath:(NSIndexPath *)indexPath error:(NSError **)error; + +@end diff --git a/PTFakeTouch/addition/UITableView-KIFAdditions.m b/PTFakeTouch/addition/UITableView-KIFAdditions.m new file mode 100755 index 0000000..e3bbab0 --- /dev/null +++ b/PTFakeTouch/addition/UITableView-KIFAdditions.m @@ -0,0 +1,87 @@ +// +// UITableView-KIFAdditions.m +// KIF +// +// Created by Hilton Campbell on 4/12/14. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import "UITableView-KIFAdditions.h" +#import "UIView-KIFAdditions.h" +#import "UIApplication-KIFAdditions.h" +#import "UITouch-KIFAdditions.h" +#import "CGGeometry-KIFAdditions.h" +#import "NSError-KIFAdditions.h" + +@implementation UITableView (KIFAdditions) + +#define DRAG_STEP_DISTANCE 5 + +- (BOOL)dragCell:(UITableViewCell *)cell toIndexPath:(NSIndexPath *)indexPath error:(NSError **)error; +{ + UIView *sourceReorderControl = [[cell subviewsWithClassNameOrSuperClassNamePrefix:@"UITableViewCellReorderControl"] lastObject]; + if (!sourceReorderControl) { + if (error) { + *error = [NSError KIFErrorWithFormat:@"Failed to find reorder control for cell"]; + } + return NO; + } + + CGPoint sourcePoint = [self convertPoint:CGPointCenteredInRect(sourceReorderControl.bounds) fromView:sourceReorderControl]; + + // If section < 0, search from the end of the table. + if (indexPath.section < 0) { + indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:self.numberOfSections + indexPath.section]; + } + + // If row < 0, search from the end of the section. + if (indexPath.row < 0) { + indexPath = [NSIndexPath indexPathForRow:[self numberOfRowsInSection:indexPath.section] + indexPath.row inSection:indexPath.section]; + } + + CGPoint destinationPoint = CGPointMake(sourcePoint.x, CGPointCenteredInRect([self rectForRowAtIndexPath:indexPath]).y); + + // Create the touch (there should only be one touch object for the whole drag) + UITouch *touch = [[UITouch alloc] initAtPoint:sourcePoint inView:self]; + [touch setPhaseAndUpdateTimestamp:UITouchPhaseBegan]; + + UIEvent *eventDown = [self eventWithTouch:touch]; + [[UIApplication sharedApplication] sendEvent:eventDown]; + + // Hold long enough to enter reordering mode + CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.2, false); + + CGPoint currentLocation = sourcePoint; + while (currentLocation.y < destinationPoint.y - DRAG_STEP_DISTANCE || currentLocation.y > destinationPoint.y + DRAG_STEP_DISTANCE) { + if (currentLocation.y < destinationPoint.y) { + currentLocation.y += DRAG_STEP_DISTANCE; + } else { + currentLocation.y -= DRAG_STEP_DISTANCE; + } + + [touch setLocationInWindow:[self.window convertPoint:currentLocation fromView:self]]; + [touch setPhaseAndUpdateTimestamp:UITouchPhaseMoved]; + + UIEvent *eventDrag = [self eventWithTouch:touch]; + [[UIApplication sharedApplication] sendEvent:eventDrag]; + + CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.01, false); + } + + // Hold long enough for the animations to catch up + CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.2, false); + + [touch setPhaseAndUpdateTimestamp:UITouchPhaseEnded]; + + UIEvent *eventUp = [self eventWithTouch:touch]; + [[UIApplication sharedApplication] sendEvent:eventUp]; + + // Dispatching the event doesn't actually update the first responder, so fake it + if (touch.view == self && [self canBecomeFirstResponder]) { + [self becomeFirstResponder]; + } + return YES; +} + +@end diff --git a/PTFakeTouch/addition/UITouch-KIFAdditions.h b/PTFakeTouch/addition/UITouch-KIFAdditions.h new file mode 100755 index 0000000..4bc2f4b --- /dev/null +++ b/PTFakeTouch/addition/UITouch-KIFAdditions.h @@ -0,0 +1,45 @@ +// +// UITouch-KIFAdditions.h +// KIF +// +// Created by Eric Firestone on 5/20/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import +#import "IOHIDEvent+KIF.h" +#import "FixCategoryBug.h" + +KW_FIX_CATEGORY_BUG_H(UITouch_KIFAdditions) + +@interface UITouch () + + +- (void)setWindow:(UIWindow *)window; +- (void)setView:(UIView *)view; +- (void)setTapCount:(NSUInteger)tapCount; +- (void)setIsTap:(BOOL)isTap; +- (void)setTimestamp:(NSTimeInterval)timestamp; +- (void)setPhase:(UITouchPhase)touchPhase; +- (void)setGestureView:(UIView *)view; +- (void)_setLocationInWindow:(CGPoint)location resetPrevious:(BOOL)resetPrevious; +- (void)_setIsFirstTouchForView:(BOOL)firstTouchForView; + +- (void)_setHidEvent:(IOHIDEventRef)event; + +@end + +@interface UITouch (KIFAdditions) + +- (id)initInView:(UIView *)view; +- (id)initAtPoint:(CGPoint)point inView:(UIView *)view; +- (id)initAtPoint:(CGPoint)point inWindow:(UIWindow *)window; +- (id)initTouch; +- (void)resetTouch; + +- (void)setLocationInWindow:(CGPoint)location; +- (void)setPhaseAndUpdateTimestamp:(UITouchPhase)phase; + +@end + diff --git a/PTFakeTouch/addition/UITouch-KIFAdditions.m b/PTFakeTouch/addition/UITouch-KIFAdditions.m new file mode 100755 index 0000000..b895875 --- /dev/null +++ b/PTFakeTouch/addition/UITouch-KIFAdditions.m @@ -0,0 +1,161 @@ +// +// UITouch-KIFAdditions.m +// KIF +// +// Created by Eric Firestone on 5/20/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import "UITouch-KIFAdditions.h" +#import "LoadableCategory.h" +#import + +KW_FIX_CATEGORY_BUG_M(UITouch_KIFAdditions) + +MAKE_CATEGORIES_LOADABLE(UITouch_KIFAdditions) + +typedef struct { + unsigned int _firstTouchForView:1; + unsigned int _isTap:1; + unsigned int _isDelayed:1; + unsigned int _sentTouchesEnded:1; + unsigned int _abandonForwardingRecord:1; +} UITouchFlags; + + + +@implementation UITouch (KIFAdditions) + +- (id)initInView:(UIView *)view; +{ + CGRect frame = view.frame; + CGPoint centerPoint = CGPointMake(frame.size.width * 0.5f, frame.size.height * 0.5f); + return [self initAtPoint:centerPoint inView:view]; +} + +- (id)initAtPoint:(CGPoint)point inWindow:(UIWindow *)window; +{ + self = [super init]; + if (self == nil) { + return nil; + } + + // Create a fake tap touch + [self setWindow:window]; // Wipes out some values. Needs to be first. + + //[self setTapCount:1]; + [self _setLocationInWindow:point resetPrevious:YES]; + + UIView *hitTestView = [window hitTest:point withEvent:nil]; + + [self setView:hitTestView]; + [self setPhase:UITouchPhaseBegan]; + DLog(@"initAtPoint setPhase 0"); + [self _setIsFirstTouchForView:YES]; + [self setIsTap:NO]; + [self setTimestamp:[[NSProcessInfo processInfo] systemUptime]]; + if ([self respondsToSelector:@selector(setGestureView:)]) { + [self setGestureView:hitTestView]; + } + + // Starting with iOS 9, internal IOHIDEvent must be set for UITouch object + NSOperatingSystemVersion iOS9 = {9, 0, 0}; + if ([NSProcessInfo instancesRespondToSelector:@selector(isOperatingSystemAtLeastVersion:)] && [[NSProcessInfo new] isOperatingSystemAtLeastVersion:iOS9]) { + [self kif_setHidEvent]; + } + + return self; +} + +- (void)resetTouch{ + // Create a fake tap touch + UIWindow *window = [[UIApplication sharedApplication] keyWindow]; + CGPoint point = CGPointMake(0, 0); + [self setWindow:window]; // Wipes out some values. Needs to be first. + + //[self setTapCount:1]; + [self _setLocationInWindow:CGPointMake(0, 0) resetPrevious:YES]; + + UIView *hitTestView = [window hitTest:point withEvent:nil]; + + [self setView:hitTestView]; + [self setPhase:UITouchPhaseBegan]; + //DLog(@"resetTouch setPhase 0"); + [self _setIsFirstTouchForView:YES]; + [self setIsTap:NO]; + [self setTimestamp:[[NSProcessInfo processInfo] systemUptime]]; + if ([self respondsToSelector:@selector(setGestureView:)]) { + [self setGestureView:hitTestView]; + } + + // Starting with iOS 9, internal IOHIDEvent must be set for UITouch object + NSOperatingSystemVersion iOS9 = {9, 0, 0}; + if ([NSProcessInfo instancesRespondToSelector:@selector(isOperatingSystemAtLeastVersion:)] && [[NSProcessInfo new] isOperatingSystemAtLeastVersion:iOS9]) { + [self kif_setHidEvent]; + } +} + +- (id)initTouch; +{ + //DLog(@"init...touch..."); + self = [super init]; + if (self == nil) { + return nil; + } + UIWindow *window = [UIApplication sharedApplication].keyWindow; + CGPoint point = CGPointMake(0, 0); + [self setWindow:window]; // Wipes out some values. Needs to be first. + + [self _setLocationInWindow:point resetPrevious:YES]; + + UIView *hitTestView = [window hitTest:point withEvent:nil]; + + [self setView:hitTestView]; + [self setPhase:UITouchPhaseEnded]; + //DLog(@"init...touch...setPhase 3"); + [self _setIsFirstTouchForView:YES]; + [self setIsTap:NO]; + [self setTimestamp:[[NSProcessInfo processInfo] systemUptime]]; + if ([self respondsToSelector:@selector(setGestureView:)]) { + [self setGestureView:hitTestView]; + } + + // Starting with iOS 9, internal IOHIDEvent must be set for UITouch object + NSOperatingSystemVersion iOS9 = {9, 0, 0}; + if ([NSProcessInfo instancesRespondToSelector:@selector(isOperatingSystemAtLeastVersion:)] && [[NSProcessInfo new] isOperatingSystemAtLeastVersion:iOS9]) { + [self kif_setHidEvent]; + } + return self; +} + +- (id)initAtPoint:(CGPoint)point inView:(UIView *)view; +{ + return [self initAtPoint:[view.window convertPoint:point fromView:view] inWindow:view.window]; +} + +// +// setLocationInWindow: +// +// Setter to allow access to the _locationInWindow member. +// +- (void)setLocationInWindow:(CGPoint)location +{ + [self setTimestamp:[[NSProcessInfo processInfo] systemUptime]]; + [self _setLocationInWindow:location resetPrevious:NO]; +} + +- (void)setPhaseAndUpdateTimestamp:(UITouchPhase)phase +{ + //DLog(@"setPhaseAndUpdateTimestamp : %ld",(long)phase); + [self setTimestamp:[[NSProcessInfo processInfo] systemUptime]]; + [self setPhase:phase]; +} + +- (void)kif_setHidEvent { + IOHIDEventRef event = kif_IOHIDEventWithTouches(@[self]); + [self _setHidEvent:event]; + CFRelease(event); +} + +@end diff --git a/PTFakeTouch/addition/UIView-Debugging.h b/PTFakeTouch/addition/UIView-Debugging.h new file mode 100755 index 0000000..cb7cfdf --- /dev/null +++ b/PTFakeTouch/addition/UIView-Debugging.h @@ -0,0 +1,22 @@ +// +// UIView+Debugging.h +// KIF +// +// Created by Graeme Arthur on 02/05/15. +// + +#import +#import + +@interface UIView (Debugging) +/*! + @abstract Prints the view hiererchy, starting from the top window(s), along with accessibility information, which is more related to KIF than the usual information given by the 'description' method. + */ ++(void)printViewHierarchy; + +/*! + @abstract Prints the view hiererchy, starting from this view, along with accessibility information, which is more related to KIF than the usual information given by the 'description' method. + */ +-(void)printViewHierarchy; + +@end \ No newline at end of file diff --git a/PTFakeTouch/addition/UIView-Debugging.m b/PTFakeTouch/addition/UIView-Debugging.m new file mode 100755 index 0000000..96d8600 --- /dev/null +++ b/PTFakeTouch/addition/UIView-Debugging.m @@ -0,0 +1,207 @@ +// +// UIView+Debugging.m +// KIF +// +// Created by Graeme Arthur on 02/05/15. +// + +#import "UIView-Debugging.h" + +@implementation UIView (Debugging) + ++(void)printViewHierarchy { + NSArray* windows = [UIApplication sharedApplication].windows; + if(windows.count == 1) { + [windows[0] printViewHierarchy]; + } else { + //more than one window, also print some information about each window + for (UIWindow* window in windows) { + printf("Window level %f", window.windowLevel); + if(window.isKeyWindow) printf(" (key window)"); + printf("\n"); + [window printViewHierarchy]; + printf("\n"); + } + } +} + +- (void)printViewHierarchy { + [self printViewHierarchyWithIndentation:0]; +} + +- (void)printViewHierarchyWithIndentation:(int)indent { + [self printIndentation:indent]; + [self printClassName]; + + [self printAccessibilityInfo]; + + if(self.hidden) { + printf(" (invisible)"); + } + + if([self isKindOfClass:[UIImageView class]]) { + [self printImageHighlightedState]; + } + + if([self isKindOfClass:[UIControl class]]) { + [self printControlState]; + } + printf("\n"); + + [self printAccessibilityElementsWithIndentation:indent]; + + for (UIView *subview in self.subviews) { + [subview printViewHierarchyWithIndentation:indent+1]; + } +} + +- (void)printIndentation:(int)indent { + for(int i = 0; i < indent; ++i) { + printf("|\t"); + } +} + +- (void)printClassName { + NSString* name = NSStringFromClass([self class]); + printf("%s", name.UTF8String); +} + +- (void)printAccessibilityInfo { + NSString* label = self.accessibilityLabel; + NSString* identifier = self.accessibilityIdentifier; + if(label != nil) { + printf(", label: %s", label.UTF8String); + } else if(identifier != nil) { + printf(", identifier: %s", identifier.UTF8String); + } +} + +- (void)printImageHighlightedState { + if(((UIImageView*)self).highlighted) { + printf(" (highlighted)"); + } else { + printf(" (not highlighted)"); + } +} + +- (void)printControlState { + UIControl* ctrl = (UIControl*)self; + ctrl.enabled ? printf(" (enabled)") : printf(" (not enabled)"); + ctrl.selected ? printf(" (selected)") : printf(" (not selected)"); + ctrl.highlighted ? printf(" (highlighted)") : printf(" (not highlighted)"); +} + +- (void)printAccessibilityElementsWithIndentation:(int)indent { + NSInteger numOfAccElements = self.accessibilityElementCount; + if(numOfAccElements != NSNotFound) { + for (NSInteger i = 0; i < numOfAccElements; ++i) { + [self printIndentation:indent]; + UIAccessibilityElement *e = [(UIAccessibilityElement*)self accessibilityElementAtIndex:i]; + printf("%s, label: %s", NSStringFromClass([e class]).UTF8String, e.accessibilityLabel.UTF8String); + if(e.accessibilityValue && e.accessibilityValue.length > 0) { + printf(", value: %s", e.accessibilityValue.UTF8String); + } + if(e.accessibilityHint && e.accessibilityHint.length > 0) { + printf(", hint: %s", e.accessibilityHint.UTF8String); + } + printf(", "); + [self printAccessibilityTraits:e.accessibilityTraits]; + printf("\n"); + } + } +} + +- (void)printAccessibilityTraits:(UIAccessibilityTraits)traits { + + printf("traits: "); + bool didPrintOne = false; + if(traits == UIAccessibilityTraitNone) { + printf("none"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitButton) { + if(didPrintOne) printf(", "); + printf("button"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitLink) { + if(didPrintOne) printf(", "); + printf("link"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitHeader) { + if(didPrintOne) printf(", "); + printf("header"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitSearchField) { + if(didPrintOne) printf(", "); + printf("search field"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitImage) { + if(didPrintOne) printf(", "); + printf("image"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitSelected) { + if(didPrintOne) printf(", "); + printf("selected"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitPlaysSound) { + if(didPrintOne) printf(", "); + printf("plays sound"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitKeyboardKey) { + if(didPrintOne) printf(", "); + printf("keyboard key"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitStaticText) { + if(didPrintOne) printf(", "); + printf("static text"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitSummaryElement) { + if(didPrintOne) printf(", "); + printf("summary element"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitNotEnabled) { + if(didPrintOne) printf(", "); + printf("not enabled"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitUpdatesFrequently) { + if(didPrintOne) printf(", "); + printf("updates frequently"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitStartsMediaSession) { + if(didPrintOne) printf(", "); + printf("starts media session"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitAdjustable) { + if(didPrintOne) printf(", "); + printf("adjustable"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitAllowsDirectInteraction) { + if(didPrintOne) printf(", "); + printf("allows direct interaction"); + didPrintOne = true; + } + if(traits & UIAccessibilityTraitCausesPageTurn) { + if(didPrintOne) printf(", "); + printf("causes page turn"); + didPrintOne = true; + } + if(!didPrintOne) { + printf("unknown flags (0x%llx)", traits); + } +} + +@end diff --git a/PTFakeTouch/addition/UIView-KIFAdditions.h b/PTFakeTouch/addition/UIView-KIFAdditions.h new file mode 100755 index 0000000..746fde0 --- /dev/null +++ b/PTFakeTouch/addition/UIView-KIFAdditions.h @@ -0,0 +1,118 @@ +// +// UIView-KIFAdditions.h +// KIF +// +// Created by Eric Firestone on 5/20/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import + +extern double KIFDegreesToRadians(double deg); +extern double KIFRadiansToDegrees(double rad); + +typedef CGPoint KIFDisplacement; + +@interface UIView (KIFAdditions) + +@property (nonatomic, readonly, getter=isProbablyTappable) BOOL probablyTappable; + +- (BOOL)isDescendantOfFirstResponder; +- (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label; +- (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label traits:(UIAccessibilityTraits)traits; +- (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label accessibilityValue:(NSString *)value traits:(UIAccessibilityTraits)traits; + +/*! + @method accessibilityElementMatchingBlock: + @abstract Finds the descendent accessibility element that matches the conditions defined by the match block. + @param matchBlock A block which returns YES for matching elements. + @result The matching accessibility element. + */ +- (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessibilityElement *))matchBlock; + +- (UIView *)subviewWithClassNamePrefix:(NSString *)prefix __deprecated; +- (NSArray *)subviewsWithClassNamePrefix:(NSString *)prefix; +- (UIView *)subviewWithClassNameOrSuperClassNamePrefix:(NSString *)prefix __deprecated; +- (NSArray *)subviewsWithClassNameOrSuperClassNamePrefix:(NSString *)prefix; + +- (void)flash; +- (void)tap; +- (void)tapAtPoint:(CGPoint)point; +- (void)twoFingerTapAtPoint:(CGPoint)point; +- (void)longPressAtPoint:(CGPoint)point duration:(NSTimeInterval)duration; + +/*! + @method dragFromPoint:toPoint: + @abstract Simulates dragging a finger on the screen between the given points. + @discussion Causes the application to dispatch a sequence of touch events which simulate dragging a finger from startPoint to endPoint. + @param startPoint The point at which to start the drag, in the coordinate system of the receiver. + @param endPoint The point at which to end the drag, in the coordinate system of the receiver. + */ +- (void)dragFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint; +- (void)dragFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint steps:(NSUInteger)stepCount; +- (void)dragFromPoint:(CGPoint)startPoint displacement:(KIFDisplacement)displacement steps:(NSUInteger)stepCount; +- (void)dragAlongPathWithPoints:(CGPoint *)points count:(NSInteger)count; +- (void)twoFingerPanFromPoint:(CGPoint)startPoint toPoint:(CGPoint)toPoint steps:(NSUInteger)stepCount; +- (void)pinchAtPoint:(CGPoint)centerPoint distance:(CGFloat)distance steps:(NSUInteger)stepCount; +- (void)zoomAtPoint:(CGPoint)centerPoint distance:(CGFloat)distance steps:(NSUInteger)stepCount; +- (void)twoFingerRotateAtPoint:(CGPoint)centerPoint angle:(CGFloat)angleInDegrees; +/*! + @method isTappableWithHitTestResultView: + @abstract Easy hook to override whether a hit test result makes a view tappable. + @discussion Some times, your view hierarchies involve putting overlays over views that would otherwise be tappable. Since KIF doesn't know about these exceptions, you can override this method as a convenient way of hooking in to the check for something being tappable. Your implementation will probably want to call up to super. + @param hitView The view -hitTest: returned when trying to tap on a point inside your view's bounds + @result Whether or not the view is tappable. + */ +- (BOOL)isTappableWithHitTestResultView:(UIView *)hitView; + +/*! + @method isTappableInRect: + @abstract Whether or not the receiver can be tapped inside the given rectangular area. + @discussion Determines whether or not tapping within the given rectangle would actually hit the receiver or one of its children. This is useful for determining if the view is actually on screen and enabled. + @param rect A rectangle specifying an area in the receiver in the receiver's frame coordinates. + @result Whether or not the view is tappable. + */ +- (BOOL)isTappableInRect:(CGRect)rect; + +/*! + @method tappablePointInRect:(CGRect)rect; + @abstract Finds a point in the receiver that is tappable. + @discussion Finds a tappable point in the receiver, where tappable is defined as a point that, when tapped, will hit the receiver. + @param rect A rectangle specifying an area in the receiver in the receiver's frame coordinates. + @result A tappable point in the receivers frame coordinates. + */ +- (CGPoint)tappablePointInRect:(CGRect)rect; + +- (UIEvent *)eventWithTouch:(UITouch *)touch; + +/*! + @abstract Evaluates if user interaction is enabled including edge cases. + */ +- (BOOL)isUserInteractionActuallyEnabled; + +/*! + @abstract Evaluates if the view and all its superviews are visible. + */ +- (BOOL)isVisibleInViewHierarchy; + +/*! + @method performBlockOnDescendentViews: + @abstract Calls a block on the view itself and on all its descendent views. + @param block The block that will be called on the views. Stop the traversation of the views by assigning YES to the stop-parameter of the block. + */ +- (void)performBlockOnDescendentViews:(void (^)(UIView *view, BOOL *stop))block; + +/*! + @method performBlockOnAscendentViews: + @abstract Calls a block on the view itself and on all its superviews. + @param block The block that will be called on the views. Stop the traversation of the views by assigning YES to the stop-parameter of the block. + */ +- (void)performBlockOnAscendentViews:(void (^)(UIView *view, BOOL *stop))block; + +/*! + @abstract Returns either the current window or another window if a transform is applied. Returns `nil` if all windows in the application have transforms. + */ +@property (nonatomic, readonly) UIWindow *windowOrIdentityWindow; + +@end diff --git a/PTFakeTouch/addition/UIView-KIFAdditions.m b/PTFakeTouch/addition/UIView-KIFAdditions.m new file mode 100755 index 0000000..bdde596 --- /dev/null +++ b/PTFakeTouch/addition/UIView-KIFAdditions.m @@ -0,0 +1,912 @@ +// +// UIView-KIFAdditions.m +// KIF +// +// Created by Eric Firestone on 5/20/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import "UIView-KIFAdditions.h" +#import "CGGeometry-KIFAdditions.h" +#import "UIAccessibilityElement-KIFAdditions.h" +#import "UIApplication-KIFAdditions.h" +#import "UITouch-KIFAdditions.h" +#import +#import "UIEvent+KIFAdditions.h" + +double KIFDegreesToRadians(double deg) { + return (deg) / 180.0 * M_PI; +} + +double KIFRadiansToDegrees(double rad) { + return ((rad) * (180.0 / M_PI)); +} + +static CGFloat const kTwoFingerConstantWidth = 40; + + +@interface NSObject (UIWebDocumentViewInternal) + +- (void)tapInteractionWithLocation:(CGPoint)point; + +@end + +// On iOS 6 the accessibility label may contain line breaks, so when trying to find the +// element, these line breaks are necessary. But on iOS 7 the system replaces them with +// spaces. So the same test breaks on either iOS 6 or iOS 7. iOS8 befuddles this again by +//limiting replacement to spaces in between strings. To work around this replace +// the line breaks in both and try again. +NS_INLINE BOOL StringsMatchExceptLineBreaks(NSString *expected, NSString *actual) { + if (expected == actual) { + return YES; + } + + if (expected.length != actual.length) { + return NO; + } + + if ([expected isEqualToString:actual]) { + return YES; + } + + if ([expected rangeOfString:@"\n"].location == NSNotFound && + [actual rangeOfString:@"\n"].location == NSNotFound) { + return NO; + } + + for (NSUInteger i = 0; i < expected.length; i ++) { + unichar expectedChar = [expected characterAtIndex:i]; + unichar actualChar = [actual characterAtIndex:i]; + if (expectedChar != actualChar && + !(expectedChar == '\n' && actualChar == ' ') && + !(expectedChar == ' ' && actualChar == '\n')) { + return NO; + } + } + + return YES; +} + + +@implementation UIView (KIFAdditions) + ++ (NSSet *)classesToSkipAccessibilitySearchRecursion +{ + static NSSet *classesToSkip; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // UIDatePicker contains hundreds of thousands of placeholder accessibility elements that aren't useful to KIF, + // so don't recurse into a date picker when searching for matching accessibility elements + classesToSkip = [[NSSet alloc] initWithObjects:[UIDatePicker class], nil]; + }); + + return classesToSkip; +} + +- (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label +{ + return [self accessibilityElementWithLabel:label traits:UIAccessibilityTraitNone]; +} + +- (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label traits:(UIAccessibilityTraits)traits; +{ + return [self accessibilityElementWithLabel:label accessibilityValue:nil traits:traits]; +} + +- (UIAccessibilityElement *)accessibilityElementWithLabel:(NSString *)label accessibilityValue:(NSString *)value traits:(UIAccessibilityTraits)traits; +{ + return [self accessibilityElementMatchingBlock:^(UIAccessibilityElement *element) { + + // TODO: This is a temporary fix for an SDK defect. + NSString *accessibilityValue = nil; + @try { + accessibilityValue = element.accessibilityValue; + } + @catch (NSException *exception) { + DLog(@"KIF: Unable to access accessibilityValue for element %@ because of exception: %@", element, exception.reason); + } + + if ([accessibilityValue isKindOfClass:[NSAttributedString class]]) { + accessibilityValue = [(NSAttributedString *)accessibilityValue string]; + } + + BOOL labelsMatch = StringsMatchExceptLineBreaks(label, element.accessibilityLabel); + BOOL traitsMatch = ((element.accessibilityTraits) & traits) == traits; + BOOL valuesMatch = !value || [value isEqual:accessibilityValue]; + + return (BOOL)(labelsMatch && traitsMatch && valuesMatch); + }]; +} + +- (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessibilityElement *))matchBlock; +{ + return [self accessibilityElementMatchingBlock:matchBlock notHidden:YES]; +} + +- (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessibilityElement *))matchBlock notHidden:(BOOL)notHidden; +{ + if (notHidden && self.hidden) { + return nil; + } + + // In case multiple elements with the same label exist, prefer ones that are currently visible + UIAccessibilityElement *matchingButOccludedElement = nil; + + BOOL elementMatches = matchBlock((UIAccessibilityElement *)self); + + if (elementMatches) { + if (self.isTappable) { + return (UIAccessibilityElement *)self; + } else { + matchingButOccludedElement = (UIAccessibilityElement *)self; + } + } + + if ([[[self class] classesToSkipAccessibilitySearchRecursion] containsObject:[self class]]) { + return matchingButOccludedElement; + } + + // Check the subviews first. Even if the receiver says it's an accessibility container, + // the returned objects are UIAccessibilityElementMockViews (which aren't actually views) + // rather than the real subviews it contains. We want the real views if possible. + // UITableViewCell is such an offender. + for (UIView *view in [self.subviews reverseObjectEnumerator]) { + UIAccessibilityElement *element = [view accessibilityElementMatchingBlock:matchBlock]; + if (!element) { + continue; + } + + UIView *viewForElement = [UIAccessibilityElement viewContainingAccessibilityElement:element]; + CGRect accessibilityFrame = [viewForElement.window convertRect:element.accessibilityFrame toView:viewForElement]; + + if ([viewForElement isTappableInRect:accessibilityFrame]) { + return element; + } else { + matchingButOccludedElement = element; + } + } + + NSMutableArray *elementStack = [NSMutableArray arrayWithObject:self]; + + while (elementStack.count) { + UIAccessibilityElement *element = [elementStack lastObject]; + [elementStack removeLastObject]; + + BOOL elementMatches = matchBlock(element); + + if (elementMatches) { + UIView *viewForElement = [UIAccessibilityElement viewContainingAccessibilityElement:element]; + CGRect accessibilityFrame = [viewForElement.window convertRect:element.accessibilityFrame toView:viewForElement]; + + if ([viewForElement isTappableInRect:accessibilityFrame]) { + return element; + } else { + matchingButOccludedElement = element; + continue; + } + } + + // If the view is an accessibility container, and we didn't find a matching subview, + // then check the actual accessibility elements + NSInteger accessibilityElementCount = element.accessibilityElementCount; + if (accessibilityElementCount == 0 || accessibilityElementCount == NSNotFound) { + continue; + } + + for (NSInteger accessibilityElementIndex = 0; accessibilityElementIndex < accessibilityElementCount; accessibilityElementIndex++) { + UIAccessibilityElement *subelement = [element accessibilityElementAtIndex:accessibilityElementIndex]; + + if (subelement) { + // Skip table view cell accessibility elements, they're handled below + if ([subelement isKindOfClass:NSClassFromString(@"UITableViewCellAccessibilityElement")]) { + continue; + } + + [elementStack addObject:subelement]; + } + } + } + + if (!matchingButOccludedElement) { + if ([self isKindOfClass:[UITableView class]]) { + UITableView *tableView = (UITableView *)self; + + // Because of a bug in [UITableView indexPathsForVisibleRows] http://openradar.appspot.com/radar?id=5191284490764288 + // We use [UITableView visibleCells] to determine the index path of the visible cells + NSMutableArray *indexPathsForVisibleRows = [[NSMutableArray alloc] init]; + [[tableView visibleCells] enumerateObjectsUsingBlock:^(UITableViewCell *cell, NSUInteger idx, BOOL *stop) { + NSIndexPath *indexPath = [tableView indexPathForCell:cell]; + if (indexPath) { + [indexPathsForVisibleRows addObject:indexPath]; + } + }]; + + for (NSUInteger section = 0, numberOfSections = [tableView numberOfSections]; section < numberOfSections; section++) { + for (NSUInteger row = 0, numberOfRows = [tableView numberOfRowsInSection:section]; row < numberOfRows; row++) { + // Skip visible rows because they are already handled + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section]; + if ([indexPathsForVisibleRows containsObject:indexPath]) { + continue; + } + + @autoreleasepool { + // Get the cell directly from the dataSource because UITableView will only vend visible cells + UITableViewCell *cell = [tableView.dataSource tableView:tableView cellForRowAtIndexPath:indexPath]; + + UIAccessibilityElement *element = [cell accessibilityElementMatchingBlock:matchBlock notHidden:NO]; + + // Remove the cell from the table view so that it doesn't stick around + [cell removeFromSuperview]; + + // Skip this cell if it isn't the one we're looking for + if (!element) { + continue; + } + } + + // Scroll to the cell and wait for the animation to complete + [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES]; + CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.5, false); + + // Now try finding the element again + return [self accessibilityElementMatchingBlock:matchBlock]; + } + } + } else if ([self isKindOfClass:[UICollectionView class]]) { + UICollectionView *collectionView = (UICollectionView *)self; + + NSArray *indexPathsForVisibleItems = [collectionView indexPathsForVisibleItems]; + + for (NSUInteger section = 0, numberOfSections = [collectionView numberOfSections]; section < numberOfSections; section++) { + for (NSUInteger item = 0, numberOfItems = [collectionView numberOfItemsInSection:section]; item < numberOfItems; item++) { + // Skip visible items because they are already handled + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; + if ([indexPathsForVisibleItems containsObject:indexPath]) { + continue; + } + + @autoreleasepool { + // Get the cell directly from the dataSource because UICollectionView will only vend visible cells + UICollectionViewCell *cell = [collectionView.dataSource collectionView:collectionView cellForItemAtIndexPath:indexPath]; + + UIAccessibilityElement *element = [cell accessibilityElementMatchingBlock:matchBlock notHidden:NO]; + + // Remove the cell from the collection view so that it doesn't stick around + [cell removeFromSuperview]; + + // Skip this cell if it isn't the one we're looking for + // Sometimes we get cells with no size here which can cause an endless loop, so we ignore those + if (!element || CGSizeEqualToSize(cell.frame.size, CGSizeZero)) { + continue; + } + } + + // Scroll to the cell and wait for the animation to complete + [collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionNone animated:YES]; + CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.5, false); + + // Now try finding the element again + return [self accessibilityElementMatchingBlock:matchBlock]; + } + } + } + } + + return matchingButOccludedElement; +} + +- (UIView *)subviewWithClassNamePrefix:(NSString *)prefix; +{ + NSArray *subviews = [self subviewsWithClassNamePrefix:prefix]; + if ([subviews count] == 0) { + return nil; + } + + return subviews[0]; +} + +- (NSArray *)subviewsWithClassNamePrefix:(NSString *)prefix; +{ + NSMutableArray *result = [NSMutableArray array]; + + // Breadth-first population of matching subviews + // First traverse the next level of subviews, adding matches. + for (UIView *view in self.subviews) { + if ([NSStringFromClass([view class]) hasPrefix:prefix]) { + [result addObject:view]; + } + } + + // Now traverse the subviews of the subviews, adding matches. + for (UIView *view in self.subviews) { + NSArray *matchingSubviews = [view subviewsWithClassNamePrefix:prefix]; + [result addObjectsFromArray:matchingSubviews]; + } + + return result; +} + +- (UIView *)subviewWithClassNameOrSuperClassNamePrefix:(NSString *)prefix; +{ + NSArray *subviews = [self subviewsWithClassNameOrSuperClassNamePrefix:prefix]; + if ([subviews count] == 0) { + return nil; + } + + return subviews[0]; +} + +- (NSArray *)subviewsWithClassNameOrSuperClassNamePrefix:(NSString *)prefix; +{ + NSMutableArray * result = [NSMutableArray array]; + + // Breadth-first population of matching subviews + // First traverse the next level of subviews, adding matches + for (UIView *view in self.subviews) { + Class klass = [view class]; + while (klass) { + if ([NSStringFromClass(klass) hasPrefix:prefix]) { + [result addObject:view]; + break; + } + + klass = [klass superclass]; + } + } + + // Now traverse the subviews of the subviews, adding matches + for (UIView *view in self.subviews) { + NSArray * matchingSubviews = [view subviewsWithClassNameOrSuperClassNamePrefix:prefix]; + [result addObjectsFromArray:matchingSubviews]; + } + + return result; +} + + +- (BOOL)isDescendantOfFirstResponder; +{ + if ([self isFirstResponder]) { + return YES; + } + return [self.superview isDescendantOfFirstResponder]; +} + +- (void)flash; +{ + UIColor *originalBackgroundColor = self.backgroundColor; + for (NSUInteger i = 0; i < 5; i++) { + self.backgroundColor = [UIColor yellowColor]; + CFRunLoopRunInMode(kCFRunLoopDefaultMode, .05, false); + self.backgroundColor = [UIColor blueColor]; + CFRunLoopRunInMode(kCFRunLoopDefaultMode, .05, false); + } + self.backgroundColor = originalBackgroundColor; +} + +- (void)tap; +{ + CGPoint centerPoint = CGPointMake(self.frame.size.width * 0.5f, self.frame.size.height * 0.5f); + + [self tapAtPoint:centerPoint]; +} + +- (void)tapAtPoint:(CGPoint)point; +{ + // Web views don't handle touches in a normal fashion, but they do have a method we can call to tap them + // This may not be necessary anymore. We didn't properly support controls that used gesture recognizers + // when this was added, but we now do. It needs to be tested before we can get rid of it. + id /*UIWebBrowserView*/ webBrowserView = nil; + + if ([NSStringFromClass([self class]) isEqual:@"UIWebBrowserView"]) { + webBrowserView = self; + } else if ([self isKindOfClass:[UIWebView class]]) { + id webViewInternal = [self valueForKey:@"_internal"]; + webBrowserView = [webViewInternal valueForKey:@"browserView"]; + } + + if (webBrowserView) { + [webBrowserView tapInteractionWithLocation:point]; + return; + } + + // Handle touches in the normal way for other views + UITouch *touch = [[UITouch alloc] initAtPoint:point inView:self]; + [touch setPhaseAndUpdateTimestamp:UITouchPhaseBegan]; + + UIEvent *event = [self eventWithTouch:touch]; + + [[UIApplication sharedApplication] sendEvent:event]; + + [touch setPhaseAndUpdateTimestamp:UITouchPhaseEnded]; + [[UIApplication sharedApplication] sendEvent:event]; + + // Dispatching the event doesn't actually update the first responder, so fake it + if ([touch.view isDescendantOfView:self] && [self canBecomeFirstResponder]) { + [self becomeFirstResponder]; + } + +} + +- (void)twoFingerTapAtPoint:(CGPoint)point { + CGPoint finger1 = CGPointMake(point.x - kTwoFingerConstantWidth, point.y - kTwoFingerConstantWidth); + CGPoint finger2 = CGPointMake(point.x + kTwoFingerConstantWidth, point.y + kTwoFingerConstantWidth); + UITouch *touch1 = [[UITouch alloc] initAtPoint:finger1 inView:self]; + UITouch *touch2 = [[UITouch alloc] initAtPoint:finger2 inView:self]; + [touch1 setPhaseAndUpdateTimestamp:UITouchPhaseBegan]; + [touch2 setPhaseAndUpdateTimestamp:UITouchPhaseBegan]; + + UIEvent *event = [self eventWithTouches:@[touch1, touch2]]; + [[UIApplication sharedApplication] sendEvent:event]; + + [touch1 setPhaseAndUpdateTimestamp:UITouchPhaseEnded]; + [touch2 setPhaseAndUpdateTimestamp:UITouchPhaseEnded]; + + [[UIApplication sharedApplication] sendEvent:event]; +} + +#define DRAG_TOUCH_DELAY 0.01 + +- (void)longPressAtPoint:(CGPoint)point duration:(NSTimeInterval)duration +{ + UITouch *touch = [[UITouch alloc] initAtPoint:point inView:self]; + [touch setPhaseAndUpdateTimestamp:UITouchPhaseBegan]; + + UIEvent *eventDown = [self eventWithTouch:touch]; + [[UIApplication sharedApplication] sendEvent:eventDown]; + + CFRunLoopRunInMode(kCFRunLoopDefaultMode, DRAG_TOUCH_DELAY, false); + + for (NSTimeInterval timeSpent = DRAG_TOUCH_DELAY; timeSpent < duration; timeSpent += DRAG_TOUCH_DELAY) + { + [touch setPhaseAndUpdateTimestamp:UITouchPhaseStationary]; + + UIEvent *eventStillDown = [self eventWithTouch:touch]; + [[UIApplication sharedApplication] sendEvent:eventStillDown]; + + CFRunLoopRunInMode(kCFRunLoopDefaultMode, DRAG_TOUCH_DELAY, false); + } + + [touch setPhaseAndUpdateTimestamp:UITouchPhaseEnded]; + UIEvent *eventUp = [self eventWithTouch:touch]; + [[UIApplication sharedApplication] sendEvent:eventUp]; + + // Dispatching the event doesn't actually update the first responder, so fake it + if ([touch.view isDescendantOfView:self] && [self canBecomeFirstResponder]) { + [self becomeFirstResponder]; + } + +} + +- (void)dragFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint; +{ + [self dragFromPoint:startPoint toPoint:endPoint steps:3]; +} + + +- (void)dragFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint steps:(NSUInteger)stepCount; +{ + KIFDisplacement displacement = CGPointMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y); + [self dragFromPoint:startPoint displacement:displacement steps:stepCount]; +} + +- (void)dragFromPoint:(CGPoint)startPoint displacement:(KIFDisplacement)displacement steps:(NSUInteger)stepCount; +{ + CGPoint endPoint = CGPointMake(startPoint.x + displacement.x, startPoint.y + displacement.y); + NSArray *path = [self pointsFromStartPoint:startPoint toPoint:endPoint steps:stepCount]; + [self dragPointsAlongPaths:@[path]]; +} + +- (void)dragAlongPathWithPoints:(CGPoint *)points count:(NSInteger)count; +{ + // convert point array into NSArray with NSValue + NSMutableArray *array = [NSMutableArray array]; + for (int i = 0; i < count; i++) + { + [array addObject:[NSValue valueWithCGPoint:points[i]]]; + } + [self dragPointsAlongPaths:@[[array copy]]]; +} + +- (void)dragPointsAlongPaths:(NSArray *)arrayOfPaths { + // must have at least one path, and each path must have the same number of points + if (arrayOfPaths.count == 0) + { + return; + } + + // all paths must have similar number of points + NSUInteger pointsInPath = [arrayOfPaths[0] count]; + for (NSArray *path in arrayOfPaths) + { + if (path.count != pointsInPath) + { + return; + } + } + + NSMutableArray *touches = [NSMutableArray array]; + + for (NSUInteger pointIndex = 0; pointIndex < pointsInPath; pointIndex++) { + // create initial touch event and send touch down event + if (pointIndex == 0) + { + for (NSArray *path in arrayOfPaths) + { + CGPoint point = [path[pointIndex] CGPointValue]; + UITouch *touch = [[UITouch alloc] initAtPoint:point inView:self]; + [touch setPhaseAndUpdateTimestamp:UITouchPhaseBegan]; + [touches addObject:touch]; + } + UIEvent *eventDown = [self eventWithTouches:[NSArray arrayWithArray:touches]]; + [[UIApplication sharedApplication] sendEvent:eventDown]; + + CFRunLoopRunInMode(UIApplicationCurrentRunMode, DRAG_TOUCH_DELAY, false); + } + else + { + UITouch *touch; + for (NSUInteger pathIndex = 0; pathIndex < arrayOfPaths.count; pathIndex++) + { + NSArray *path = arrayOfPaths[pathIndex]; + CGPoint point = [path[pointIndex] CGPointValue]; + touch = touches[pathIndex]; + [touch setLocationInWindow:[self.window convertPoint:point fromView:self]]; + [touch setPhaseAndUpdateTimestamp:UITouchPhaseMoved]; + } + UIEvent *event = [self eventWithTouches:[NSArray arrayWithArray:touches]]; + [[UIApplication sharedApplication] sendEvent:event]; + + CFRunLoopRunInMode(UIApplicationCurrentRunMode, DRAG_TOUCH_DELAY, false); + + // The last point needs to also send a phase ended touch. + if (pointIndex == pointsInPath - 1) { + for (UITouch * touch in touches) { + [touch setPhaseAndUpdateTimestamp:UITouchPhaseEnded]; + UIEvent *eventUp = [self eventWithTouch:touch]; + [[UIApplication sharedApplication] sendEvent:eventUp]; + + } + + } + } + } + + // Dispatching the event doesn't actually update the first responder, so fake it + if ([touches[0] view] == self && [self canBecomeFirstResponder]) { + [self becomeFirstResponder]; + } + + while (UIApplicationCurrentRunMode != kCFRunLoopDefaultMode) { + CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.1, false); + } +} + +- (void)twoFingerPanFromPoint:(CGPoint)startPoint toPoint:(CGPoint)toPoint steps:(NSUInteger)stepCount { + //estimate the first finger to be diagonally up and left from the center + CGPoint finger1Start = CGPointMake(startPoint.x - kTwoFingerConstantWidth, + startPoint.y - kTwoFingerConstantWidth); + CGPoint finger1End = CGPointMake(toPoint.x - kTwoFingerConstantWidth, + toPoint.y - kTwoFingerConstantWidth); + //estimate the second finger to be diagonally down and right from the center + CGPoint finger2Start = CGPointMake(startPoint.x + kTwoFingerConstantWidth, + startPoint.y + kTwoFingerConstantWidth); + CGPoint finger2End = CGPointMake(toPoint.x + kTwoFingerConstantWidth, + toPoint.y + kTwoFingerConstantWidth); + NSArray *finger1Path = [self pointsFromStartPoint:finger1Start toPoint:finger1End steps:stepCount]; + NSArray *finger2Path = [self pointsFromStartPoint:finger2Start toPoint:finger2End steps:stepCount]; + NSArray *paths = @[finger1Path, finger2Path]; + + [self dragPointsAlongPaths:paths]; +} + +- (void)pinchAtPoint:(CGPoint)centerPoint distance:(CGFloat)distance steps:(NSUInteger)stepCount { + //estimate the first finger to be on the left + CGPoint finger1Start = CGPointMake(centerPoint.x - kTwoFingerConstantWidth - distance, centerPoint.y); + CGPoint finger1End = CGPointMake(centerPoint.x - kTwoFingerConstantWidth, centerPoint.y); + //estimate the second finger to be on the right + CGPoint finger2Start = CGPointMake(centerPoint.x + kTwoFingerConstantWidth + distance, centerPoint.y); + CGPoint finger2End = CGPointMake(centerPoint.x + kTwoFingerConstantWidth, centerPoint.y); + NSArray *finger1Path = [self pointsFromStartPoint:finger1Start toPoint:finger1End steps:stepCount]; + NSArray *finger2Path = [self pointsFromStartPoint:finger2Start toPoint:finger2End steps:stepCount]; + NSArray *paths = @[finger1Path, finger2Path]; + + [self dragPointsAlongPaths:paths]; +} + +- (void)zoomAtPoint:(CGPoint)centerPoint distance:(CGFloat)distance steps:(NSUInteger)stepCount { + //estimate the first finger to be on the left + CGPoint finger1Start = CGPointMake(centerPoint.x - kTwoFingerConstantWidth, centerPoint.y); + CGPoint finger1End = CGPointMake(centerPoint.x - kTwoFingerConstantWidth - distance, centerPoint.y); + //estimate the second finger to be on the right + CGPoint finger2Start = CGPointMake(centerPoint.x + kTwoFingerConstantWidth, centerPoint.y); + CGPoint finger2End = CGPointMake(centerPoint.x + kTwoFingerConstantWidth + distance, centerPoint.y); + NSArray *finger1Path = [self pointsFromStartPoint:finger1Start toPoint:finger1End steps:stepCount]; + NSArray *finger2Path = [self pointsFromStartPoint:finger2Start toPoint:finger2End steps:stepCount]; + NSArray *paths = @[finger1Path, finger2Path]; + + [self dragPointsAlongPaths:paths]; +} + +- (void)twoFingerRotateAtPoint:(CGPoint)centerPoint angle:(CGFloat)angleInDegrees { + NSInteger stepCount = ABS(angleInDegrees)/2; // very rough approximation. 90deg = ~45 steps, 360 deg = ~180 steps + CGFloat radius = kTwoFingerConstantWidth*2; + double angleInRadians = KIFDegreesToRadians(angleInDegrees); + + NSMutableArray *finger1Path = [NSMutableArray array]; + NSMutableArray *finger2Path = [NSMutableArray array]; + for (NSUInteger i = 0; i < stepCount; i++) { + double currentAngle = 0; + if (i == stepCount - 1) { + currentAngle = angleInRadians; // do not interpolate for the last step for maximum accuracy + } + else { + double interpolation = i/(double)stepCount; + currentAngle = interpolation * angleInRadians; + } + // interpolate betwen 0 and the target rotation + CGPoint offset1 = CGPointMake(radius * cos(currentAngle), radius * sin(currentAngle)); + CGPoint offset2 = CGPointMake(-offset1.x, -offset1.y); // second finger is just opposite of the first + + CGPoint finger1 = CGPointMake(centerPoint.x + offset1.x, centerPoint.y + offset1.y); + CGPoint finger2 = CGPointMake(centerPoint.x + offset2.x, centerPoint.y + offset2.y); + + [finger1Path addObject:[NSValue valueWithCGPoint:finger1]]; + [finger2Path addObject:[NSValue valueWithCGPoint:finger2]]; + } + [self dragPointsAlongPaths:@[[finger1Path copy], [finger2Path copy]]]; +} + +- (NSArray *)pointsFromStartPoint:(CGPoint)startPoint toPoint:(CGPoint)toPoint steps:(NSUInteger)stepCount { + + CGPoint displacement = CGPointMake(toPoint.x - startPoint.x, toPoint.y - startPoint.y); + NSMutableArray *points = [NSMutableArray array]; + + for (NSUInteger i = 0; i < stepCount; i++) { + CGFloat progress = ((CGFloat)i)/(stepCount - 1); + CGPoint point = CGPointMake(startPoint.x + (progress * displacement.x), + startPoint.y + (progress * displacement.y)); + [points addObject:[NSValue valueWithCGPoint:point]]; + } + return [NSArray arrayWithArray:points]; +} + +- (BOOL)isProbablyTappable +{ + // There are some issues with the tappability check in UIWebViews, so if the view is a UIWebView we will just skip the check. + return [NSStringFromClass([self class]) isEqualToString:@"UIWebBrowserView"] || self.isTappable; +} + +// Is this view currently on screen? +- (BOOL)isTappable; +{ + return ([self hasTapGestureRecognizer] || + [self isTappableInRect:self.bounds]); +} + +- (BOOL)hasTapGestureRecognizer +{ + __block BOOL hasTapGestureRecognizer = NO; + + [self.gestureRecognizers enumerateObjectsUsingBlock:^(id obj, + NSUInteger idx, + BOOL *stop) { + if ([obj isKindOfClass:[UITapGestureRecognizer class]]) { + hasTapGestureRecognizer = YES; + + if (stop != NULL) { + *stop = YES; + } + } + }]; + + return hasTapGestureRecognizer; +} + +- (BOOL)isTappableInRect:(CGRect)rect; +{ + CGPoint tappablePoint = [self tappablePointInRect:rect]; + + return !isnan(tappablePoint.x); +} + +- (BOOL)isTappableWithHitTestResultView:(UIView *)hitView; +{ + // Special case for UIControls, which may have subviews which don't respond to -hitTest:, + // but which are tappable. In this case the hit view will be the containing + // UIControl, and it will forward the tap to the appropriate subview. + // This applies with UISegmentedControl which contains UISegment views (a private UIView + // representing a single segment). + if ([hitView isKindOfClass:[UIControl class]] && [self isDescendantOfView:hitView]) { + return YES; + } + + // Button views in the nav bar (a private class derived from UINavigationItemView), do not return + // themselves in a -hitTest:. Instead they return the nav bar. + if ([hitView isKindOfClass:[UINavigationBar class]] && [self isNavigationItemView] && [self isDescendantOfView:hitView]) { + return YES; + } + + return [hitView isDescendantOfView:self]; +} + +- (CGPoint)tappablePointInRect:(CGRect)rect; +{ + // Start at the top and recurse down + CGRect frame = [self.window convertRect:rect fromView:self]; + + UIView *hitView = nil; + CGPoint tapPoint = CGPointZero; + + // Mid point + tapPoint = CGPointCenteredInRect(frame); + hitView = [self.window hitTest:tapPoint withEvent:nil]; + if ([self isTappableWithHitTestResultView:hitView]) { + return [self.window convertPoint:tapPoint toView:self]; + } + + // Top left + tapPoint = CGPointMake(frame.origin.x + 1.0f, frame.origin.y + 1.0f); + hitView = [self.window hitTest:tapPoint withEvent:nil]; + if ([self isTappableWithHitTestResultView:hitView]) { + return [self.window convertPoint:tapPoint toView:self]; + } + + // Top right + tapPoint = CGPointMake(frame.origin.x + frame.size.width - 1.0f, frame.origin.y + 1.0f); + hitView = [self.window hitTest:tapPoint withEvent:nil]; + if ([self isTappableWithHitTestResultView:hitView]) { + return [self.window convertPoint:tapPoint toView:self]; + } + + // Bottom left + tapPoint = CGPointMake(frame.origin.x + 1.0f, frame.origin.y + frame.size.height - 1.0f); + hitView = [self.window hitTest:tapPoint withEvent:nil]; + if ([self isTappableWithHitTestResultView:hitView]) { + return [self.window convertPoint:tapPoint toView:self]; + } + + // Bottom right + tapPoint = CGPointMake(frame.origin.x + frame.size.width - 1.0f, frame.origin.y + frame.size.height - 1.0f); + hitView = [self.window hitTest:tapPoint withEvent:nil]; + if ([self isTappableWithHitTestResultView:hitView]) { + return [self.window convertPoint:tapPoint toView:self]; + } + + return CGPointMake(NAN, NAN); +} + +- (UIEvent *)eventWithTouches:(NSArray *)touches +{ + // _touchesEvent is a private selector, interface is exposed in UIApplication(KIFAdditionsPrivate) + UIEvent *event = [[UIApplication sharedApplication] _touchesEvent]; + + [event _clearTouches]; + [event kif_setEventWithTouches:touches]; + + for (UITouch *aTouch in touches) { + [event _addTouch:aTouch forDelayedDelivery:NO]; + } + + return event; +} + +- (UIEvent *)eventWithTouch:(UITouch *)touch; +{ + NSArray *touches = touch ? @[touch] : nil; + return [self eventWithTouches:touches]; +} + +- (BOOL)isUserInteractionActuallyEnabled; +{ + BOOL isUserInteractionEnabled = self.userInteractionEnabled; + + // Navigation item views don't have user interaction enabled, but their parent nav bar does and will forward the event + if (!isUserInteractionEnabled && [self isNavigationItemView]) { + // If this view is inside a nav bar, and the nav bar is enabled, then consider it enabled + UIView *navBar = [self superview]; + while (navBar && ![navBar isKindOfClass:[UINavigationBar class]]) { + navBar = [navBar superview]; + } + if (navBar && navBar.userInteractionEnabled) { + isUserInteractionEnabled = YES; + } + } + + // UIActionsheet Buttons have UIButtonLabels with userInteractionEnabled=NO inside, + // grab the superview UINavigationButton instead. + if (!isUserInteractionEnabled && [self isKindOfClass:NSClassFromString(@"UIButtonLabel")]) { + UIView *button = [self superview]; + while (button && ![button isKindOfClass:NSClassFromString(@"UINavigationButton")]) { + button = [button superview]; + } + if (button && button.userInteractionEnabled) { + isUserInteractionEnabled = YES; + } + } + + // Somtimes views are inside a UIControl and don't have user interaction enabled. + // Walk up the hierarchary evaluating the parent UIControl subclass and use that instead. + if (!isUserInteractionEnabled && [self.superview isKindOfClass:[UIControl class]]) { + // If this view is inside a UIControl, and it is enabled, then consider the view enabled + UIControl *control = (UIControl *)[self superview]; + while (control && [control isKindOfClass:[UIControl class]]) { + if (control.isUserInteractionEnabled) { + isUserInteractionEnabled = YES; + break; + } + control = (UIControl *)[control superview]; + } + } + + return isUserInteractionEnabled; +} + +- (BOOL)isNavigationItemView; +{ + return [self isKindOfClass:NSClassFromString(@"UINavigationItemView")] || [self isKindOfClass:NSClassFromString(@"_UINavigationBarBackIndicatorView")]; +} + +- (UIWindow *)windowOrIdentityWindow +{ + if (CGAffineTransformIsIdentity(self.window.transform)) { + return self.window; + } + + for (UIWindow *window in [[UIApplication sharedApplication] windowsWithKeyWindow]) { + if (CGAffineTransformIsIdentity(window.transform)) { + return window; + } + } + + return nil; +} + +- (BOOL)isVisibleInViewHierarchy +{ + __block BOOL result = YES; + [self performBlockOnAscendentViews:^(UIView *view, BOOL *stop) { + if (view.isHidden) { + result = NO; + if (stop != NULL) { + *stop = YES; + } + } + }]; + return result; +} + +- (void)performBlockOnDescendentViews:(void (^)(UIView *view, BOOL *stop))block +{ + BOOL stop = NO; + [self performBlockOnDescendentViews:block stop:&stop]; +} + +- (void)performBlockOnDescendentViews:(void (^)(UIView *view, BOOL *stop))block stop:(BOOL *)stop +{ + block(self, stop); + if (*stop) { + return; + } + + for (UIView *view in self.subviews) { + [view performBlockOnDescendentViews:block stop:stop]; + if (*stop) { + return; + } + } +} + +- (void)performBlockOnAscendentViews:(void (^)(UIView *view, BOOL *stop))block +{ + BOOL stop = NO; + UIView *checkedView = self; + while(checkedView && stop == NO) { + block(checkedView, &stop); + checkedView = checkedView.superview; + } +} + + +@end diff --git a/PTFakeTouch/addition/UIWindow-KIFAdditions.h b/PTFakeTouch/addition/UIWindow-KIFAdditions.h new file mode 100755 index 0000000..64c9b2c --- /dev/null +++ b/PTFakeTouch/addition/UIWindow-KIFAdditions.h @@ -0,0 +1,17 @@ +// +// UIWindow-KIFAdditions.h +// KIF +// +// Created by Eric Firestone on 5/20/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import + + +@interface UIWindow (KIFAdditions) + +- (UIResponder *)firstResponder; + +@end diff --git a/PTFakeTouch/addition/UIWindow-KIFAdditions.m b/PTFakeTouch/addition/UIWindow-KIFAdditions.m new file mode 100755 index 0000000..893b49e --- /dev/null +++ b/PTFakeTouch/addition/UIWindow-KIFAdditions.m @@ -0,0 +1,15 @@ +// +// UIWindow-KIFAdditions.m +// KIF +// +// Created by Eric Firestone on 5/20/11. +// Licensed to Square, Inc. under one or more contributor license agreements. +// See the LICENSE file distributed with this work for the terms under +// which Square, Inc. licenses this file to you. + +#import "UIWindow-KIFAdditions.h" + + +//@implementation UIWindow (KIFAdditions) +// +//@end diff --git a/PTFakeTouch/addition/XCTestCase-KIFAdditions.h b/PTFakeTouch/addition/XCTestCase-KIFAdditions.h new file mode 100755 index 0000000..64f966c --- /dev/null +++ b/PTFakeTouch/addition/XCTestCase-KIFAdditions.h @@ -0,0 +1,14 @@ +// +// XCTestCase-KIFAdditions.h +// KIF +// +// Created by Tony DiPasquale on 12/9/13. +// +// + +#import +#import "KIFTestActor.h" + +@interface XCTestCase (KIFAdditions) + +@end diff --git a/PTFakeTouch/addition/XCTestCase-KIFAdditions.m b/PTFakeTouch/addition/XCTestCase-KIFAdditions.m new file mode 100755 index 0000000..01e8aff --- /dev/null +++ b/PTFakeTouch/addition/XCTestCase-KIFAdditions.m @@ -0,0 +1,94 @@ +// +// XCTestCase-KIFAdditions.m +// KIF +// +// Created by Tony DiPasquale on 12/9/13. +// +// + +#import "XCTestCase-KIFAdditions.h" +#import "LoadableCategory.h" +#import "UIApplication-KIFAdditions.h" +#import + +MAKE_CATEGORIES_LOADABLE(TestCase_KIFAdditions) + +static inline void Swizzle(Class c, SEL orig, SEL new) +{ + Method origMethod = class_getInstanceMethod(c, orig); + Method newMethod = class_getInstanceMethod(c, new); + if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) + class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); + else + method_exchangeImplementations(origMethod, newMethod); +} + +@interface XCTestCase () +- (void)_recordUnexpectedFailureWithDescription:(id)arg1 exception:(id)arg2; +@end + +@implementation XCTestCase (KIFAdditions) + +- (void)failWithException:(NSException *)exception stopTest:(BOOL)stop +{ + self.continueAfterFailure = YES; + + [self recordFailureWithDescription:exception.description inFile:exception.userInfo[@"FilenameKey"] atLine:[exception.userInfo[@"LineNumberKey"] unsignedIntegerValue] expected:NO]; + + if (stop) { + [self writeScreenshotForException:exception]; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Swizzle([XCTestCase class], @selector(_recordUnexpectedFailureWithDescription:exception:), @selector(KIF_recordUnexpectedFailureWithDescription:exception:)); + }); + [exception raise]; + } +} + +- (void)failWithExceptions:(NSArray *)exceptions stopTest:(BOOL)stop +{ + NSException *lastException = exceptions.lastObject; + for (NSException *exception in exceptions) { + [self failWithException:exception stopTest:(exception == lastException ? stop : NO)]; + } +} + +- (void)KIF_recordUnexpectedFailureWithDescription:(id)arg1 exception:(NSException *)arg2 +{ + if (![[arg2 name] isEqualToString:@"KIFFailureException"]) { + [self KIF_recordUnexpectedFailureWithDescription:arg1 exception:arg2]; + } +} + +- (void)writeScreenshotForException:(NSException *)exception; +{ + [[UIApplication sharedApplication] writeScreenshotForLine:[exception.userInfo[@"LineNumberKey"] unsignedIntegerValue] inFile:exception.userInfo[@"FilenameKey"] description:nil error:NULL]; +} + +@end + +#ifdef __IPHONE_8_0 + +@interface XCTestSuite () +- (void)_recordUnexpectedFailureForTestRun:(id)arg1 description:(id)arg2 exception:(id)arg3; +@end + +@implementation XCTestSuite (KIFAdditions) + ++ (void)load +{ + Swizzle([XCTestSuite class], @selector(_recordUnexpectedFailureForTestRun:description:exception:), @selector(KIF_recordUnexpectedFailureForTestRun:description:exception:)); +} + +- (void)KIF_recordUnexpectedFailureForTestRun:(XCTestSuiteRun *)arg1 description:(id)arg2 exception:(NSException *)arg3 +{ + if (![[arg3 name] isEqualToString:@"KIFFailureException"]) { + [self KIF_recordUnexpectedFailureForTestRun:arg1 description:arg2 exception:arg3]; + } else { + [arg1 recordFailureWithDescription:[NSString stringWithFormat:@"Test suite stopped on fatal error: %@", arg3.description] inFile:arg3.userInfo[@"FilenameKey"] atLine:[arg3.userInfo[@"LineNumberKey"] unsignedIntegerValue] expected:NO]; + } +} + +@end + +#endif diff --git a/PTFakeTouchTests/Info.plist b/PTFakeTouchTests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/PTFakeTouchTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/PTFakeTouchTests/PTFakeTouchTests.m b/PTFakeTouchTests/PTFakeTouchTests.m new file mode 100644 index 0000000..8e9335b --- /dev/null +++ b/PTFakeTouchTests/PTFakeTouchTests.m @@ -0,0 +1,39 @@ +// +// PTFakeTouchTests.m +// PTFakeTouchTests +// +// Created by tangxuan on 16/8/15. +// Copyright © 2016年 tangxuan. All rights reserved. +// + +#import + +@interface PTFakeTouchTests : XCTestCase + +@end + +@implementation PTFakeTouchTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end