18862BDB2C806BD900D3564D /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 180E7C7F2BD8FC4E008558E8 /* libavcodec.a */; };
18862BDC2C806BD900D3564D /* libswresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 180E7C822BD8FC4E008558E8 /* libswresample.a */; };
18862BDD2C806BD900D3564D /* libavformat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 180E7C802BD8FC4E008558E8 /* libavformat.a */; };
+ 1888148E2C85766B009299A9 /* AiDeviceAuthManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1888148C2C85766B009299A9 /* AiDeviceAuthManager.h */; };
+ 1888148F2C85766B009299A9 /* AiDeviceAuthManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1888148C2C85766B009299A9 /* AiDeviceAuthManager.h */; };
+ 188814902C85766B009299A9 /* AiDeviceAuthManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */; };
+ 188814912C85766B009299A9 /* AiDeviceAuthManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */; };
189C15862C05726600676A80 /* AiConnectManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 189C15842C05726600676A80 /* AiConnectManager.h */; };
189C15872C05726600676A80 /* AiConnectManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 189C15852C05726600676A80 /* AiConnectManager.m */; };
18AD83252BFAE8B9009BDE3B /* AiDeviceInfoManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */; };
18862A1E2C8064E300D3564D /* BleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BleManager.m; sourceTree = "<group>"; };
18862A202C8064E300D3564D /* TimerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TimerManager.m; sourceTree = "<group>"; };
18862A212C8064E300D3564D /* HidManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HidManager.h; sourceTree = "<group>"; };
+ 1888148C2C85766B009299A9 /* AiDeviceAuthManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiDeviceAuthManager.h; sourceTree = "<group>"; };
+ 1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiDeviceAuthManager.m; sourceTree = "<group>"; };
189C15842C05726600676A80 /* AiConnectManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiConnectManager.h; sourceTree = "<group>"; };
189C15852C05726600676A80 /* AiConnectManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiConnectManager.m; sourceTree = "<group>"; };
18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiDeviceInfoManager.h; sourceTree = "<group>"; };
18862A1E2C8064E300D3564D /* BleManager.m */,
18862A1A2C8064E300D3564D /* TimerManager.h */,
18862A202C8064E300D3564D /* TimerManager.m */,
+ 1888148C2C85766B009299A9 /* AiDeviceAuthManager.h */,
+ 1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */,
);
path = Manager;
sourceTree = "<group>";
180E7CAD2BD8FC4E008558E8 /* attributes.h in Headers */,
18AD83252BFAE8B9009BDE3B /* AiDeviceInfoManager.h in Headers */,
180E7C932BD8FC4E008558E8 /* murmur3.h in Headers */,
+ 1888148E2C85766B009299A9 /* AiDeviceAuthManager.h in Headers */,
180E7CE52BD8FC4E008558E8 /* version.h in Headers */,
180E7CC62BD8FC4E008558E8 /* tea.h in Headers */,
180E7CF12BD8FC4F008558E8 /* mediacodec.h in Headers */,
18862B1B2C806BD900D3564D /* attributes.h in Headers */,
18862B1C2C806BD900D3564D /* AiDeviceInfoManager.h in Headers */,
18862B1D2C806BD900D3564D /* murmur3.h in Headers */,
+ 1888148F2C85766B009299A9 /* AiDeviceAuthManager.h in Headers */,
18862B1E2C806BD900D3564D /* version.h in Headers */,
18862B1F2C806BD900D3564D /* tea.h in Headers */,
18862B202C806BD900D3564D /* mediacodec.h in Headers */,
184A71202BDD11C70025A332 /* AiTrippleModel.m in Sources */,
180E7AAC2BD7BB12008558E8 /* AiMouseSdk.m in Sources */,
180E7BE12BD7BD84008558E8 /* AiAudioConverter.m in Sources */,
+ 188814902C85766B009299A9 /* AiDeviceAuthManager.m in Sources */,
184A71072BDA4C050025A332 /* AFHTTPSessionManager.m in Sources */,
180E7BE02BD7BD84008558E8 /* AiMouseTools.m in Sources */,
184A710A2BDA4C050025A332 /* AFURLRequestSerialization.m in Sources */,
18862BB52C806BD900D3564D /* AiTrippleModel.m in Sources */,
18862BB62C806BD900D3564D /* AiMouseSdk.m in Sources */,
18862BB72C806BD900D3564D /* AiAudioConverter.m in Sources */,
+ 188814912C85766B009299A9 /* AiDeviceAuthManager.m in Sources */,
18862BB82C806BD900D3564D /* AFHTTPSessionManager.m in Sources */,
18862BB92C806BD900D3564D /* AiMouseTools.m in Sources */,
18862BBA2C806BD900D3564D /* AFURLRequestSerialization.m in Sources */,
#import "AiRecordManager.h"
#import <AVFoundation/AVFoundation.h>
+#import <Cocoa/Cocoa.h>
+#import "AiDeviceAuthManager.h"
@interface AiRecordManager()
@property (nonatomic,assign)BOOL isAllowRecord;
[self openSettings];
break;
}
+}
-
-
+- (void)checkPermissions2{
+ [self showLog:@"查询录音授权状态"];
+ switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]) {
+ case AVAuthorizationStatusAuthorized:
+ self.isAllowRecord = true;
+ [self showLog:@"录音已经授权"];
+ break;
+ case AVAuthorizationStatusNotDetermined:
+ {
+ [self showLog:@"录音未授权"];
+ [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
+ if (granted) {
+ self.isAllowRecord = true;
+ [self showLog:@"录音已经授权"];
+ }
+ else{
+ [self showLog:@"已拒绝"];
+ }
+ }];
+ }
+ break;
+ case AVAuthorizationStatusDenied:
+ [self showLog:@"已拒绝"];
+ [[AiDeviceAuthManager shared] showMicrophoneAlert];
+ break;
+ default:
+ [self showLog:@"已拒绝"];
+ [[AiDeviceAuthManager shared] showMicrophoneAlert];
+ break;
+ }
}
+//// 表明用户尚未选择关于客户端是否可以访问硬件
+//AVAuthorizationStatusNotDetermined
+//
+//// 客户端未被授权访问硬件的媒体类型。用户不能改变客户机的状态,可能由于活跃的限制,如家长控制
+// AVAuthorizationStatusRestricted,
+//
+//// 明确拒绝用户访问硬件支持的媒体类型的客户
+//AVAuthorizationStatusDenied,
+//
+//// 客户端授权访问硬件支持的媒体类型
+//AVAuthorizationStatusAuthorized
+//————————————————
+//
+// 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
+//
+//原文链接:https://blog.csdn.net/skl5879166/article/details/115365332
+
+
- (void)openSettings{
-// NSURL *url = [NSURL URLWithString:@""];
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"]];
}
- (void)showLog:(NSString *)log{
--- /dev/null
+//
+// AiDeviceAuthManager.h
+// AiMouseSdk
+//
+// Created by incar on 2024/9/2.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface AiDeviceAuthManager : NSObject
+
+
+///单例
++(AiDeviceAuthManager *)shared;
+
+- (void)showHidAlert;
+
+- (void)showMicrophoneAlert;
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// AiDeviceAuthManager.m
+// AiMouseSdk
+//
+// Created by incar on 2024/9/2.
+//
+
+#import "AiDeviceAuthManager.h"
+#import <Cocoa/Cocoa.h>
+
+@interface AiDeviceAuthManager()<NSAlertDelegate>
+
+@property (nonatomic, strong) NSAlert *hidAlerl;
+@end
+
+
+@implementation AiDeviceAuthManager
++(AiDeviceAuthManager *)shared{
+ static AiDeviceAuthManager *manager = nil;
+ static dispatch_once_t oncePredicate;
+ dispatch_once(&oncePredicate, ^{
+ manager = [[AiDeviceAuthManager alloc]init];
+ });
+ return manager;
+}
+
+
+- (void)showHidAlert{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"请前往设置-隐私与安全性-输入监控,将输入监控打开并重启app才能使用AI功能"];
+ [alert addButtonWithTitle:@"确定"];
+// [alert addButtonWithTitle:@"取消"];
+ NSInteger result = [alert runModal];
+ if (result == NSAlertFirstButtonReturn) {
+ NSLog(@"用户点击了确定");
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent"]];
+ } else if (result == NSAlertSecondButtonReturn) {
+ NSLog(@"用户点击了取消");
+ }
+}
+
+
+- (void)showMicrophoneAlert{
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"请前往设置-隐私与安全性-麦克风,将麦克风打开并重启app才能使用AI功能"];
+ [alert addButtonWithTitle:@"确定"];
+// [alert addButtonWithTitle:@"取消"];
+ NSInteger result = [alert runModal];
+ if (result == NSAlertFirstButtonReturn) {
+ NSLog(@"用户点击了确定");
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"]];
+ } else if (result == NSAlertSecondButtonReturn) {
+ NSLog(@"用户点击了取消");
+ }
+}
+
+@end
if(self.curentPeripheral == nil || self.curentPeripheral.state == CBPeripheralStateDisconnected){
[self startScan];
}
+ if (self.curentPeripheral && self.curentPeripheral.state == CBPeripheralStateConnected && [DeviceManger shared].connectType == AiMouseConnectType_hid ) {
+ self.connectStateCallBack(self.curentPeripheral.name,true);
+ }
}
@end
#import "HidManager.h"
#include <IOKit/hid/IOHIDLib.h>
#include <IOKit/hid/IOHIDKeys.h>
-
+#import <Security/Security.h>
+#import <Carbon/Carbon.h>
+#import <Cocoa/Cocoa.h>
+#import "AiDeviceAuthManager.h"
@interface HidManager ()
@property(nonatomic, assign) IOHIDManagerRef hidManager;///hid管理
IOReturn result = IOHIDDeviceOpen([HidManager shared].deviceInfoCha, kIOHIDOptionsTypeNone);
if (result != kIOReturnSuccess) {
[[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]];
+ [[AiDeviceAuthManager shared] showHidAlert];
+ return;
}else{
[[HidManager shared] showLog:@"打开设备成功!"];
// [HidManager shared].connectStateCallBack(true) ;
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[HidManager shared].connectStateCallBack(true);
});
}
IOReturn result = IOHIDDeviceOpen(inIOHIDDeviceRef, kIOHIDOptionsTypeNone);
if (result != kIOReturnSuccess) {
[[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备信息失败! %d",result]];
+ [[AiDeviceAuthManager shared] showHidAlert];
+ return;
}else{
// CFRetain(inIOHIDDeviceRef);
// IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
IOReturn result = IOHIDDeviceOpen(inIOHIDDeviceRef, kIOHIDOptionsTypeNone);
if (result != kIOReturnSuccess) {
[[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备voice失败! %d",result]];
+ [[AiDeviceAuthManager shared] showHidAlert];
+ return;
+ return;
}else{
// CFRetain(inIOHIDDeviceRef);
// IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
}
return outValue;
}
+
+
+
+//// 判断输入监控权限的方法
+//-(BOOL)checkInputMonitoringPermission{
+// AuthorizationRef authorizationRef;
+// OSStatus status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
+// if (status!= errAuthorizationSuccess) {
+// return NO;
+// }
+//
+// CFDictionaryRef query = CFDictionaryCreate(NULL,
+// (const void **)&kSecClass,
+// (const void **)&kSecClassGenericPassword,
+// (const void **)&kSecMatchLimit,
+// (const void **)&kSecMatchLimitOne,
+// (const void **)&kSecReturnAttributes,
+// (const void **)&kCFBooleanTrue,
+// (const void **)&kSecUseDataProtectionKeychain,
+// (const void **)&kCFBooleanFalse,
+// NULL);
+//
+// CFArrayRef resultArray = NULL;
+// status = SecItemCopyMatching(query, (CFTypeRef *)&resultArray);
+// CFRelease(query);
+//
+// if (status!= errSecSuccess) {
+// AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
+// return NO;
+// }
+//
+// BOOL hasInputMonitoring = NO;
+// if (resultArray && CFArrayGetCount(resultArray) > 0) {
+// CFDictionaryRef itemDict = CFArrayGetValueAtIndex(resultArray, 0);
+// CFBooleanRef inputMonitoringValue = (CFBooleanRef)CFDictionaryGetValue(itemDict, CFSTR("kSecAttrCanAccessWhenUnlocked"));
+// if (inputMonitoringValue && CFBooleanGetValue(inputMonitoringValue)) {
+// hasInputMonitoring = YES;
+// }
+// }
+//
+// if (resultArray) {
+// CFRelease(resultArray);
+// }
+// AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
+//
+// return hasInputMonitoring;
+//}
@end
// [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
// [[NSRunLoop currentRunLoop] run];
// });
- self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:true];
+ self.timer = [NSTimer scheduledTimerWithTimeInterval:8 target:self selector:@selector(timerAction) userInfo:nil repeats:true];
}
- (void)timerAction{
@property (nonatomic, strong) NSString *brand;///型号
@property (nonatomic, strong) NSString *batch;/// 批次
@property (nonatomic, strong) NSString *sn;/// 设备号
+@property (nonatomic, strong) NSString *mac;/// mac地址
@end
/// 日志等级
@end
@implementation TlwSnInfo
-(NSString *)description{
- NSString *info = [NSString stringWithFormat:@"code = %@ brand = %@ batch = %@ sn = %@",self.code,self.brand,self.batch,self.sn];
+ NSString *info = [NSString stringWithFormat:@"code = %@ brand = %@ batch = %@ mac = %@ sn = %@",self.code,self.brand,self.batch,self.mac,self.sn];
return info;
}
@end
- (void)getFullDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{
+ if (self.getFullInfoCallBack) {
+ return;
+ }
self.getFullInfoCallBack = finished;
self.questTimes = 0;
[self checkFullInfoAction];
}
}
- (void)reGetFullInfoAction{
+ if(self.getFullInfoCallBack == nil)return;;
__weak typeof(self) ws = self;
[self getDeviceInfo:^(TlwDeviceInfo *deviceInfo, NSError *error) {
if(deviceInfo != nil){
if( info != nil){
info.brand = snInfo.brand;
info.sn = snInfo.sn;
- info.mac = snInfo.sn;
+ info.mac = snInfo.mac;
[ws showLog:info.description];
if(ws.getFullInfoCallBack)ws.getFullInfoCallBack(info, nil);
ws.getFullInfoCallBack = nil;
case 0x22:
{
- // 220210 48584D33303030313031E6FCFF68D7D000
NSString *code = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(3, 2)] encoding:NSUTF8StringEncoding];
NSString *brand = [self getBrand:[data subdataWithRange:NSMakeRange(5, 6)]];
- NSString *batch = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(11, 2)]];
- NSString *sn = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(13, 6)]];
+ NSString *batch = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(11, 2)] encoding:NSUTF8StringEncoding];
+ NSString *mac = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(13, 6)]];
+
+ NSString *fullBrand = [self getFullBrand:[data subdataWithRange:NSMakeRange(5, 6)]];
+ NSString *sn = [[NSString stringWithFormat:@"%@%@%@%@",code,fullBrand,batch,mac] lowercaseString];
TlwSnInfo *info = [[TlwSnInfo alloc] init];
info.code = code;
info.brand = brand;
info.batch = batch;
+ info.mac = mac;
info.sn = sn;
[self showLog:info.description];
if(self.getSnInfoCallBack)self.getSnInfoCallBack(info, nil);
// 0x05fff1fec09f0114ef
if(data.length < 7 ){
[self showLog:@"收到异常数据"];
- // [self switchConnect:AiMouseConnectType_hid isConnected:false ];
return;
}
if(![[[TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(1, 2)]] lowercaseString] isEqualToString:@"fff1"]){
[self showLog:@"收到异常数据"];
- // [self switchConnect:AiMouseConnectType_hid isConnected:false ];
return;
}
//语音开启回复
uint8 state;
[[data subdataWithRange:NSMakeRange(6, 1)] getBytes:&state length:1];
- BOOL success = state == 0x02;
+ BOOL success = state == 0;
[self showLog:[NSString stringWithFormat:@"语音开启回复 %@",@(success)]];
if(self.openRecordCallBack)self.openRecordCallBack(true, nil);
[self startRecord];
//语音停止回复
uint8 state;
[[data subdataWithRange:NSMakeRange(6, 1)] getBytes:&state length:1];
- BOOL success = state == 0x02;
+ BOOL success = state == 0;
[self showLog:[NSString stringWithFormat:@"语音停止回复 %@",@(success)]];
[self stopRecord];
//设置DPI回复
uint8 state;
[[data subdataWithRange:NSMakeRange(6, 1)] getBytes:&state length:1];
- BOOL success = state == 0x02;
+ BOOL success = state == 0;
[self showLog:[NSString stringWithFormat:@"设置DPI回复 %@",@(success)]];
if(self.setDpiCallBack)self.setDpiCallBack(true, nil);
case 0x22:
{ //sn查询回复
// 05FFF1FEC022 1048584D33303030313031E6FCFF68D7D0EF00000000000000000000000000000000000000000000000000000000000000000000000000000000
- // 220210 48584D33303030313031E6FCFF68D7D000
data = [data subdataWithRange:NSMakeRange(4, data.length - 4)];
NSString *code = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(3, 2)] encoding:NSUTF8StringEncoding];
NSString *brand = [self getBrand:[data subdataWithRange:NSMakeRange(5, 6)]];
- NSString *batch = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(11, 2)]];
- NSString *sn = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(13, 6)]];
+ NSString *batch = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(11, 2)] encoding:NSUTF8StringEncoding];
+ NSString *mac = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(13, 6)]];
+
+ NSString *fullBrand = [self getFullBrand:[data subdataWithRange:NSMakeRange(5, 6)]];
+ NSString *sn = [[NSString stringWithFormat:@"%@%@%@%@",code,fullBrand,batch,mac] lowercaseString];
TlwSnInfo *info = [[TlwSnInfo alloc] init];
info.code = code;
info.brand = brand;
info.batch = batch;
+ info.mac = mac;
info.sn = sn;
[self showLog:info.description];
if(self.getSnInfoCallBack)self.getSnInfoCallBack(info, nil);
- (NSString *)getBrand:(NSData *)data{
NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
for (NSInteger i = 0; i < text.length;i++) {
- if ([[text substringWithRange:NSMakeRange(i, 1)] isEqual:@"0"]) {
+ if ([[text substringWithRange:NSMakeRange(i, 1)] isEqual:@"\0"]) {
return [text substringWithRange:NSMakeRange(0, i)];
}
}
return text;
}
+- (NSString *)getFullBrand:(NSData *)data{
+ NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ NSString *replacedString = [text stringByReplacingOccurrencesOfString:@"\0" withString:@"0"];
+ return replacedString;
+}
@end
</Locations>
</BreakpointContent>
</BreakpointProxy>
+ <BreakpointProxy
+ BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+ <BreakpointContent
+ uuid = "31993B35-9DA9-4381-B863-11397B6D9184"
+ shouldBeEnabled = "Yes"
+ ignoreCount = "0"
+ continueAfterRunningActions = "No"
+ filePath = "AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m"
+ startingColumnNumber = "9223372036854775807"
+ endingColumnNumber = "9223372036854775807"
+ startingLineNumber = "22"
+ endingLineNumber = "22"
+ landmarkName = "-description"
+ landmarkType = "7">
+ </BreakpointContent>
+ </BreakpointProxy>
+ <BreakpointProxy
+ BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+ <BreakpointContent
+ uuid = "B9B9032E-D4BF-479C-B350-7D0E383A7C18"
+ shouldBeEnabled = "Yes"
+ ignoreCount = "0"
+ continueAfterRunningActions = "No"
+ filePath = "AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m"
+ startingColumnNumber = "9223372036854775807"
+ endingColumnNumber = "9223372036854775807"
+ startingLineNumber = "656"
+ endingLineNumber = "656"
+ landmarkName = "TlwMouse"
+ landmarkType = "3">
+ </BreakpointContent>
+ </BreakpointProxy>
</Breakpoints>
</Bucket>
[self.view addSubview:label];
}
{
- NSTextField *label = [[NSTextField alloc] initWithFrame:CGRectMake(180, self.view.bounds.size.height - 260, 300, 100)];
+ NSTextField *label = [[NSTextField alloc] initWithFrame:CGRectMake(180, self.view.bounds.size.height - 360, 300, 200)];
label.editable = NO;
label.bordered = NO;
label.stringValue = @"";
}
- (void)geviceInfoAction{
+// [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent"]];
+// return;
[[DeviceManger shared] getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) {
if (deviceInfo) {
NSString *info = deviceInfo.description;
}];
}
+
- (void)moreAction:(NSButton *)sender {
NSMenu *popupMenu = [[NSMenu alloc] initWithTitle:@"Popup Menu"];
NSMenuItem *item1 = [[NSMenuItem alloc] initWithTitle:@"语音开启" action:@selector(voiceStart:) keyEquivalent:@"1"];