From d9d857e90e79f862677969dbbde21e31458a0a47 Mon Sep 17 00:00:00 2001 From: Pal Lockheart Date: Sat, 3 Dec 2016 21:30:28 +0800 Subject: [PATCH 1/2] iOS9.3 patch --- CyDelete.xm | 164 +++++++++++++----- CyDelete/CyDeleteListController.mm | 10 +- CyDelete/Makefile | 2 +- CyDelete/Resources/CyDelete.plist | 4 +- CyDelete/Resources/Pangu.png | Bin 29680 -> 19405 bytes .../Resources/en.lproj/Localizable.strings | 13 +- .../Resources/pt_PT.lproj/Localizable.strings | 5 +- .../Resources/zh_CN.lproj/Localizable.strings | 24 ++- CyDelete/theos | 2 +- Makefile | 4 +- README.md | 2 +- layout/DEBIAN/control | 14 +- layout/DEBIAN/postinst | 6 + setuid/Makefile | 4 - theos | 2 +- 15 files changed, 186 insertions(+), 70 deletions(-) create mode 100755 layout/DEBIAN/postinst diff --git a/CyDelete.xm b/CyDelete.xm index 634245d..d49aeca 100644 --- a/CyDelete.xm +++ b/CyDelete.xm @@ -1,14 +1,18 @@ // -// CyDelete8.xm -// CyDelete8 +// CyDelete.xm +// CyDelete // // Created by Ryan Burke on 02.01.2014. // Copyright (c) 2014 Ryan Burke. All rights reserved. // +// Modified by Pal Lockheart on 12.04.2016. +// Copyright (c) 2016 Pal Lockheart. All rights reserved. +// #import #import #include +#import #import #import #import @@ -165,6 +169,14 @@ static id ownerForSBApplication(SBApplication *application) { return package; } +static BOOL isOfficialUninstallable(SBApplication *application) { + return [application isSystemApplication] + || [application isInternalApplication] + || [application isWebApplication] + || [[application path] hasPrefix:@"/private/var/mobile/Containers/Bundle/Application"] //iOS 9.1.x- + || [[application path] hasPrefix:@"/private/var/containers/Bundle/Application"]; //iOS 9.2.x+ +} + @implementation CDUninstallOperation - (id)init { if((self = [super init]) != nil) { @@ -219,7 +231,7 @@ static id ownerForSBApplication(SBApplication *application) { - (void)displayError { NSString *body = [NSString stringWithFormat:CDLocalizedString(@"PACKAGE_UNINSTALL_ERROR_BODY"), _package]; UIAlertView *delView = [[UIAlertView alloc] initWithTitle:CDLocalizedString(@"PACKAGE_UNINSTALL_ERROR_TITLE") message:body delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil]; - [delView show]; + [delView show]; } -(void)displayRespring { @@ -283,10 +295,10 @@ static void removeBundleFromMIList(NSString *bundle) { //Show the user an error message warning them that we didn't remove the application. NSString *nonCydiaText = [NSString stringWithFormat:CDLocalizedString(@"PACKAGE_NOT_CYDIA_BODY"), package]; UIAlertView *nonCydiaAlert = [[UIAlertView alloc] initWithTitle:CDLocalizedString(@"PACKAGE_NOT_CYDIA_TITLE") - message:nonCydiaText - delegate:nil - cancelButtonTitle:@"Okay" - otherButtonTitles:nil]; + message:nonCydiaText + delegate:nil + cancelButtonTitle:@"Okay" + otherButtonTitles:nil]; [nonCydiaAlert show]; } else { @@ -298,10 +310,31 @@ static void removeBundleFromMIList(NSString *bundle) { } %end -@interface SBApplicationIcon (CyDelete) - -(BOOL)cydelete_allowsUninstall; - -(void)cydelete_uninstallClicked; -@end +static BOOL cydelete_IOSVersionAbove92() { + return kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_9_2; +} + +static BOOL cydelete_allowsUninstall(SBIcon *arg) { + //Get the bundle ID for this application. + NSString *bundle = nil; + if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) { + bundle = [[arg application] bundleIdentifier]; + } + else { + bundle = [[arg application] displayName]; + } + //If the application is an Apple application. + bool isApple = ([bundle hasPrefix:@"com.apple."] && ![bundle hasPrefix:@"com.apple.samplecode."]); + //If the application is Cydia and user has protected it. + bool isCydia = ([bundle isEqualToString:@"com.saurik.Cydia"] && getProtectCydia()); + //If the application is Cydia and user has protected it. + bool isPangu = ([bundle isEqualToString:@"io.pangu.nvwastone"] && getProtectPangu()); + //If any of these match then we don't want to allow uninstall. + if(isApple || isCydia || isPangu || !getEnabled() || getFreeMemory() < 20 ) { + return NO; + } + return YES; +} static void uninstallClickedForIcon(SBIcon *self) { //Get the application for this icon. @@ -325,59 +358,93 @@ static void uninstallClickedForIcon(SBIcon *self) { } } +static BOOL _forceCydia; +@interface SBApplicationIcon(CyDelete) +@property (nonatomic) BOOL forceCydia; +@end + + +@interface LSApplicationWorkspace : NSObject ++ (id) defaultWorkspace; +- (BOOL) unregisterApplication:(id)application; +- (BOOL) registerApplicationDictionary:(id)application; +@end + %hook SBIconController + - (_Bool)iconViewDisplaysCloseBox:(id)arg1{ + if([arg1 class] != %c(SBIconView) && [arg1 class] != %c(SBActivatorIcon)) { + return %orig(arg1); + } + SBIconView *iconView = arg1; + SBIcon *icon = [iconView icon]; + return cydelete_allowsUninstall(icon); + } - (void)iconCloseBoxTapped:(id)_i { %log; SBIconView *iconView = _i; SBIcon *icon = [iconView icon]; + SBApplicationIcon *appicon = (SBApplicationIcon *)icon; SBApplication *app = [icon application]; id pkgName = ownerForSBApplication(app); if(pkgName != [NSNull null]) { uninstallClickedForIcon(icon); } - %orig; + if(cydelete_IOSVersionAbove92() && [[iconPackagesDict allKeys] containsObject:[app bundleIdentifier]]) { + //new mechanism: iOS 9.2 above will not automatically trigger uninstall, we've to call it manually + BOOL contains = NO; + for(CDUninstallDpkgOperation *operation in [uninstallQueue operations]){ + if([operation.package isEqualToString:[app bundleIdentifier]]){ + contains = YES; + break; + } + } + if(contains) { + UIAlertController* alert=[UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"%@ IS uninstalling",[app displayName]] message:@"Please WAIT A SEC" preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController: alert animated:YES completion:nil]; + }else{ + appicon.forceCydia = YES; + UIAlertController* alert=[UIAlertController alertControllerWithTitle:[appicon uninstallAlertTitle] message:[appicon uninstallAlertBody] preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:[appicon uninstallAlertCancelTitle] style:UIAlertActionStyleDefault handler:nil]]; + [alert addAction:[UIAlertAction actionWithTitle:[appicon uninstallAlertConfirmTitle] style:UIAlertActionStyleCancel handler:^(UIAlertAction* _Nonnull action) + { + Class $LSApplicationWorkspace = objc_getClass("LSApplicationWorkspace"); + [[$LSApplicationWorkspace defaultWorkspace] unregisterApplication:[NSURL fileURLWithPath:[app path]]]; + Class $SBApplicationController = objc_getClass("SBApplicationController"); + [[$SBApplicationController sharedInstance] uninstallApplication:app]; + }]]; + appicon.forceCydia = NO; + [self presentViewController: alert animated:YES completion:nil]; + } + }else{ + %orig; + } } %end %hook SBApplicationIcon - - %new(c@:) - -(BOOL)cydelete_allowsUninstall { - //Get the bundle ID for this application. - NSString *bundle = nil; - if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) { - bundle = [[self application] bundleIdentifier]; - } - else { - bundle = [[self application] displayName]; - } - //If the application is an Apple application. - bool isApple = ([bundle hasPrefix:@"com.apple."] && ![bundle hasPrefix:@"com.apple.samplecode."]); - //If the application is Cydia and user has protected it. - bool isCydia = ([bundle isEqualToString:@"com.saurik.Cydia"] && getProtectCydia()); - //If the application is Cydia and user has protected it. - bool isPangu = ([bundle isEqualToString:@"io.pangu.loader"] && getProtectPangu()); - //If any of these match then we don't want to allow uninstall. - if(isApple || isCydia || isPangu || !getEnabled() || getFreeMemory() < 20 ) { - return NO; - } - return YES; + %new + - (BOOL)forceCydia{ + return _forceCydia; + } + %new + - (void)setForceCydia:(BOOL)force{ + _forceCydia = force; } + //iOS 7/8/9.0-9.1 compatible code -(BOOL)allowsCloseBox { if([self class] != %c(SBApplicationIcon) && [self class] != %c(SBActivatorIcon)) { return %orig; } - return [self cydelete_allowsUninstall]; + return cydelete_allowsUninstall(self); } - -(BOOL)allowsUninstall { if([self class] != %c(SBApplicationIcon) && [self class] != %c(SBActivatorIcon)) { return %orig; } - return [self cydelete_allowsUninstall]; + return cydelete_allowsUninstall(self); } - -(void)closeBoxClicked:(id)event { if([self class] != %c(SBApplicationIcon) && [self class] != %c(SBActivatorIcon)) { %orig; @@ -386,7 +453,6 @@ static void uninstallClickedForIcon(SBIcon *self) { uninstallClickedForIcon(self); %orig; } - -(void)uninstallClicked:(id)event { if([self class] != %c(SBApplicationIcon) && [self class] != %c(SBActivatorIcon)) { %orig; @@ -397,11 +463,17 @@ static void uninstallClickedForIcon(SBIcon *self) { } -(NSString *)uninstallAlertTitle { - return [NSString stringWithFormat:SBLocalizedString(@"UNINSTALL_ICON_TITLE"), + %log; + if(!_forceCydia && isOfficialUninstallable([self application])) + return %orig; + return [NSString stringWithFormat:cydelete_IOSVersionAbove92() ? SBLocalizedString(@"UNINSTALL_ICON_TITLE_DELETE_WITH_NAME") : SBLocalizedString(@"UNINSTALL_ICON_TITLE"), [[self application] displayName]]; } -(NSString *)uninstallAlertBody { + %log; + if(!_forceCydia && isOfficialUninstallable([self application])) + return %orig; NSString *bundle = nil; @@ -427,11 +499,17 @@ static void uninstallClickedForIcon(SBIcon *self) { } -(NSString *)uninstallAlertConfirmTitle { - return SBLocalizedString(@"UNINSTALL_ICON_CONFIRM"); + %log; + if(!_forceCydia && isOfficialUninstallable([self application])) + return %orig; + return cydelete_IOSVersionAbove92() ? SBLocalizedString(@"UNINSTALL_ICON_BUTTON_DELETE") : SBLocalizedString(@"UNINSTALL_ICON_CONFIRM"); } -(NSString *)uninstallAlertCancelTitle { - return SBLocalizedString(@"UNINSTALL_ICON_CANCEL"); + %log; + if(!_forceCydia && isOfficialUninstallable([self application])) + return %orig; + return cydelete_IOSVersionAbove92() ? SBLocalizedString(@"UNINSTALL_ICON_BUTTON_CANCEL") : SBLocalizedString(@"UNINSTALL_ICON_CANCEL"); } %end @@ -441,4 +519,4 @@ static void uninstallClickedForIcon(SBIcon *self) { iconPackagesDict = [[NSMutableDictionary alloc] init]; uninstallQueue = [[NSOperationQueue alloc] init]; [uninstallQueue setMaxConcurrentOperationCount:1]; -} +} \ No newline at end of file diff --git a/CyDelete/CyDeleteListController.mm b/CyDelete/CyDeleteListController.mm index 1f1d775..29ebfc6 100644 --- a/CyDelete/CyDeleteListController.mm +++ b/CyDelete/CyDeleteListController.mm @@ -11,7 +11,7 @@ @interface CyDeleteListController : PSListController - (id)specifiers; -- (void)ryanDonate:(id)arg; +- (void)donate:(id)arg; - (void)viewSource:(id)arg; @end @@ -30,6 +30,10 @@ - (id)navigationTitle { return [[self bundle] localizedStringForKey:[super title] value:[super title] table:nil]; } +- (id)localized:(NSString *)key{ + return [[self bundle] localizedStringForKey:key value:key table:nil]; +} + - (id)localizedSpecifiersWithSpecifiers:(NSArray *)specifiers { NSLog(@"localizedSpecifiersWithSpecifiers"); @@ -54,8 +58,8 @@ - (id)localizedSpecifiersWithSpecifiers:(NSArray *)specifiers { return specifiers; } -- (void)ryanDonate:(id)arg { - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4VBFWEFBUF56N"]]; +- (void)donate:(id)arg { + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4VBFWEFBUF56N"]]; } - (void)viewSource:(id)arg { diff --git a/CyDelete/Makefile b/CyDelete/Makefile index 38db991..8c82196 100644 --- a/CyDelete/Makefile +++ b/CyDelete/Makefile @@ -1,6 +1,6 @@ ARCHS = armv7 arm64 -TARGET = iphone:8.1 +TARGET = iphone include theos/makefiles/common.mk diff --git a/CyDelete/Resources/CyDelete.plist b/CyDelete/Resources/CyDelete.plist index c283f4a..9088bcb 100644 --- a/CyDelete/Resources/CyDelete.plist +++ b/CyDelete/Resources/CyDelete.plist @@ -68,7 +68,7 @@ action - ryanDonate: + donate: cell PSButtonCell label @@ -84,6 +84,6 @@ title - CyDelete8 + CyDelete9 diff --git a/CyDelete/Resources/Pangu.png b/CyDelete/Resources/Pangu.png index 7fb8c85bf57d2403f374eb15598da02672f2d5b5..fc46f348e476c2089ad88b34bd0939aa8da5667f 100644 GIT binary patch literal 19405 zcmV)BK*PU@P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 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 R=o_Ih(&7qYB_alX{}0o<0;vE1 diff --git a/CyDelete/Resources/en.lproj/Localizable.strings b/CyDelete/Resources/en.lproj/Localizable.strings index 8bd5e9f..6f361ae 100755 --- a/CyDelete/Resources/en.lproj/Localizable.strings +++ b/CyDelete/Resources/en.lproj/Localizable.strings @@ -3,7 +3,7 @@ DONATE - Donate via PayPal + Donate NON_CYDIA_DEL Non-Cydia Deletion NON_CYDIA_DEL_TEXT @@ -18,12 +18,21 @@ Settings NO_DRM_DONATE_COPYRIGHT -There is no DRM protection on this application but please help support future development (my coffee fund) by donating via PayPal. +There is no DRM protection on this application but please help support future development (my coffee fund) by donating. +CyDelete9 © 2016 Pal Lockheart CyDelete8 © 2014 Ryan Burke CyDelete © 2009-2011 Dustin L. Howett Released under the GPLv3 Licence. SOURCE_CODE Source Code + PAYPAL + PayPal + BITCOIN + Bitcoin + ALIPAY + Alipay + CANCEL + Cancel diff --git a/CyDelete/Resources/pt_PT.lproj/Localizable.strings b/CyDelete/Resources/pt_PT.lproj/Localizable.strings index 54de1bf..e82c52c 100644 --- a/CyDelete/Resources/pt_PT.lproj/Localizable.strings +++ b/CyDelete/Resources/pt_PT.lproj/Localizable.strings @@ -3,7 +3,7 @@ DONATE - Doar via PayPal + Doar NON_CYDIA_DEL Eliminação não Cydia NON_CYDIA_DEL_TEXT @@ -18,8 +18,9 @@ Definições NO_DRM_DONATE_COPYRIGHT -Não há protecção DRM nesta aplicação, por favor apoie o desenvolvimento futuro (o meu fundo para café) ao doar via PayPal. +Não há protecção DRM nesta aplicação, por favor apoie o desenvolvimento futuro (o meu fundo para café) ao doar. +CyDelete9 © 2016 Pal Lockhart CyDelete8 © 2014 Ryan Burke CyDelete © 2009-2011 Dustin L. Howett Disponibilizado sob licença GPLv3. diff --git a/CyDelete/Resources/zh_CN.lproj/Localizable.strings b/CyDelete/Resources/zh_CN.lproj/Localizable.strings index 0cbdc34..66d1cf2 100755 --- a/CyDelete/Resources/zh_CN.lproj/Localizable.strings +++ b/CyDelete/Resources/zh_CN.lproj/Localizable.strings @@ -3,7 +3,7 @@ DONATE - 通过PayPal捐助 + 捐助 NON_CYDIA_DEL 非Cydia卸载 NON_CYDIA_DEL_TEXT @@ -12,5 +12,27 @@ 受保护的程序 PROTECTED_WARNING 卸载这两个应用程序将会导致安装软件包时无图形界面,因此不推荐这样做。 + ENABLED + 启用 + SETTINGS_TITLE + 设置 + NO_DRM_DONATE_COPYRIGHT + +本程序未做版权保护,若希望作者有动力继续更新,还请捐杯咖啡钱。 + +CyDelete9 © 2016 路痴 +CyDelete8 © 2014 Ryan Burke +CyDelete © 2009-2011 Dustin L. Howett +在GPLv3协议下发布. + SOURCE_CODE + 源代码 + PAYPAL + 贝宝 + BITCOIN + 比特币 + ALIPAY + 支付宝 + CANCEL + 取消 diff --git a/CyDelete/theos b/CyDelete/theos index e30945d..11eaf40 120000 --- a/CyDelete/theos +++ b/CyDelete/theos @@ -1 +1 @@ -/opt/theos \ No newline at end of file +../theos \ No newline at end of file diff --git a/Makefile b/Makefile index d7e3a3b..1a4cd01 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ ARCHS = armv7 arm64 -TARGET = iphone:8.1 +TARGET = iphone include theos/makefiles/common.mk @@ -12,4 +12,4 @@ SUBPROJECTS += setuid CyDelete include $(THEOS_MAKE_PATH)/aggregate.mk after-install:: - install.exec "killall -9 SpringBoard" + install.exec "killall backboardd" diff --git a/README.md b/README.md index fc49847..d0aa4e0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ CyDelete ========= -The original mobile substrate CyDelete tweak created by @DHowett updated for iOS 7 and 8. +The original mobile substrate CyDelete tweak created by @DHowett and ported to iOS7/8 by Ryan Burke updated for iOS 9. diff --git a/layout/DEBIAN/control b/layout/DEBIAN/control index aa6ec47..64797c5 100755 --- a/layout/DEBIAN/control +++ b/layout/DEBIAN/control @@ -1,13 +1,13 @@ Package: com.ryanburke.cydelete -Name: CyDelete8 -Depends: firmware (>=7.0), mobilesubstrate, preferenceloader, apt, bash +Name: CyDelete9 +Depends: firmware (>=9.0), mobilesubstrate, preferenceloader, apt, bash Conflicts: net.howett.cydelete, com.sosiphone.cydeletefr -Version: 1.0.2 +Version: 1.1.0 Architecture: iphoneos-arm -Description: Allows you to uninstall applications installed via Cydia from the Springboard just like AppStore applications. Just hold an icon down and tap on the X and the app will be uninstalled! This application is a new branch of the original CyDelete, created by @DHowett, bringing new support for iOS 8. Supports iOS 7 and 8. -Maintainer: Ryan Burke -Author: Ryan Burke +Description: Allows you to uninstall applications installed via Cydia from the Springboard just like AppStore applications. Just hold an icon down and tap on the X and the app will be uninstalled! This application is a new branch of the original CyDelete which created by @DHowett and ported to iOS8 by Ryan Burke, bringing new support for iOS 9.3. Supports iOS 7/8/9. +Maintainer: Pal Lockheart +Author: Pal Lockheart Section: Tweaks Depiction: http://moreinfo.thebigboss.org/moreinfo/depiction.php?file=cydelete7Dp -dev: ryanb93 +dev: palxex Tag: purpose::extension, role::enduser \ No newline at end of file diff --git a/layout/DEBIAN/postinst b/layout/DEBIAN/postinst new file mode 100755 index 0000000..b4b37dc --- /dev/null +++ b/layout/DEBIAN/postinst @@ -0,0 +1,6 @@ +#!/bin/bash +if [[ -e /usr/libexec/cydelete/setuid ]]; then + chmod 4755 /usr/libexec/cydelete/setuid + chown root:wheel /usr/libexec/cydelete/setuid +fi +exit 0 \ No newline at end of file diff --git a/setuid/Makefile b/setuid/Makefile index 2035300..d85dd2c 100644 --- a/setuid/Makefile +++ b/setuid/Makefile @@ -6,7 +6,3 @@ ARCHS = armv7 arm64 include ../theos/makefiles/common.mk include ../theos/makefiles/tool.mk - -after-setuid-stage:: - sudo chmod 4755 $(FW_STAGING_DIR)/usr/libexec/cydelete/setuid - sudo chown root:wheel $(FW_STAGING_DIR)/usr/libexec/cydelete/setuid diff --git a/theos b/theos index e30945d..11eaf40 120000 --- a/theos +++ b/theos @@ -1 +1 @@ -/opt/theos \ No newline at end of file +../theos \ No newline at end of file From d6107657102d1a0b3a915cefb2f0a70a34ab5d13 Mon Sep 17 00:00:00 2001 From: Pal Lockheart Date: Sat, 17 Dec 2016 01:06:22 +0800 Subject: [PATCH 2/2] remove obsolete alert; add donation --- CyDelete.xm | 40 +++++++++--------------------- CyDelete/CyDeleteListController.mm | 29 ++++++++++++++++++++++ CyDelete/Resources/CyDelete.plist | 8 ++++++ README.md | 7 +++++- 4 files changed, 55 insertions(+), 29 deletions(-) diff --git a/CyDelete.xm b/CyDelete.xm index d49aeca..ead3208 100644 --- a/CyDelete.xm +++ b/CyDelete.xm @@ -391,31 +391,18 @@ static BOOL _forceCydia; } if(cydelete_IOSVersionAbove92() && [[iconPackagesDict allKeys] containsObject:[app bundleIdentifier]]) { //new mechanism: iOS 9.2 above will not automatically trigger uninstall, we've to call it manually - BOOL contains = NO; - for(CDUninstallDpkgOperation *operation in [uninstallQueue operations]){ - if([operation.package isEqualToString:[app bundleIdentifier]]){ - contains = YES; - break; - } - } - if(contains) { - UIAlertController* alert=[UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"%@ IS uninstalling",[app displayName]] message:@"Please WAIT A SEC" preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]]; - [self presentViewController: alert animated:YES completion:nil]; - }else{ - appicon.forceCydia = YES; - UIAlertController* alert=[UIAlertController alertControllerWithTitle:[appicon uninstallAlertTitle] message:[appicon uninstallAlertBody] preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:[appicon uninstallAlertCancelTitle] style:UIAlertActionStyleDefault handler:nil]]; - [alert addAction:[UIAlertAction actionWithTitle:[appicon uninstallAlertConfirmTitle] style:UIAlertActionStyleCancel handler:^(UIAlertAction* _Nonnull action) - { - Class $LSApplicationWorkspace = objc_getClass("LSApplicationWorkspace"); - [[$LSApplicationWorkspace defaultWorkspace] unregisterApplication:[NSURL fileURLWithPath:[app path]]]; - Class $SBApplicationController = objc_getClass("SBApplicationController"); - [[$SBApplicationController sharedInstance] uninstallApplication:app]; - }]]; - appicon.forceCydia = NO; - [self presentViewController: alert animated:YES completion:nil]; - } + appicon.forceCydia = YES; + UIAlertController* alert=[UIAlertController alertControllerWithTitle:[appicon uninstallAlertTitle] message:[appicon uninstallAlertBody] preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:[appicon uninstallAlertCancelTitle] style:UIAlertActionStyleDefault handler:nil]]; + [alert addAction:[UIAlertAction actionWithTitle:[appicon uninstallAlertConfirmTitle] style:UIAlertActionStyleCancel handler:^(UIAlertAction* _Nonnull action) + { + Class $LSApplicationWorkspace = objc_getClass("LSApplicationWorkspace"); + [[$LSApplicationWorkspace defaultWorkspace] unregisterApplication:[NSURL fileURLWithPath:[app path]]]; + Class $SBApplicationController = objc_getClass("SBApplicationController"); + [[$SBApplicationController sharedInstance] uninstallApplication:app]; + }]]; + appicon.forceCydia = NO; + [self presentViewController: alert animated:YES completion:nil]; }else{ %orig; } @@ -463,7 +450,6 @@ static BOOL _forceCydia; } -(NSString *)uninstallAlertTitle { - %log; if(!_forceCydia && isOfficialUninstallable([self application])) return %orig; return [NSString stringWithFormat:cydelete_IOSVersionAbove92() ? SBLocalizedString(@"UNINSTALL_ICON_TITLE_DELETE_WITH_NAME") : SBLocalizedString(@"UNINSTALL_ICON_TITLE"), @@ -499,14 +485,12 @@ static BOOL _forceCydia; } -(NSString *)uninstallAlertConfirmTitle { - %log; if(!_forceCydia && isOfficialUninstallable([self application])) return %orig; return cydelete_IOSVersionAbove92() ? SBLocalizedString(@"UNINSTALL_ICON_BUTTON_DELETE") : SBLocalizedString(@"UNINSTALL_ICON_CONFIRM"); } -(NSString *)uninstallAlertCancelTitle { - %log; if(!_forceCydia && isOfficialUninstallable([self application])) return %orig; return cydelete_IOSVersionAbove92() ? SBLocalizedString(@"UNINSTALL_ICON_BUTTON_CANCEL") : SBLocalizedString(@"UNINSTALL_ICON_CANCEL"); diff --git a/CyDelete/CyDeleteListController.mm b/CyDelete/CyDeleteListController.mm index 29ebfc6..fd80a55 100644 --- a/CyDelete/CyDeleteListController.mm +++ b/CyDelete/CyDeleteListController.mm @@ -62,6 +62,35 @@ - (void)donate:(id)arg { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4VBFWEFBUF56N"]]; } +- (void)donate2:(id)arg { + UIAlertController* alert=[UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"%@ palxex",[self localized:@"DONATE"]] message:nil preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:[self localized:@"BITCOIN"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* _Nonnull action) + { + NSURL *targetURL = [NSURL URLWithString:@"bitcoin:1EXrR9YSEEXtFSYWjNnwrhyRhc4DoQHhzC"]; + if([[UIApplication sharedApplication] canOpenURL:targetURL]) + [[UIApplication sharedApplication] openURL:targetURL]; + else{ + [[UIPasteboard generalPasteboard] setString:@"1EXrR9YSEEXtFSYWjNnwrhyRhc4DoQHhzC"]; + UIAlertController* alert=[UIAlertController alertControllerWithTitle:@"" message:@"BTC address 1EXrR9YSEEXtFSYWjNnwrhyRhc4DoQHhzC; have been copied in your pasteboard" preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"OKay" style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController: alert animated:YES completion:nil]; + } + }]]; + [alert addAction:[UIAlertAction actionWithTitle:[self localized:@"ALIPAY"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* _Nonnull action) + { + NSURL *targetURL = [NSURL URLWithString:@"alipayqr://platformapi/startapp?saId=10000007&qrcode=https%3A%2F%2Fqr.alipay.com%2Faex04760kwfblpiaho9mg00"]; + if([[UIApplication sharedApplication] canOpenURL:targetURL]) + [[UIApplication sharedApplication] openURL:targetURL]; + else + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://qr.alipay.com/aex04760kwfblpiaho9mg00"]]; + }]]; + [alert addAction:[UIAlertAction actionWithTitle:[self localized:@"PAYPAL"] style:UIAlertActionStyleDefault handler:^(UIAlertAction* _Nonnull action) + {[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=W25D7EKNG9JNQ&lc=C2&item_name=Donation&button_subtype=services"]]; + }]]; + [alert addAction:[UIAlertAction actionWithTitle:[self localized:@"CANCEL"] style:UIAlertActionStyleCancel handler:nil]]; + [self presentViewController: alert animated:YES completion:nil]; +} + - (void)viewSource:(id)arg { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://github.com/ryanb93/CyDelete"]]; } diff --git a/CyDelete/Resources/CyDelete.plist b/CyDelete/Resources/CyDelete.plist index 9088bcb..e7bb2de 100644 --- a/CyDelete/Resources/CyDelete.plist +++ b/CyDelete/Resources/CyDelete.plist @@ -74,6 +74,14 @@ label DONATE + + action + donate2: + cell + PSButtonCell + label + DONATE + action viewSource: diff --git a/README.md b/README.md index d0aa4e0..83cd569 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ CyDelete ========= -The original mobile substrate CyDelete tweak created by @DHowett and ported to iOS7/8 by Ryan Burke updated for iOS 9. +A mobile substrate tweak to uninstall applications from the homescreen that have been installed using Cydia. + +### Contributors +CyDelete - [Dustin Howett ](https://github.com/DHowett) +CyDelete 7 & 8 - [Ryan Burke](https://github.com/ryanb93) +CyDelete 9 - [Pal Lockhart](https://github.com/palxex) \ No newline at end of file