How can I make my app sandbox compliant? The list of things it does that I'm not sure whether are okay or not are...
- It calls IOReg and collects information on various devices (name, battery percent, whether it's charging, etc.,)
- It makes an NSStatusItem.
- It stores a bunch of data into NSUserDefaults
- It modifies whether it is a launch item or not. The code it uses to do this is below:
I guess I should have a more clear question: What, if anything, do I need to do to make my app sandbox compliant? Are there any entitlements I need to give it? Do I need to use different APIs? Is there any part that simply can't be done with sandboxing? (I fear that I may just have to give Battery Status a final update next week and then lie low and wait for Apple to remove it for not being sandbox compliant.)
- It calls IOReg and collects information on various devices (name, battery percent, whether it's charging, etc.,)
- It makes an NSStatusItem.
- It stores a bunch of data into NSUserDefaults
- It modifies whether it is a launch item or not. The code it uses to do this is below:
Code:
- (NSArray *)loginItems
{
CFArrayRef snapshotRef = LSSharedFileListCopySnapshot(loginItemsListRef, NULL);
return (__bridge NSArray *)snapshotRef;
}
// Return a CFRetained item for the app's bundle, if there is one.
- (LSSharedFileListItemRef)mainBundleLoginItemCopy
{
NSArray *loginItems = [self loginItems];
NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
for (id item in loginItems) {
LSSharedFileListItemRef itemRef = (__bridge LSSharedFileListItemRef)item;
CFURLRef itemURLRef;
if (LSSharedFileListItemResolve(itemRef, 0, &itemURLRef, NULL) == noErr) {
// Again, use toll-free bridging.
NSURL *itemURL = (__bridge NSURL *)itemURLRef;
if ([itemURL isEqual:bundleURL])
{
return (__bridge LSSharedFileListItemRef)item;
}
}
}
return NULL;
}
- (BOOL)launchOnLogin
{
if (!loginItemsListRef)
return NO;
LSSharedFileListItemRef itemRef = [self mainBundleLoginItemCopy];
if (!itemRef)
return NO;
CFRelease(itemRef);
return YES;
}
- (void)setLaunchOnLogin:(BOOL)value
{
if (!loginItemsListRef)
return;
if (!value) {
[self removeMainBundleFromLoginItems];
} else {
[self addMainBundleToLoginItems];
}
}
- (void)addMainBundleToLoginItems
{
// We use the URL to the app itself (i.e. the main bundle).
NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
NSDictionary *properties;
properties = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:@"com.apple.loginitem.HideOnLaunch"];
LSSharedFileListItemRef itemRef;
itemRef = LSSharedFileListInsertItemURL(loginItemsListRef,
kLSSharedFileListItemLast,
NULL,
NULL,
(__bridge CFURLRef)bundleURL,
(__bridge CFDictionaryRef)properties,
NULL);
if (itemRef) {
CFRelease(itemRef);
}
}
- (void)removeMainBundleFromLoginItems
{
// Try to get the item corresponding to the main bundle URL.
LSSharedFileListItemRef itemRef = [self mainBundleLoginItemCopy];
if (!itemRef)
return;
LSSharedFileListItemRemove(loginItemsListRef, itemRef);
CFRelease(itemRef);
}
I guess I should have a more clear question: What, if anything, do I need to do to make my app sandbox compliant? Are there any entitlements I need to give it? Do I need to use different APIs? Is there any part that simply can't be done with sandboxing? (I fear that I may just have to give Battery Status a final update next week and then lie low and wait for Apple to remove it for not being sandbox compliant.)