我尝试编写应用程序,它可以从Web服务器(ipa文件)下载应用程序并安装它。有谁知道如何安装这个ipa文件?我可以使用应用程序内部的OTA或使用命令行来安装它吗?
答案 0 :(得分:6)
因此,这是越狱设备的即时解决方案,可以直接在您的应用程序中安装任何.ipa
文件。您必须采取的步骤是:
予。获得root访问权限。您可以通过setuid(0);
功能调用main()
来实现此目的。您需要在可执行文件上设置粘性权限位并使用启动脚本。
II。解压缩.ipa
文件。是的,没错 - IPA只是伪装的ZIP文件。您可以使用opensource libzip库。
III。里面会有一个名为Payload
的目录。实际的应用包(我们称之为MyApp.app
)将驻留在该文件夹中。
IV。在文件系统的/var/mobile/Applications
目录中创建一个目录。这将是要安装的应用程序的容器沙箱。按照惯例,此目录的名称应为UUID。例如,您可以使用以下代码段:
CFUUIDRef uuidObj = CFUUIDCreate(NULL);
CFStringRef uuid = CFUUIDCreateString(NULL, uuidObj);
CFRelease(uuidObj);
NSString *appPath = [@"/var/mobile/Applications" stringByAppendingPathComponent:(id)uuid];
[fmgr createDirectoryAtPath:appPath withIntermediateDirectories:YES attributes:nil error:NULL];
CFRelease(uuid);
诉通过循环遍历Payload
目录(在步骤II中获得)的内容来查找应用程序包。将其复制到新创建的沙箱(其名称为UUID字符串)。同时复制iTunesMetadata.plist
和iTunesArtwork
文件,以便iTunes为应用程序显示一个漂亮的图标并通知您更新。修复应用程序可执行文件的权限,使其可执行:
NSString *execName = [appInfoPlist objectForKey:@"CFBundleExecutable"];
NSString *execPath = [bundle stringByAppendingPathComponent:execName];
chmod(execPath.UTF8String, 0755);
VI。您需要告诉SpringBoard找到您的应用程序,然后重新加载其已安装的应用程序缓存,以使新安装的图标显示在主屏幕上。为此,首先更新MobileInstallation属性列表文件中的应用程序列表。这里bundle
变量指的是应用包的文件系统位置,类似于/var/mobile/applications/LONG_UUID_STRING/MyApp.app
。
#define kMobileInstallationPlistPath @"/var/mobile/Library/Caches/com.apple.mobile.installation.plist"
NSMutableDictionary *appInfoPlist = [NSMutableDictionary dictionaryWithContentsOfFile:[bundle stringByAppendingPathComponent:@"Info.plist"]];
[appInfoPlist setObject:@"User" forKey:@"ApplicationType"];
[appInfoPlist setObject:bundle forKey:@"Path"];
[appInfoPlist setObject:@{
@"CFFIXED_USER_HOME" : appPath,
@"HOME" : appPath,
@"TMPDIR" : [appPath stringByAppendingPathComponent:@"tmp"]
} forKey:@"EnvironmentVariables"];
[appInfoPlist setObject:appPath forKey:@"Container"];
NSData *data = [NSData dataWithContentsOfFile:kMobileInstallationPlistPath];
NSMutableDictionary *mobileInstallation = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:NULL error:NULL];
NSString *bundleID = [appInfoPlist objectForKey:@"CFBundleIdentifier"];
[[mobileInstallation objectForKey:@"User"] setObject:appInfoPlist forKey:bundleID];
[mobileInstallation writeToFile:kMobileInstallationPlistPath atomically:NO];
然后删除SpringBoard存储的缓存应用程序信息:
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");
然后通知SpringBoard重新加载所有应用程序的列表:
Class __LSApplicationWorkspace = objc_getClass("LSApplicationWorkspace");
[(LSApplicationWorkspace *)[__LSApplicationWorkspace defaultWorkspace] invalidateIconCache:nil];
[(LSApplicationWorkspace *)[__LSApplicationWorkspace defaultWorkspace] registerApplication:[NSURL fileURLWithPath:bundle]];
notify_post("com.apple.mobile.application_installed");
答案 1 :(得分:2)
您可以通过OTA分发执行此操作,请参阅 http://help.apple.com/iosdeployment-apps/mac/1.1/#app43ad871e
可在此处找到示例plist: https://gist.github.com/hramos/774468
请注意,您需要企业开发人员计划或收集用户的UDID并将其包含在您的ad-hoc配置文件中。