Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration for haptic manager into the SMM #753

Merged
merged 5 commits into from
Oct 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions SmartDeviceLink-iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,6 @@
1680B11C1A9CD7AD00DBD79E /* SDLProtocolMessageAssemblerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1680B1101A9CD7AD00DBD79E /* SDLProtocolMessageAssemblerSpec.m */; };
1680B11D1A9CD7AD00DBD79E /* SDLProtocolMessageDisassemblerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1680B1111A9CD7AD00DBD79E /* SDLProtocolMessageDisassemblerSpec.m */; };
1680B11E1A9CD7AD00DBD79E /* SDLProtocolReceivedMessageRouterSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1680B1121A9CD7AD00DBD79E /* SDLProtocolReceivedMessageRouterSpec.m */; };
1FF7DAB61F75B27300B46C30 /* SDLHapticInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF7DAB51F75B27300B46C30 /* SDLHapticInterface.h */; };
1FF7DAB81F75B28E00B46C30 /* SDLHapticHitTester.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF7DAB71F75B28E00B46C30 /* SDLHapticHitTester.h */; };
1FF7DABA1F75B2A800B46C30 /* SDLHapticManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF7DAB91F75B2A800B46C30 /* SDLHapticManager.h */; };
1FF7DABC1F75B2BF00B46C30 /* SDLHapticManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF7DABB1F75B2BF00B46C30 /* SDLHapticManager.m */; };
1FF7DAC01F75CF6C00B46C30 /* SDLHapticManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF7DABF1F75CF6C00B46C30 /* SDLHapticManagerSpec.m */; };
1E4920B11F6A6443008F2CC3 /* SDLRadioState.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E5AD05F1F207AB10029B8AF /* SDLRadioState.m */; };
1E4920B21F6A6455008F2CC3 /* SDLGetInteriorVehicleDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E5AD08B1F20BC320029B8AF /* SDLGetInteriorVehicleDataResponse.m */; };
1E4920B31F6A6463008F2CC3 /* SDLOnInteriorVehicleData.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E5AD0971F20C0FB0029B8AF /* SDLOnInteriorVehicleData.m */; };
Expand Down Expand Up @@ -297,6 +292,11 @@
1EE8C45D1F387D1C00FDC2CF /* SDLGetInteriorVehicleDataResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EE8C45C1F387D1C00FDC2CF /* SDLGetInteriorVehicleDataResponseSpec.m */; };
1EE8C45F1F3884FF00FDC2CF /* SDLSetInteriorVehicleDataSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EE8C45E1F3884FF00FDC2CF /* SDLSetInteriorVehicleDataSpec.m */; };
1EE8C4611F38865B00FDC2CF /* SDLSetInteriorVehicleDataResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EE8C4601F38865B00FDC2CF /* SDLSetInteriorVehicleDataResponseSpec.m */; };
1FF7DAB61F75B27300B46C30 /* SDLHapticInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF7DAB51F75B27300B46C30 /* SDLHapticInterface.h */; };
1FF7DAB81F75B28E00B46C30 /* SDLHapticHitTester.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF7DAB71F75B28E00B46C30 /* SDLHapticHitTester.h */; };
1FF7DABA1F75B2A800B46C30 /* SDLHapticManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF7DAB91F75B2A800B46C30 /* SDLHapticManager.h */; };
1FF7DABC1F75B2BF00B46C30 /* SDLHapticManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF7DABB1F75B2BF00B46C30 /* SDLHapticManager.m */; };
1FF7DAC01F75CF6C00B46C30 /* SDLHapticManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF7DABF1F75CF6C00B46C30 /* SDLHapticManagerSpec.m */; };
332A914F1CED9CC60043824C /* SDLAppInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 332A913D1CED87F80043824C /* SDLAppInfo.m */; };
332A91501CED9CF10043824C /* SDLAppInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 332A913C1CED87F80043824C /* SDLAppInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D00AC671F140F0A004000D9 /* SDLSystemCapabilityType.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D00AC651F140F0A004000D9 /* SDLSystemCapabilityType.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -1418,11 +1418,6 @@
1680B1101A9CD7AD00DBD79E /* SDLProtocolMessageAssemblerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLProtocolMessageAssemblerSpec.m; sourceTree = "<group>"; };
1680B1111A9CD7AD00DBD79E /* SDLProtocolMessageDisassemblerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLProtocolMessageDisassemblerSpec.m; sourceTree = "<group>"; };
1680B1121A9CD7AD00DBD79E /* SDLProtocolReceivedMessageRouterSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLProtocolReceivedMessageRouterSpec.m; sourceTree = "<group>"; };
1FF7DAB51F75B27300B46C30 /* SDLHapticInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLHapticInterface.h; sourceTree = "<group>"; };
1FF7DAB71F75B28E00B46C30 /* SDLHapticHitTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLHapticHitTester.h; sourceTree = "<group>"; };
1FF7DAB91F75B2A800B46C30 /* SDLHapticManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLHapticManager.h; sourceTree = "<group>"; };
1FF7DABB1F75B2BF00B46C30 /* SDLHapticManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLHapticManager.m; sourceTree = "<group>"; };
1FF7DABF1F75CF6C00B46C30 /* SDLHapticManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLHapticManagerSpec.m; path = ProxySpecs/SDLHapticManagerSpec.m; sourceTree = "<group>"; };
1E5AD0321F1F3AA30029B8AF /* SDLRemoteControlCapabilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLRemoteControlCapabilities.h; sourceTree = "<group>"; };
1E5AD0331F1F3AA30029B8AF /* SDLRemoteControlCapabilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRemoteControlCapabilities.m; sourceTree = "<group>"; };
1E5AD0361F1F4E390029B8AF /* SDLClimateControlCapabilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLClimateControlCapabilities.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1484,6 +1479,11 @@
1EE8C45C1F387D1C00FDC2CF /* SDLGetInteriorVehicleDataResponseSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLGetInteriorVehicleDataResponseSpec.m; sourceTree = "<group>"; };
1EE8C45E1F3884FF00FDC2CF /* SDLSetInteriorVehicleDataSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLSetInteriorVehicleDataSpec.m; sourceTree = "<group>"; };
1EE8C4601F38865B00FDC2CF /* SDLSetInteriorVehicleDataResponseSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLSetInteriorVehicleDataResponseSpec.m; sourceTree = "<group>"; };
1FF7DAB51F75B27300B46C30 /* SDLHapticInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLHapticInterface.h; sourceTree = "<group>"; };
1FF7DAB71F75B28E00B46C30 /* SDLHapticHitTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLHapticHitTester.h; sourceTree = "<group>"; };
1FF7DAB91F75B2A800B46C30 /* SDLHapticManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLHapticManager.h; sourceTree = "<group>"; };
1FF7DABB1F75B2BF00B46C30 /* SDLHapticManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLHapticManager.m; sourceTree = "<group>"; };
1FF7DABF1F75CF6C00B46C30 /* SDLHapticManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLHapticManagerSpec.m; path = ProxySpecs/SDLHapticManagerSpec.m; sourceTree = "<group>"; };
332A913C1CED87F80043824C /* SDLAppInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLAppInfo.h; sourceTree = "<group>"; };
332A913D1CED87F80043824C /* SDLAppInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLAppInfo.m; sourceTree = "<group>"; };
5D00AC651F140F0A004000D9 /* SDLSystemCapabilityType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLSystemCapabilityType.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3608,7 +3608,6 @@
children = (
97E26DEA1E807AD70074A3C7 /* SDLMutableDataQueue.h */,
97E26DEB1E807AD70074A3C7 /* SDLMutableDataQueue.m */,
DAC5724C1D0FE3B60004288B /* Touches */,
E9C32B831AB20B2900F283AF /* @categories */,
5D5934F91A851A8000687FB9 /* Prioritized Objects */,
5D61FAD21A84238A00846EE7 /* SDLHexUtility.h */,
Expand Down Expand Up @@ -4408,6 +4407,7 @@
DA8966E71E56937100413EAB /* Streaming */ = {
isa = PBXGroup;
children = (
DAC5724C1D0FE3B60004288B /* Touches */,
DA8966F01E56970C00413EAB /* Utilities */,
DAA41D521DF66B1100BC7337 /* Video Encoding */,
DA8966E81E56938C00413EAB /* Lifecycle */,
Expand Down
6 changes: 3 additions & 3 deletions SmartDeviceLink/SDLHapticHitTester.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ NS_ASSUME_NONNULL_BEGIN
/**
Determines which view was selected based on SDLTouch object. If no view gets matched null value will be returned.

@param touch SDLTouch which has touch coordinates
@return matched UIView object or null
@param point Point to check for a view
@return point UIView object or nil
*/
- (nullable UIView *)viewForSDLTouch:(SDLTouch *)touch;
- (nullable UIView *)viewForPoint:(CGPoint)point;

@end

Expand Down
9 changes: 8 additions & 1 deletion SmartDeviceLink/SDLHapticInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ NS_ASSUME_NONNULL_BEGIN

@protocol SDLHapticInterface <NSObject>

/**
Whether or not this will attempt to send haptic RPCs.

@note Defaults to NO.
*/
@property (nonatomic, assign) BOOL enableHapticDataRequests;

/**
Initializes haptic interface. After initializing the application must call updateInterfaceLayout to process the UIWindow. Application must update later view changes in the window by sending SDLDidUpdateProjectionView notification.

@param window UIWindow to be stored in haptic interface
@param connectionManager Object of a class that implements ConnectionManagerType. This is used for RPC communication.
*/
- (instancetype)initWithWindow:(UIWindow *)window connectionManager:(id<SDLConnectionManagerType>)connectionManager;
- (instancetype)initWithWindow:(UIWindow *)window connectionManager:(id<SDLConnectionManagerType>)connectionManager;

/**
updateInterfaceLayout crawls through the view hierarchy, updates and keep tracks of views to be reported through Haptic RPC. This function is automatically called when SDLDidUpdateProjectionView notification is sent by the application.
Expand Down
2 changes: 2 additions & 0 deletions SmartDeviceLink/SDLHapticManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ NS_ASSUME_NONNULL_BEGIN

@interface SDLHapticManager : NSObject <SDLHapticInterface, SDLHapticHitTester>

@property (nonatomic, assign) BOOL enableHapticDataRequests;

@end

NS_ASSUME_NONNULL_END
22 changes: 12 additions & 10 deletions SmartDeviceLink/SDLHapticManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ - (instancetype)initWithWindow:(UIWindow *)window connectionManager:(id<SDLConne

_projectionWindow = window;
_connectionManager = connectionManager;
_enableHapticDataRequests = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_projectionViewUpdated:) name:SDLDidUpdateProjectionView object:nil];

return self;
Expand All @@ -59,7 +60,7 @@ - (void)updateInterfaceLayout {
if (preferredViewIndex != NSNotFound && self.focusableViews.count > 1) {
[self.focusableViews exchangeObjectAtIndex:preferredViewIndex withObjectAtIndex:0];
}

[self sdl_sendHapticRPC];
}

Expand All @@ -79,21 +80,18 @@ - (void)sdl_parseViewHierarchy:(UIView *)currentView {
}]];

BOOL isButton = [currentView isKindOfClass:[UIButton class]];
//if current view is focusable and it doesn't have any focusable sub views then add the cuurent view and return
if ((currentView.canBecomeFocused || isButton) && focusableSubviews.count == 0) {
//if current view is focusable and it doesn't have any focusable sub views then add the current view and return
[self.focusableViews addObject:currentView];
return;
}
// if current view has focusable sub views parse them recursively
else if (currentView.subviews.count > 0) {
} else if (currentView.subviews.count > 0) {
// if current view has focusable sub views parse them recursively
NSArray<UIView *> *subviews = currentView.subviews;

for (UIView *childView in subviews) {
[self sdl_parseViewHierarchy:childView];
}
}
//else just return
else {
} else {
return;
}
}
Expand All @@ -102,6 +100,10 @@ - (void)sdl_parseViewHierarchy:(UIView *)currentView {
Iterates through the focusable views, extracts rectangular parameters, creates Haptic RPC request and sends it
*/
- (void)sdl_sendHapticRPC {
if (!self.enableHapticDataRequests) {
return;
}

NSMutableArray<SDLHapticRect *> *hapticRects = [[NSMutableArray alloc] init];

for (UIView *view in self.focusableViews) {
Expand All @@ -119,12 +121,12 @@ - (void)sdl_sendHapticRPC {
}

#pragma mark SDLHapticHitTester functions
- (nullable UIView *)viewForSDLTouch:(SDLTouch *)touch {
- (nullable UIView *)viewForPoint:(CGPoint)point {
UIView *selectedView = nil;

for (UIView *view in self.focusableViews) {
//Convert the absolute location to local location and check if that falls within view boundary
CGPoint localPoint = [view convertPoint:touch.location fromView:self.projectionWindow];
CGPoint localPoint = [view convertPoint:point fromView:self.projectionWindow];
if ([view pointInside:localPoint withEvent:nil]) {
if (selectedView != nil) {
selectedView = nil;
Expand Down
14 changes: 13 additions & 1 deletion SmartDeviceLink/SDLStreamingMediaConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (weak, nonatomic, nullable) id<SDLStreamingMediaManagerDataSource> dataSource;

/**
Set the window your video streaming content is within.

Activates the haptic view parser when set. If the window contains `UIView` based views, these will be discovered and automatically sent to the head unit if it uses a haptic interface. Whether or not it supports the haptic interace, this library will also use that information to attempt to return the touched view to you in `SDLTouchManagerDelegate`.

@warning Apps using views outside of the `UIView` heirarchy (such as OpenGL) are currently unsupported. If you app uses partial views in the heirarchy, only those views will be discovered. Your OpenGL views will not be discoverable to a haptic interface head unit and you will have to manually make these views discoverable via the `SDLSendHapticData` RPC request.

@warning This is a weak property and it's therefore your job to hold a strong reference to this window.
*/
@property (weak, nonatomic, nullable) UIWindow *window;

/**
Create an insecure video streaming configuration. No security managers will be provided and the encryption flag will be set to None. If you'd like custom video encoder settings, you can set the property manually.

Expand All @@ -51,9 +62,10 @@ NS_ASSUME_NONNULL_BEGIN
@param securityManagers The security managers to use or nil for none.
@param encryptionFlag The maximum encrpytion supported. If the connected head unit supports less than set here, it will still connect, but if it supports more than set here, it will not connect.
@param videoSettings Custom video encoder settings to be used in video streaming.
@param window The UIWindow you are running the content that is being streamed on, to use for haptics if needed and possible (only works for UIViews)
@return The configuration
*/
- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *_Nullable)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(NSDictionary<NSString *, id> *_Nullable)videoSettings dataSource:(nullable id<SDLStreamingMediaManagerDataSource>)dataSource;
- (instancetype)initWithSecurityManagers:(nullable NSArray<Class<SDLSecurityType>> *)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(nullable NSDictionary<NSString *, id> *)videoSettings dataSource:(nullable id<SDLStreamingMediaManagerDataSource>)dataSource window:(nullable UIWindow *)window;

/**
Create a secure configuration for each of the security managers provided.
Expand Down
9 changes: 5 additions & 4 deletions SmartDeviceLink/SDLStreamingMediaConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
@implementation SDLStreamingMediaConfiguration

- (instancetype)init {
return [self initWithSecurityManagers:nil encryptionFlag:SDLStreamingEncryptionFlagNone videoSettings:nil dataSource:nil];
return [self initWithSecurityManagers:nil encryptionFlag:SDLStreamingEncryptionFlagNone videoSettings:nil dataSource:nil window:nil];
}

+ (instancetype)insecureConfiguration {
return [[self alloc] init];
}

- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *_Nullable)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(NSDictionary<NSString *, id> *_Nullable)videoSettings dataSource:(nullable id<SDLStreamingMediaManagerDataSource>)dataSource {
- (instancetype)initWithSecurityManagers:(nullable NSArray<Class<SDLSecurityType>> *)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(nullable NSDictionary<NSString *,id> *)videoSettings dataSource:(nullable id<SDLStreamingMediaManagerDataSource>)dataSource window:(nullable UIWindow *)window {
self = [super init];
if (!self) {
return nil;
Expand All @@ -33,6 +33,7 @@ - (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *_Null
_maximumDesiredEncryption = encryptionFlag;
_customVideoEncoderSettings = videoSettings;
_dataSource = dataSource;
_window = window;

return self;
}
Expand All @@ -41,7 +42,7 @@ - (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)secu
NSAssert(securityManagers.count > 0, @"A secure streaming media configuration requires security managers to be passed.");
SDLStreamingEncryptionFlag encryptionFlag = SDLStreamingEncryptionFlagAuthenticateAndEncrypt;

return [self initWithSecurityManagers:securityManagers encryptionFlag:encryptionFlag videoSettings:nil dataSource:nil];
return [self initWithSecurityManagers:securityManagers encryptionFlag:encryptionFlag videoSettings:nil dataSource:nil window:nil];
}

+ (instancetype)secureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers {
Expand All @@ -51,7 +52,7 @@ + (instancetype)secureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecuri
#pragma mark NSCopying

- (id)copyWithZone:(nullable NSZone *)zone {
return [[self.class allocWithZone:zone] initWithSecurityManagers:_securityManagers encryptionFlag:_maximumDesiredEncryption videoSettings:_customVideoEncoderSettings dataSource:_dataSource];
return [[self.class allocWithZone:zone] initWithSecurityManagers:_securityManagers encryptionFlag:_maximumDesiredEncryption videoSettings:_customVideoEncoderSettings dataSource:_dataSource window:_window];
}

@end
Expand Down
6 changes: 6 additions & 0 deletions SmartDeviceLink/SDLStreamingMediaLifecycleManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
@class SDLTouchManager;
@class SDLVideoStreamingFormat;

@protocol SDLHapticInterface;
@protocol SDLStreamingMediaManagerDataSource;

NS_ASSUME_NONNULL_BEGIN
Expand Down Expand Up @@ -63,6 +64,11 @@ extern SDLAudioStreamState *const SDLAudioStreamStateShuttingDown;
*/
@property (nonatomic, strong, readonly) SDLTouchManager *touchManager;

/**
A haptic interface that can be updated to reparse views within the window you've provided. Send a `SDLDidUpdateProjectionView` notification or call the `updateInterfaceLayout` method to reparse. The "output" of this haptic interface occurs in the `touchManager` property where it will call the delegate.
*/
@property (nonatomic, strong, readonly, nullable) id<SDLHapticInterface> hapticInterface;

/**
A data source for the streaming manager's preferred resolutions and preferred formats.
*/
Expand Down
Loading