mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-20 20:23:25 +01:00
[AltServer] Improves handling of errors when installing apps
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
extern NSErrorDomain const AltServerErrorDomain;
|
extern NSErrorDomain const AltServerErrorDomain;
|
||||||
|
extern NSErrorDomain const AltServerInstallationErrorDomain;
|
||||||
|
|
||||||
typedef NS_ERROR_ENUM(AltServerErrorDomain, ALTServerError)
|
typedef NS_ERROR_ENUM(AltServerErrorDomain, ALTServerError)
|
||||||
{
|
{
|
||||||
@@ -23,6 +24,8 @@ typedef NS_ERROR_ENUM(AltServerErrorDomain, ALTServerError)
|
|||||||
ALTServerErrorInvalidResponse,
|
ALTServerErrorInvalidResponse,
|
||||||
|
|
||||||
ALTServerErrorInvalidApp,
|
ALTServerErrorInvalidApp,
|
||||||
|
ALTServerErrorInstallationFailed,
|
||||||
|
ALTServerErrorMaximumFreeAppLimitReached,
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|||||||
@@ -9,6 +9,56 @@
|
|||||||
#import "NSError+ALTServerError.h"
|
#import "NSError+ALTServerError.h"
|
||||||
|
|
||||||
NSErrorDomain const AltServerErrorDomain = @"com.rileytestut.AltServer";
|
NSErrorDomain const AltServerErrorDomain = @"com.rileytestut.AltServer";
|
||||||
|
NSErrorDomain const AltServerInstallationErrorDomain = @"com.rileytestut.AltServer.Installation";
|
||||||
|
|
||||||
@implementation NSError (ALTServerError)
|
@implementation NSError (ALTServerError)
|
||||||
|
|
||||||
|
+ (void)load
|
||||||
|
{
|
||||||
|
[NSError setUserInfoValueProviderForDomain:AltServerErrorDomain provider:^id _Nullable(NSError * _Nonnull error, NSErrorUserInfoKey _Nonnull userInfoKey) {
|
||||||
|
if ([userInfoKey isEqualToString:NSLocalizedFailureReasonErrorKey])
|
||||||
|
{
|
||||||
|
return [error alt_localizedDescription];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable NSString *)alt_localizedDescription
|
||||||
|
{
|
||||||
|
switch ((ALTServerError)self.code)
|
||||||
|
{
|
||||||
|
case ALTServerErrorUnknown:
|
||||||
|
return NSLocalizedString(@"An unknown error occured.", @"");
|
||||||
|
|
||||||
|
case ALTServerErrorConnectionFailed:
|
||||||
|
return NSLocalizedString(@"Could not connect to AltServer.", @"");
|
||||||
|
|
||||||
|
case ALTServerErrorLostConnection:
|
||||||
|
return NSLocalizedString(@"Lost connection to AltServer.", @"");
|
||||||
|
|
||||||
|
case ALTServerErrorDeviceNotFound:
|
||||||
|
return NSLocalizedString(@"AltServer could not locate this device", @"");
|
||||||
|
|
||||||
|
case ALTServerErrorDeviceWriteFailed:
|
||||||
|
return NSLocalizedString(@"Failed to write app data to phone.", @"");
|
||||||
|
|
||||||
|
case ALTServerErrorInvalidRequest:
|
||||||
|
return NSLocalizedString(@"AltServer received an invalid request.", @"");
|
||||||
|
|
||||||
|
case ALTServerErrorInvalidResponse:
|
||||||
|
return NSLocalizedString(@"AltServer sent an invalid response.", @"");
|
||||||
|
|
||||||
|
case ALTServerErrorInvalidApp:
|
||||||
|
return NSLocalizedString(@"The app is invalid.", @"");
|
||||||
|
|
||||||
|
case ALTServerErrorInstallationFailed:
|
||||||
|
return NSLocalizedString(@"An error occured while installing the app.", @"");
|
||||||
|
|
||||||
|
case ALTServerErrorMaximumFreeAppLimitReached:
|
||||||
|
return NSLocalizedString(@"You have reached the limit of 3 apps per device.", @"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -15,16 +15,14 @@
|
|||||||
#include <libimobiledevice/notification_proxy.h>
|
#include <libimobiledevice/notification_proxy.h>
|
||||||
#include <libimobiledevice/afc.h>
|
#include <libimobiledevice/afc.h>
|
||||||
|
|
||||||
void ALTDeviceManagerDidFinishAppInstallation(const char *notification, void *udid);
|
|
||||||
void ALTDeviceManagerUpdateStatus(plist_t command, plist_t status, void *udid);
|
void ALTDeviceManagerUpdateStatus(plist_t command, plist_t status, void *udid);
|
||||||
|
|
||||||
NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
||||||
|
|
||||||
@interface ALTDeviceManager ()
|
@interface ALTDeviceManager ()
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSMutableDictionary<NSUUID *, void (^)(void)> *installationCompletionHandlers;
|
@property (nonatomic, readonly) NSMutableDictionary<NSUUID *, void (^)(NSError *)> *installationCompletionHandlers;
|
||||||
@property (nonatomic, readonly) NSMutableDictionary<NSUUID *, NSProgress *> *installationProgress;
|
@property (nonatomic, readonly) NSMutableDictionary<NSUUID *, NSProgress *> *installationProgress;
|
||||||
@property (nonatomic, readonly) NSMutableDictionary<NSUUID *, NSValue *> *installationClients;
|
|
||||||
@property (nonatomic, readonly) dispatch_queue_t installationQueue;
|
@property (nonatomic, readonly) dispatch_queue_t installationQueue;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -49,7 +47,6 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
|||||||
{
|
{
|
||||||
_installationCompletionHandlers = [NSMutableDictionary dictionary];
|
_installationCompletionHandlers = [NSMutableDictionary dictionary];
|
||||||
_installationProgress = [NSMutableDictionary dictionary];
|
_installationProgress = [NSMutableDictionary dictionary];
|
||||||
_installationClients = [NSMutableDictionary dictionary];
|
|
||||||
|
|
||||||
_installationQueue = dispatch_queue_create("com.rileytestut.AltServer.InstallationQueue", DISPATCH_QUEUE_SERIAL);
|
_installationQueue = dispatch_queue_create("com.rileytestut.AltServer.InstallationQueue", DISPATCH_QUEUE_SERIAL);
|
||||||
}
|
}
|
||||||
@@ -75,7 +72,7 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
|||||||
lockdownd_service_descriptor_t service = NULL;
|
lockdownd_service_descriptor_t service = NULL;
|
||||||
|
|
||||||
void (^finish)(NSError *error) = ^(NSError *error) {
|
void (^finish)(NSError *error) = ^(NSError *error) {
|
||||||
np_client_free(np);
|
|
||||||
instproxy_client_free(ipc);
|
instproxy_client_free(ipc);
|
||||||
afc_client_free(afc);
|
afc_client_free(afc);
|
||||||
lockdownd_client_free(client);
|
lockdownd_client_free(client);
|
||||||
@@ -138,28 +135,6 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
|||||||
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connect to Notification Proxy */
|
|
||||||
if ((lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &service) != LOCKDOWN_E_SUCCESS) || service == NULL)
|
|
||||||
{
|
|
||||||
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (np_client_new(device, service, &np) != NP_E_SUCCESS)
|
|
||||||
{
|
|
||||||
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
|
||||||
}
|
|
||||||
|
|
||||||
np_set_notify_callback(np, ALTDeviceManagerDidFinishAppInstallation, uuidString);
|
|
||||||
|
|
||||||
const char *notifications[2] = { NP_APP_INSTALLED, NULL };
|
|
||||||
np_observe_notifications(np, notifications);
|
|
||||||
|
|
||||||
if (service)
|
|
||||||
{
|
|
||||||
lockdownd_service_descriptor_free(service);
|
|
||||||
service = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Connect to Installation Proxy */
|
/* Connect to Installation Proxy */
|
||||||
if ((lockdownd_start_service(client, "com.apple.mobile.installation_proxy", &service) != LOCKDOWN_E_SUCCESS) || service == NULL)
|
if ((lockdownd_start_service(client, "com.apple.mobile.installation_proxy", &service) != LOCKDOWN_E_SUCCESS) || service == NULL)
|
||||||
{
|
{
|
||||||
@@ -177,18 +152,12 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
|||||||
service = NULL;
|
service = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lockdownd_service_descriptor_free(service);
|
|
||||||
service = NULL;
|
|
||||||
|
|
||||||
/* Connect to AFC service */
|
/* Connect to AFC service */
|
||||||
if ((lockdownd_start_service(client, "com.apple.afc", &service) != LOCKDOWN_E_SUCCESS) || service == NULL)
|
if ((lockdownd_start_service(client, "com.apple.afc", &service) != LOCKDOWN_E_SUCCESS) || service == NULL)
|
||||||
{
|
{
|
||||||
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
lockdownd_client_free(client);
|
|
||||||
client = NULL;
|
|
||||||
|
|
||||||
if (afc_client_new(device, service, &afc) != AFC_E_SUCCESS)
|
if (afc_client_new(device, service, &afc) != AFC_E_SUCCESS)
|
||||||
{
|
{
|
||||||
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorConnectionFailed userInfo:nil]);
|
||||||
@@ -239,12 +208,11 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
|||||||
|
|
||||||
NSProgress *installationProgress = [NSProgress progressWithTotalUnitCount:100 parent:progress pendingUnitCount:1];
|
NSProgress *installationProgress = [NSProgress progressWithTotalUnitCount:100 parent:progress pendingUnitCount:1];
|
||||||
|
|
||||||
NSValue *value = [NSValue valueWithPointer:(const void *)np];
|
NSProgress *installationProgress = [NSProgress progressWithTotalUnitCount:100 parent:progress pendingUnitCount:1];
|
||||||
|
|
||||||
self.installationClients[UUID] = value;
|
|
||||||
self.installationProgress[UUID] = installationProgress;
|
self.installationProgress[UUID] = installationProgress;
|
||||||
self.installationCompletionHandlers[UUID] = ^{
|
self.installationCompletionHandlers[UUID] = ^(NSError *error) {
|
||||||
finish(nil);
|
finish(error);
|
||||||
|
|
||||||
if (temporaryDirectoryURL != nil)
|
if (temporaryDirectoryURL != nil)
|
||||||
{
|
{
|
||||||
@@ -470,29 +438,6 @@ NSErrorDomain const ALTDeviceErrorDomain = @"com.rileytestut.ALTDeviceError";
|
|||||||
|
|
||||||
#pragma mark - Callbacks -
|
#pragma mark - Callbacks -
|
||||||
|
|
||||||
void ALTDeviceManagerDidFinishAppInstallation(const char *notification, void *uuid)
|
|
||||||
{
|
|
||||||
NSUUID *UUID = [[NSUUID alloc] initWithUUIDString:[NSString stringWithUTF8String:(const char *)uuid]];
|
|
||||||
|
|
||||||
void (^completionHandler)(void) = ALTDeviceManager.sharedManager.installationCompletionHandlers[UUID];
|
|
||||||
if (completionHandler != nil)
|
|
||||||
{
|
|
||||||
completionHandler();
|
|
||||||
|
|
||||||
ALTDeviceManager.sharedManager.installationCompletionHandlers[UUID] = nil;
|
|
||||||
ALTDeviceManager.sharedManager.installationProgress[UUID] = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSValue *value = ALTDeviceManager.sharedManager.installationClients[UUID];
|
|
||||||
if (value != nil)
|
|
||||||
{
|
|
||||||
np_client_t np = (np_client_t)value.pointerValue;
|
|
||||||
np_set_notify_callback(np, NULL, uuid);
|
|
||||||
|
|
||||||
ALTDeviceManager.sharedManager.installationClients[UUID] = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALTDeviceManagerUpdateStatus(plist_t command, plist_t status, void *uuid)
|
void ALTDeviceManagerUpdateStatus(plist_t command, plist_t status, void *uuid)
|
||||||
{
|
{
|
||||||
NSUUID *UUID = [[NSUUID alloc] initWithUUIDString:[NSString stringWithUTF8String:(const char *)uuid]];
|
NSUUID *UUID = [[NSUUID alloc] initWithUUIDString:[NSString stringWithUTF8String:(const char *)uuid]];
|
||||||
@@ -506,7 +451,46 @@ void ALTDeviceManagerUpdateStatus(plist_t command, plist_t status, void *uuid)
|
|||||||
int percent = -1;
|
int percent = -1;
|
||||||
instproxy_status_get_percent_complete(status, &percent);
|
instproxy_status_get_percent_complete(status, &percent);
|
||||||
|
|
||||||
if (progress.completedUnitCount < percent)
|
char *name = NULL;
|
||||||
|
char *description = NULL;
|
||||||
|
uint64_t code = 0;
|
||||||
|
instproxy_status_get_error(status, &name, &description, &code);
|
||||||
|
|
||||||
|
if ((percent == -1 && progress.completedUnitCount > 0) || code != 0)
|
||||||
|
{
|
||||||
|
void (^completionHandler)(NSError *) = ALTDeviceManager.sharedManager.installationCompletionHandlers[UUID];
|
||||||
|
if (completionHandler != nil)
|
||||||
|
{
|
||||||
|
if (code != 0)
|
||||||
|
{
|
||||||
|
NSLog(@"Error installing app. %@ (%@). %@", @(code), @(name), @(description));
|
||||||
|
|
||||||
|
NSError *error = nil;
|
||||||
|
|
||||||
|
if (code == 3892346913)
|
||||||
|
{
|
||||||
|
error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorMaximumFreeAppLimitReached userInfo:nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSError *underlyingError = [NSError errorWithDomain:AltServerInstallationErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey: @(description)}];
|
||||||
|
|
||||||
|
error = [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorInstallationFailed userInfo:@{NSUnderlyingErrorKey: underlyingError}];
|
||||||
|
}
|
||||||
|
|
||||||
|
completionHandler(error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSLog(@"Finished installing app!");
|
||||||
|
completionHandler(nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALTDeviceManager.sharedManager.installationCompletionHandlers[UUID] = nil;
|
||||||
|
ALTDeviceManager.sharedManager.installationProgress[UUID] = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (progress.completedUnitCount < percent)
|
||||||
{
|
{
|
||||||
progress.completedUnitCount = percent;
|
progress.completedUnitCount = percent;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user