iOS8下代码安装/卸载APP

iOS8下安装/卸载APP的代码,好久之前的了,还是贴出来吧,顺便把注释写上了。

 

#import <Foundation/Foundation.h>
#import <spawn.h>
#import <sys/wait.h>
#import <UIKit/UIKit.h>

/*!
 *  @brief  Mobile Installation 的回调定义
 */

typedef void (*MobileInstallationCallback)(CFDictionaryRef information);

/*!
 *  @brief  Mobile Installation 安装App (8.0)
 *  @param  bundlePath          IPA文件路径
 *  @param  parameters          unknown
 *  @param  unknown1            unknown
 *  @param  unknown2            unknown
 */

extern int MobileInstallationInstallForLaunchServices(CFStringRef bundlePath, CFDictionaryRef parameters, void *unknown1, void *unknown2) NS_AVAILABLE_IOS(8_0);
/*!
 *  @brief  Mobile Installation 卸载App (8.0)
 *  @param  bundleIdentifier    App的Bundle ID
 *  @param  parameters          unknown
 *  @param  callback            Mobile Installation 的回调
 *  @param  unknown             unknown
 */

extern int MobileInstallationUninstallForLaunchServices(CFStringRef bundleIdentifier, CFDictionaryRef parameters, MobileInstallationCallback callback, void *unknown) NS_AVAILABLE_IOS(8_0);

/*!
 *  @brief  为了稍后使用POSIX SPAWN
 */

extern char **environ;

/*!
 *  @brief  更新SpringBoard图标, 依赖uicache
 */

void uicache(void);

void uicache(void){
    posix_spawnattr_t attr;
    posix_spawn_file_actions_t fact;
    pid_t pid;
    char cmd[]="uicache";
    char *args[2];
args[0]=cmd;
args[1]=NULL;
    posix_spawnattr_init(&attr);
    posix_spawn_file_actions_init(&fact);
    posix_spawn(&pid,"/usr/bin/uicache",&fact,&attr,args,environ);
    int stat=0;
    waitpid(pid,&stat,0);
}

int main (int argc, const char * argv[]){
    @autoreleasepool{

#pragma mark
#pragma mark - Install
        CFStringRef path = CFStringCreateWithCString(kCFAllocatorDefault, "/PATH/TO/IPA/FILE", kCFStringEncodingUTF8);

        MobileInstallationInstallForLaunchServices(path, NULLNULLNULL);

#pragma mark
#pragma mark - Uninstall

        CFStringRef identifier = CFStringCreateWithCString(kCFAllocatorDefault, "APP.BUNDLE.ID", kCFStringEncodingUTF8);
        if (identifier != NULL) {
            MobileInstallationUninstallForLaunchServices(identifier, NULL, NULL, NULL);

            CFRelease(identifier);
        }

#pragma mark
#pragma mark - UICache

        uicache();

    }
    return 0;
}

声明: 本文为0xBBC原创, 转载注明出处喵~

《iOS8下代码安装/卸载APP》有13个想法

  1. uicache函数有泄露哦,需要补上:

    posix_spawnattr_destroy(&attr);
    posix_spawn_file_actions_destroy(&fact);

  2. 我是卸载了之后,uicache,图标还是存在,需要重启iOS图标才会消掉。这个要咋搞呢?

    1. 必须是越狱手机才可以吗 你用的是越狱手机吗 我现在为什么导进去那个私有库就报错呢

  3. 楼主,用这个安装卸载方法。重复安装卸载。在某一次,可能会出现个问题。就是桌面的图标点击崩溃。看了下崩溃的原因。是因为桌面图标链接的地址,还是上一次安装的app遗留下来的地址。感觉uicache好像没有起作用呢?

    1. 需要在Cydia里手动安装uicache这个util,我这里只是调用它。另外如果安装了也不行的话,那可能就是uicache本身的原因了。我只测试到iOS 8,之后的系统没再试过。

  4. 加上entitlements 真机调试运行报如下错误
    The executable was signed with invalid entitlements.

    The entitlements specified in your application’s Code Signing Entitlements file do not match those specified in your provisioning profile. (0xE8008016).

    去掉entitlements 能正常调试运行。
    这个有没有碰到?

  5. 你好啊,博主,使用的你代码,不能安装ipa啊
    我已经把MobileInstallation.framwork添加到项目,签上MobileInstallation的entitlements了
    调用接口 阻塞很久之后,方法MobileInstallationInstallForLaunchServices返回0,但是在springboard没有看到有app被装上,求指教

  6. 博主,你好,感谢你的分享,不过有两个问题想问一下:
    1.私有API的参数是怎么分析出来的?
    2.这里只列出了安装卸载的API,请问如何获取已安装应用列表,旧版的API是MobileInstallationBrowse,不知道新版的叫什么?

  7. hi,楼主你的博客对我帮助很大 ,这些api能在ios8非越狱的环境下使用吗,我用你的demo 无法链接到MobileInstallation.framwork,请问你这个安装和卸载的方法不需要自己实现?非常希望您能解答我的疑惑,万分感谢

    1. 非越狱的环境下,估计企业签名/开发者签名可以,但是要上架App Store的程序肯定不行。
      MobileInstallation.framwork需要自己从PrivateFrameworks复制出来,然后在Build Phase里手动link一下。
      这个安装和卸载的方法是iOS的私有方法,在MobileInstallation里实现的,你还需要签上MobileInstallation的entitlements。

发表评论

电子邮件地址不会被公开。 必填项已用*标注