2020-07-13 17:59:52 -07:00
//
// S c e n e D e l e g a t e . s w i f t
// A l t S t o r e
//
// C r e a t e d b y R i l e y T e s t u t o n 7 / 6 / 2 0 .
// C o p y r i g h t © 2 0 2 0 R i l e y T e s t u t . A l l r i g h t s r e s e r v e d .
//
import UIKit
import AltStoreCore
2022-11-02 17:58:59 -07:00
import EmotionalDamage
2023-05-20 09:51:45 -07:00
import minimuxer
2020-07-13 17:59:52 -07:00
@ available ( iOS 13 , * )
2023-01-04 09:52:12 -05:00
final class SceneDelegate : UIResponder , UIWindowSceneDelegate
2020-07-13 17:59:52 -07:00
{
var window : UIWindow ?
func scene ( _ scene : UIScene , willConnectTo session : UISceneSession , options connectionOptions : UIScene . ConnectionOptions )
{
// U s e t h i s m e t h o d t o o p t i o n a l l y c o n f i g u r e a n d a t t a c h t h e U I W i n d o w ` w i n d o w ` t o t h e p r o v i d e d U I W i n d o w S c e n e ` s c e n e ` .
// I f u s i n g a s t o r y b o a r d , t h e ` w i n d o w ` p r o p e r t y w i l l a u t o m a t i c a l l y b e i n i t i a l i z e d a n d a t t a c h e d t o t h e s c e n e .
// T h i s d e l e g a t e d o e s n o t i m p l y t h e c o n n e c t i n g s c e n e o r s e s s i o n a r e n e w ( s e e ` a p p l i c a t i o n : c o n f i g u r a t i o n F o r C o n n e c t i n g S c e n e S e s s i o n ` i n s t e a d ) .
guard let _ = ( scene as ? UIWindowScene ) else { return }
2020-09-08 16:42:25 -07:00
if let context = connectionOptions . urlContexts . first
{
self . open ( context )
}
2020-07-13 17:59:52 -07:00
}
func sceneWillEnterForeground ( _ scene : UIScene )
{
// C a l l e d a s t h e s c e n e t r a n s i t i o n s f r o m t h e b a c k g r o u n d t o t h e f o r e g r o u n d .
// U s e t h i s m e t h o d t o u n d o t h e c h a n g e s m a d e o n e n t e r i n g t h e b a c k g r o u n d .
// a p p l i c a t i o n W i l l E n t e r F o r e g r o u n d i s _ n o t _ c a l l e d w h e n l a u n c h i n g a p p ,
// w h e r e a s s c e n e W i l l E n t e r F o r e g r o u n d _ i s _ c a l l e d w h e n l a u n c h i n g .
// A s a r e s u l t , D a t a b a s e M a n a g e r m i g h t n o t b e s t a r t e d y e t , s o j u s t r e t u r n i f i t i s n ' t
// ( s i n c e a l l t h e s e m e t h o d s a r e c a l l e d s e p a r a t e l y d u r i n g a p p s t a r t u p ) .
guard DatabaseManager . shared . isStarted else { return }
AppManager . shared . update ( )
2022-11-08 14:15:09 -05:00
start_em_proxy ( bind_addr : Consts . Proxy . serverURL )
2020-07-13 17:59:52 -07:00
PatreonAPI . shared . refreshPatreonAccount ( )
}
func sceneDidEnterBackground ( _ scene : UIScene )
{
// C a l l e d a s t h e s c e n e t r a n s i t i o n s f r o m t h e f o r e g r o u n d t o t h e b a c k g r o u n d .
// U s e t h i s m e t h o d t o s a v e d a t a , r e l e a s e s h a r e d r e s o u r c e s , a n d s t o r e e n o u g h s c e n e - s p e c i f i c s t a t e i n f o r m a t i o n
// t o r e s t o r e t h e s c e n e b a c k t o i t s c u r r e n t s t a t e .
guard UIApplication . shared . applicationState = = . background else { return }
2022-09-09 17:47:49 -05:00
// M a k e s u r e t o u p d a t e A p p D e l e g a t e . a p p l i c a t i o n D i d E n t e r B a c k g r o u n d ( ) a s w e l l .
guard let oneMonthAgo = Calendar . current . date ( byAdding : . month , value : - 1 , to : Date ( ) ) else { return }
let midnightOneMonthAgo = Calendar . current . startOfDay ( for : oneMonthAgo )
DatabaseManager . shared . purgeLoggedErrors ( before : midnightOneMonthAgo ) { result in
switch result
{
case . success : break
case . failure ( let error ) : print ( " [ALTLog] Failed to purge logged errors before \( midnightOneMonthAgo ) . " , error )
}
}
2022-11-02 17:58:59 -07:00
2020-07-13 17:59:52 -07:00
}
2020-09-08 16:42:25 -07:00
func scene ( _ scene : UIScene , openURLContexts URLContexts : Set < UIOpenURLContext > )
{
guard let context = URLContexts . first else { return }
self . open ( context )
}
}
@ available ( iOS 13.0 , * )
private extension SceneDelegate
{
func open ( _ context : UIOpenURLContext )
{
if context . url . isFileURL
{
guard context . url . pathExtension . lowercased ( ) = = " ipa " else { return }
DispatchQueue . main . async {
NotificationCenter . default . post ( name : AppDelegate . importAppDeepLinkNotification , object : nil , userInfo : [ AppDelegate . importAppDeepLinkURLKey : context . url ] )
}
}
else
{
guard let components = URLComponents ( url : context . url , resolvingAgainstBaseURL : false ) else { return }
guard let host = components . host ? . lowercased ( ) else { return }
2023-05-20 09:51:45 -07:00
let queryItems = components . queryItems ? . reduce ( into : [ String : String ] ( ) ) { $0 [ $1 . name . lowercased ( ) ] = $1 . value } ? ? [ : ]
2020-09-08 16:42:25 -07:00
switch host
{
case " patreon " :
DispatchQueue . main . async {
NotificationCenter . default . post ( name : AppDelegate . openPatreonSettingsDeepLinkNotification , object : nil )
}
case " appbackupresponse " :
let result : Result < Void , Error >
switch context . url . path . lowercased ( )
{
case " /success " : result = . success ( ( ) )
case " /failure " :
guard
let errorDomain = queryItems [ " errorDomain " ] ,
let errorCodeString = queryItems [ " errorCode " ] , let errorCode = Int ( errorCodeString ) ,
let errorDescription = queryItems [ " errorDescription " ]
else { return }
let error = NSError ( domain : errorDomain , code : errorCode , userInfo : [ NSLocalizedDescriptionKey : errorDescription ] )
result = . failure ( error )
default : return
}
DispatchQueue . main . async {
NotificationCenter . default . post ( name : AppDelegate . appBackupDidFinish , object : nil , userInfo : [ AppDelegate . appBackupResultKey : result ] )
}
case " install " :
guard let downloadURLString = queryItems [ " url " ] , let downloadURL = URL ( string : downloadURLString ) else { return }
DispatchQueue . main . async {
NotificationCenter . default . post ( name : AppDelegate . importAppDeepLinkNotification , object : nil , userInfo : [ AppDelegate . importAppDeepLinkURLKey : downloadURL ] )
}
case " source " :
guard let sourceURLString = queryItems [ " url " ] , let sourceURL = URL ( string : sourceURLString ) else { return }
DispatchQueue . main . async {
NotificationCenter . default . post ( name : AppDelegate . addSourceDeepLinkNotification , object : nil , userInfo : [ AppDelegate . addSourceDeepLinkURLKey : sourceURL ] )
}
2023-05-20 09:51:45 -07:00
case " sidejit-enable " :
2023-06-01 07:36:40 -07:00
guard UnstableFeatures . enabled ( . jitUrlScheme ) else { return UIApplication . alert ( title : " JIT URL scheme unstable feature is not enabled " , message : nil ) }
2023-05-20 09:51:45 -07:00
if let bundleID = queryItems [ " bid " ] {
DispatchQueue . main . async {
do {
try debug_app ( bundleID )
} catch {
2023-06-01 07:36:40 -07:00
UIApplication . alert ( title : " An error occurred when enabling JIT " , message : error . message ( ) )
2023-05-20 09:51:45 -07:00
}
}
} else if let processID = queryItems [ " pid " ] {
DispatchQueue . main . async {
do {
2023-06-01 07:36:40 -07:00
guard let processID = UInt32 ( processID ) else { return UIApplication . alert ( title : " An error occurred when enabling JIT " , message : " Process ID is not a valid unsigned integer " ) }
2023-05-20 09:51:45 -07:00
try attach_debugger ( processID )
} catch {
2023-06-01 07:36:40 -07:00
UIApplication . alert ( title : " An error occurred when enabling JIT " , message : error . message ( ) )
2023-05-20 09:51:45 -07:00
}
}
2023-06-01 07:36:40 -07:00
} else { return UIApplication . alert ( title : " An error occurred when enabling JIT " , message : " Please specify a bundle ID using the `bid` query parameter or a process ID using `pid` query parameter " ) }
2023-05-20 09:51:45 -07:00
2020-09-08 16:42:25 -07:00
default : break
}
}
}
2020-07-13 17:59:52 -07:00
}