1

I'm trying to reload the icon cache after installing an application through LSApplicationWorkspace. The applications install, but I have to execute "uicache" in mobileterminal to reload the springboard cache. Is there a way I could do this programmatically? The application ISN'T running as root by the way.

At the moment, I have code as follows to reload the springboard icon cache but it doesn't work:

remove("/var/mobile/Library/Caches/com.apple.mobile.installation.plist");
remove("/var/mobile/Library/Caches/com.apple.springboard-imagecache-icons");
remove("/var/mobile/Library/Caches/com.apple.springboard-imagecache-icons.plist");
remove("/var/mobile/Library/Caches/com.apple.springboard-imagecache-smallicons");
remove("/var/mobile/Library/Caches/com.apple.springboard-imagecache-smallicons.plist");
remove("/var/mobile/Library/Caches/SpringBoardIconCache");
remove("/var/mobile/Library/Caches/SpringBoardIconCache-small");
remove("/var/mobile/Library/Caches/com.apple.IconsCache");

// find ios 8 version:
NSString *cache_path = @"/var/mobile/Library/Caches/";
NSArray *conts = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:cache_path error:nil];
for (NSString *filefolder in conts) {
    if ([filefolder containsString:@"com.apple.LaunchServices"]) {
        NSString *newpath = [cache_path stringByAppendingPathComponent:filefolder];
        remove([newpath UTF8String]);
    }
}

// build the args list
Class __LSApplicationWorkspace = objc_getClass("LSApplicationWorkspace");
[(LSApplicationWorkspace *)[__LSApplicationWorkspace defaultWorkspace] invalidateIconCache:nil];
[(LSApplicationWorkspace *)[__LSApplicationWorkspace defaultWorkspace] registerApplication:[NSURL fileURLWithPath:bundlePath]];
int didNotify = notify_post("com.apple.mobile.application_installed");
NSLog(@"Did Notify: %i",didNotify);

// remove temp.app:
if ([[NSFileManager defaultManager] fileExistsAtPath:bundlePath]) {
    [[NSFileManager defaultManager] removeItemAtPath:bundlePath error:nil];
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Declan Land
  • 639
  • 2
  • 11
  • 27
  • You actually don't need root to launch `uicache`. It requires you launch it as mobile. Also, doesn't `LSApplicationWorkspace` reload springboard for you when you install an app? – creker Feb 19 '16 at 12:57
  • I've tried using system("uicache"); and I get no response. Also here is my device log when I install an application - the installation works perfect, but for some reason it doesn't reload the cache. Thanks for your help! http://pastebin.com/raw/HXEFwvaM – Declan Land Feb 19 '16 at 13:18
  • When using system("/usr/bin/uicache"); I get this response: Sandbox:myApp(9000) deny(1) process-fork – Declan Land Feb 19 '16 at 13:21
  • Yeah, running as non-root and running inside the sandbox are not the same thing. You could do everything you need if you're outside of the sandbox, you don't even need the root. But it looks like it would be impossible to do it being inside. Jailbreak doesn't break sandboxing, it still works almost the same. – creker Feb 22 '16 at 01:35

1 Answers1

0

I found a temporary solution to my question if anyone is interested. I created an extra application (running as root), that was to be installed separately from the original app. I made this application invisible to the user by adding the following to the Info.plist:

<key>SBAppTags</key>
  <array>
     <string>hidden</string>
  </array>

And used URL Schemes to call the "Reload" function.

Although another option could have been to create a LaunchDaemon or a MobileSubstrate extension. I couldn't find a way of reloading the cache as a "mobile" user though.

Declan Land
  • 639
  • 2
  • 11
  • 27