2022-09-02 23:19:48 +08:00
# import "TSApplicationsManager.h"
# import "TSUtil.h"
# import "../Helper/Shared.h"
2022-09-03 09:08:59 +08:00
# define TrollStoreErrorDomain @ "TrollStoreErrorDomain"
2022-09-02 23:19:48 +08:00
@ implementation TSApplicationsManager
+ ( instancetype ) sharedInstance
{
static TSApplicationsManager * sharedInstance = nil ;
static dispatch_once _t onceToken ;
dispatch_once ( & onceToken , ^ {
sharedInstance = [ [ TSApplicationsManager alloc ] init ] ;
} ) ;
return sharedInstance ;
}
- ( NSArray * ) installedAppPaths
{
return trollStoreInstalledAppBundlePaths ( ) ;
}
- ( NSDictionary * ) infoDictionaryForAppPath : ( NSString * ) appPath
{
NSString * infoPlistPath = [ appPath stringByAppendingPathComponent : @ "Info.plist" ] ;
2022-09-10 02:22:34 +08:00
NSError * error ;
NSDictionary * infoDict = [ NSDictionary dictionaryWithContentsOfURL : [ NSURL fileURLWithPath : infoPlistPath ] error : & error ] ;
if ( error )
{
NSLog ( @ "error getting info dict: %@" , error ) ;
}
return infoDict ;
2022-09-02 23:19:48 +08:00
}
- ( NSString * ) appIdForAppPath : ( NSString * ) appPath
{
return [ self infoDictionaryForAppPath : appPath ] [ @ "CFBundleIdentifier" ] ;
}
- ( NSString * ) displayNameForAppPath : ( NSString * ) appPath
{
NSDictionary * infoDict = [ self infoDictionaryForAppPath : appPath ] ;
NSString * displayName = infoDict [ @ "CFBundleDisplayName" ] ;
if ( ! [ displayName isKindOfClass : [ NSString class ] ] ) displayName = nil ;
if ( ! displayName || [ displayName isEqualToString : @ "" ] )
{
displayName = infoDict [ @ "CFBundleName" ] ;
if ( ! [ displayName isKindOfClass : [ NSString class ] ] ) displayName = nil ;
if ( ! displayName || [ displayName isEqualToString : @ "" ] )
{
displayName = infoDict [ @ "CFBundleExecutable" ] ;
if ( ! [ displayName isKindOfClass : [ NSString class ] ] ) displayName = [ appPath lastPathComponent ] ;
}
}
return displayName ;
}
2022-09-03 09:08:59 +08:00
- ( NSError * ) errorForCode : ( int ) code
{
NSString * errorDescription = @ "Unknown Error" ;
switch ( code )
{
2022-09-10 02:22:34 +08:00
// IPA install errors
2022-09-03 09:08:59 +08:00
case 166 :
errorDescription = @ "The IPA file does not exist or is not accessible." ;
break ;
case 167 :
errorDescription = @ "The IPA file does not appear to contain an app." ;
break ;
2022-09-10 02:22:34 +08:00
// App install errors
2022-09-03 09:08:59 +08:00
case 170 :
errorDescription = @ "Failed to create container for app bundle." ;
break ;
case 171 :
2022-09-04 00:49:53 +08:00
errorDescription = @ "A non-TrollStore app with the same identifier is already installed. If you are absolutely sure it is not, you can force install it." ;
2022-09-03 09:08:59 +08:00
break ;
case 172 :
2022-09-10 02:22:34 +08:00
errorDescription = @ "The app does not contain an Info.plist file." ;
2022-09-03 09:08:59 +08:00
break ;
2022-09-06 07:04:10 +08:00
case 173 :
2022-09-10 02:22:34 +08:00
errorDescription = @ "The app is not signed with a fake CoreTrust certificate and ldid is not installed. Install ldid in the settings tab and try again." ;
break ;
case 174 :
errorDescription = @ "The apps main executable does not exists." ;
break ;
case 175 :
errorDescription = @ "Failed to sign the app. ldid returned a non zero status code." ;
break ;
case 176 :
errorDescription = @ "The apps Info.plist is missing required values." ;
break ;
case 177 :
errorDescription = @ "Failed to mark app as TrollStore app." ;
2022-09-06 07:04:10 +08:00
break ;
2022-09-10 02:22:34 +08:00
case 178 :
errorDescription = @ "Failed to copy app bundle." ;
break ;
// App detach errors
/ * case 184 :
errorDescription = @ "Refusing to detach, the app is still signed with a fake root certificate. The detach option is only for when you have installed an App Store app on top of a TrollStore app." ;
break ; * /
2022-09-03 09:08:59 +08:00
}
NSError * error = [ NSError errorWithDomain : TrollStoreErrorDomain code : code userInfo : @ { NSLocalizedDescriptionKey : errorDescription } ] ;
return error ;
}
2022-09-10 02:22:34 +08:00
- ( int ) installIpa : ( NSString * ) pathToIpa force : ( BOOL ) force log : ( NSString * * ) logOut
2022-09-02 23:19:48 +08:00
{
2022-09-04 00:49:53 +08:00
int ret ;
if ( force )
{
2022-09-10 02:22:34 +08:00
ret = spawnRoot ( helperPath ( ) , @ [ @ "install" , pathToIpa , @ "force" ] , nil , logOut ) ;
2022-09-04 00:49:53 +08:00
}
else
{
2022-09-10 02:22:34 +08:00
ret = spawnRoot ( helperPath ( ) , @ [ @ "install" , pathToIpa ] , nil , logOut ) ;
2022-09-04 00:49:53 +08:00
}
2022-09-02 23:19:48 +08:00
[ [ NSNotificationCenter defaultCenter ] postNotificationName : @ "ApplicationsChanged" object : nil ] ;
return ret ;
}
2022-09-04 00:49:53 +08:00
- ( int ) installIpa : ( NSString * ) pathToIpa
{
2022-09-10 02:22:34 +08:00
return [ self installIpa : pathToIpa force : NO log : nil ] ;
2022-09-04 00:49:53 +08:00
}
2022-09-03 09:08:59 +08:00
- ( int ) uninstallApp : ( NSString * ) appId
2022-09-02 23:19:48 +08:00
{
2022-09-04 21:37:49 +08:00
if ( ! appId ) return -200 ;
2022-09-10 02:22:34 +08:00
int ret = spawnRoot ( helperPath ( ) , @ [ @ "uninstall" , appId ] , nil , nil ) ;
2022-09-02 23:19:48 +08:00
[ [ NSNotificationCenter defaultCenter ] postNotificationName : @ "ApplicationsChanged" object : nil ] ;
return ret ;
}
2022-09-04 21:37:49 +08:00
- ( int ) uninstallAppByPath : ( NSString * ) path
{
if ( ! path ) return -200 ;
2022-09-10 02:22:34 +08:00
int ret = spawnRoot ( helperPath ( ) , @ [ @ "uninstall-path" , path ] , nil , nil ) ;
2022-09-04 21:37:49 +08:00
[ [ NSNotificationCenter defaultCenter ] postNotificationName : @ "ApplicationsChanged" object : nil ] ;
return ret ;
}
2022-09-10 02:22:34 +08:00
/ * - ( int ) detachFromApp : ( NSString * ) appId
{
if ( ! appId ) return -200 ;
int ret = spawnRoot ( helperPath ( ) , @ [ @ "detach" , appId ] , nil , nil ) ;
[ [ NSNotificationCenter defaultCenter ] postNotificationName : @ "ApplicationsChanged" object : nil ] ;
return ret ;
} * /
2022-09-02 23:19:48 +08:00
@ end