Posts

Post not yet marked as solved
1 Replies
386 Views
Hi everyone, I'm trying to make some app using HandTrackingProvider to monitor hand gestures in immersive world and move objects in the space. I know the HandTrackingProvider class is for visionOS only, not for iOS or any other Apple OS. https://developer.apple.com/documentation/arkit/handtrackingprovider For now, the visionOS simulator can not use cameras, how can I debug hand trackings? I'm working on Apple's sample code "Happy Beam" now. https://developer.apple.com/documentation/visionos/happybeam Anyone have genius technics to solve this? Or there is any workaround? Any idea will be appriciated. Thank you! Yos
Posted
by AlohaYos.
Last updated
.
Post not yet marked as solved
0 Replies
1.3k Views
I have a question about Keychain access and MDM management on iPad OS. My iPad app save some information in Keychain with the sample code below. Information is correctly stored in Keychain on personal iPads. However, in the case of an iPad managed by MDM in the company, the information remains nil when read from keychain. I found an explanation about MDM on the website below. "IPhone and iPad MDM functionality restrictions" https://support.apple.com/guide/mdm/restrictions-for-iphone-and-ipad-mdm0f7dd3d8/1/web/1.0 At the "iCloud Keychain" section in this explanation, you can read that "Keychain cannot be used on an iPad managed by MDM". Is this limitation the reason why information is not stored in Keychain? And, can this restriction be changed by modifying the settings on the MDM side? Or, what kind of coding technics can be used on the app side? I want to save the information entered by the user and read that information even if the application is reinstalled. Even if the app is running under MDM environment. My app is assumed to be used in the following situations. IPad app used in the factory IPad is MDM managed Do not use Apple ID Do not use a server to store information Information is saved/read using saveObject:forKey and loadObjectForKey: @implementation IOSKeyChain + (BOOL) checkOSStatus: (OSStatus) status { return status == noErr; } + (NSMutableDictionary *) keychainQueryForKey: (NSString *) key { return [@ {(__ bridge id) kSecClass: (__ bridge id) kSecClassGenericPassword, (__bridge id) kSecAttrService: key, (__bridge id) kSecAttrAccount: key, (__bridge id) kSecAttrAccessible: (__bridge id) kSecAttrAccessibleAfterFirstUnlock } mutableCopy]; } + (BOOL) saveObject: (id) object for Key: (NSString *) key { NSMutableDictionary * keychainQuery = [self keychainQueryForKey: key]; // Deleting previous object with this key, because SecItemUpdate is more complicated. [self deleteObjectForKey: key]; . [keychainQuery setObject: [NSKeyedArchiver archivedDataWithRootObject: object] forKey: (__ bridge id) kSecValueData]; return [self checkOSStatus: SecItemAdd ((_ _ bridge CFDictionaryRef) keychainQuery, NULL)]; } + (id) loadObjectForKey: (NSString *) key { id object = nil; . NSMutableDictionary * keychainQuery = [self keychainQueryForKey: key]; . [keychainQuery setObject: (__ bridge id) kCFBooleanTrue forKey: (__ bridge id) kSecReturnData]; [keychainQuery setObject: (__ bridge id) kSecMatchLimitOne for Key: (__ bridge id) kSecMatchLimit]; . CFDataRef keyData = NULL; . if ([self checkOSStatus: SecItemCopyMatching ((__ bridge CFDictionaryRef) keychainQuery, (CFTypeRef *) & keyData)]) { @try { object = [NSKeyedUnarchiver unarchiveObjectWithData: (__ bridge NSData *) keyData]; } @catch (NSException * exception) { NSLog (@ "Unarchiving for key% @ failed with exception% @", key, exception.name); object = nil; } @finally {} } . if (keyData) { CF Release (keyData); } . return object; } + (BOOL) deleteObjectForKey: (NSString *) key { NSMutableDictionary * keychainQuery = [self keychainQueryForKey: key]; return [self checkOSStatus: SecItemDelete ((_ _ bridge CFDictionaryRef) keychainQuery)]; } @end code-block
Posted
by AlohaYos.
Last updated
.