2018-09-23 16:01:05 +00:00
//
// X C a l l b a c k U R L . s w i f t
// T u s k e r
//
// C r e a t e d b y S h a d o w f a c t s o n 9 / 2 3 / 1 8 .
// C o p y r i g h t © 2 0 1 8 S h a d o w f a c t s . A l l r i g h t s r e s e r v e d .
//
2018-09-24 01:10:45 +00:00
import UIKit
2018-09-26 01:41:12 +00:00
typealias XCBAction = ( _ url : XCBRequest , _ session : XCBSession , _ silent : Bool ? ) -> Void
2018-09-23 16:01:05 +00:00
2018-09-26 01:41:12 +00:00
struct XCBRequestSpec {
2018-09-23 16:01:05 +00:00
let path : String
2018-09-24 01:35:33 +00:00
let type : XCBActionType
2018-09-23 16:01:05 +00:00
let arguments : [ String : Bool ]
2018-09-24 01:10:45 +00:00
let canRunSilently : Bool
let action : XCBAction
2018-09-23 16:01:05 +00:00
2018-09-24 01:35:33 +00:00
init ( type : XCBActionType , arguments : [ String : Bool ] , canRunSilently : Bool , action : @ escaping XCBAction ) {
self . path = type . path
2018-09-24 01:10:45 +00:00
self . type = type
self . canRunSilently = canRunSilently
self . action = action
var arguments = arguments
if canRunSilently {
arguments [ " silent " ] = true
}
2018-09-26 01:41:12 +00:00
arguments [ " json " ] = true
2018-09-23 16:01:05 +00:00
self . arguments = arguments
2018-09-24 01:10:45 +00:00
}
2018-09-26 01:41:12 +00:00
func handle ( request : XCBRequest ) -> Bool {
let session = XCBManager . createSession ( type : type , request : request )
if canRunSilently && request . silent {
if let source = request . source {
2018-09-24 01:10:45 +00:00
let permission = Preferences . shared . silentActions [ source ] ? ? . undecided
switch permission {
case . accepted :
2018-09-26 01:41:12 +00:00
action ( request , session , true )
2018-09-24 01:10:45 +00:00
case . rejected :
2018-09-26 01:41:12 +00:00
action ( request , session , false )
2018-09-24 01:10:45 +00:00
case . undecided :
let alert = UIAlertController ( title : " \( source ) wants to perform actions silently " , message : " Accepting will allow \( source ) to perform actions without your confirmation, rejecting will always prompt for confirmation. " , preferredStyle : . alert )
alert . addAction ( UIAlertAction ( title : " Accept " , style : . default , handler : { ( _ ) in
Preferences . shared . silentActions [ source ] = . accepted
2018-09-26 01:41:12 +00:00
self . action ( request , session , true )
2018-09-24 01:10:45 +00:00
} ) )
alert . addAction ( UIAlertAction ( title : " Reject " , style : . default , handler : { ( _ ) in
Preferences . shared . silentActions [ source ] = . rejected
2018-09-26 01:41:12 +00:00
self . action ( request , session , false )
2018-09-24 01:10:45 +00:00
} ) )
UIApplication . shared . keyWindow ! . rootViewController ! . present ( alert , animated : true )
}
} else {
session . complete ( with : . error , additionalData : [
2018-09-25 01:58:44 +00:00
" error " : " Cannot perform silent action without source app, x-source parameter must be specified. "
2018-09-24 01:10:45 +00:00
] )
}
} else {
2018-09-26 01:41:12 +00:00
action ( request , session , nil )
2018-09-24 01:10:45 +00:00
}
return true
2018-09-23 16:01:05 +00:00
}
}
2018-09-26 01:41:12 +00:00
extension XCBRequestSpec {
2018-09-23 16:01:05 +00:00
func matches ( _ components : URLComponents ) -> Bool {
2018-09-24 01:10:45 +00:00
guard path = = components . path else { return false }
for ( name , optional ) in arguments {
2018-09-23 16:01:05 +00:00
if ( ! optional && components . queryItems ? . first ( where : { $0 . name = = name } ) = = nil ) {
return false
}
}
return true
}
}