nativescript-matrix-sdk
Version:
Native Matrix SDK integration for NativeScript
156 lines (135 loc) • 5.51 kB
text/typescript
import { isIOS } from '@nativescript/core';
import { MemoryOptimizerBase, MemoryCondition } from '../../src/memory-optimizer-base';
import { Logger } from '../../src/logger';
// Add iOS globals declarations
declare const UIApplication: any;
declare const NSProcessInfo: any;
declare const NSNotificationCenter: any;
declare const NSOperationQueue: any;
declare const NSAutoreleasePool: any;
declare const NSMutableData: any;
declare const UIApplicationState: any;
declare const UIApplicationDidReceiveMemoryWarningNotification: any;
/**
* iOS-specific memory optimization implementation
*/
export class MatrixMemoryOptimizerIOS extends MemoryOptimizerBase {
private memoryWarningObserver: any = null;
constructor(lowMemoryThresholdMB = 100, criticalMemoryThresholdMB = 50) {
super(lowMemoryThresholdMB, criticalMemoryThresholdMB);
}
/**
* Start monitoring for memory pressure signals
*/
protected override startMemoryMonitoring(): void {
if (!isIOS) {
Logger.warn('[MatrixMemoryOptimizerIOS] Not running on iOS, memory monitoring disabled');
return;
}
try {
// Register for low memory warnings from iOS
const notificationName = UIApplication.didReceiveMemoryWarningNotification;
this.memoryWarningObserver = NSNotificationCenter.defaultCenter.addObserverForNameObjectQueueUsingBlock(
notificationName,
null,
NSOperationQueue.mainQueue,
(notification) => {
Logger.warn('[MatrixMemoryOptimizerIOS] Memory warning received from system');
this.setMemoryCondition(MemoryCondition.CRITICAL);
}
);
Logger.info('[MatrixMemoryOptimizerIOS] Memory monitoring set up successfully');
} catch (error) {
Logger.error('[MatrixMemoryOptimizerIOS] Failed to set up memory monitoring:', error);
}
}
/**
* Check current memory usage and determine condition
*/
protected override checkMemoryStatus(): MemoryCondition {
try {
if (isIOS) {
// iOS doesn't provide easy access to memory stats
// We'll use a combination of heuristics to determine memory status
// 1. Check total memory - low memory devices are more likely to be constrained
const info = NSProcessInfo.processInfo;
const totalMemory = info.physicalMemory / (1024 * 1024); // Convert to MB
// 2. Check app state - background apps should be more memory conservative
const appState = UIApplication.sharedApplication.applicationState;
const isBackground = appState === UIApplicationState.Background;
// Determine memory condition based on heuristics
if (totalMemory < 1500 || isBackground) {
// Low memory device or background state
return MemoryCondition.LOW;
}
// No obvious memory pressure, return normal
return MemoryCondition.NORMAL;
}
} catch (error) {
Logger.error('[MatrixMemoryOptimizerIOS] Error checking memory:', error);
}
// Default to normal if we can't determine
return MemoryCondition.NORMAL;
}
/**
* Try to free memory in iOS
*/
protected override forceGarbageCollection(): void {
try {
if (isIOS) {
Logger.debug('[MatrixMemoryOptimizerIOS] Attempting to release memory');
// 1. Create and drain autorelease pool
const pool = NSAutoreleasePool.new();
pool.drain();
// 2. Create and immediately discard a large object
const tempData = NSMutableData.dataWithCapacity(5 * 1024 * 1024); // 5MB
// 3. Send an explicit memory warning to the application
// This will cause the system to call didReceiveMemoryWarning on view controllers
UIApplication.sharedApplication.performSelectorOnMainThreadWithObjectWaitUntilDone(
"_performMemoryWarning",
null,
false
);
}
} catch (error) {
Logger.error('[MatrixMemoryOptimizerIOS] Error releasing memory:', error);
}
}
/**
* Clean up resources when no longer needed
*/
public override cleanup(): void {
try {
if (this.memoryWarningObserver && isIOS) {
NSNotificationCenter.defaultCenter.removeObserver(this.memoryWarningObserver);
this.memoryWarningObserver = null;
Logger.info('[MatrixMemoryOptimizerIOS] Memory monitoring cleaned up');
}
} catch (error) {
Logger.error('[MatrixMemoryOptimizerIOS] Failed to clean up memory monitoring:', error);
}
// Call base cleanup
super.cleanup();
}
/**
* Get the total device memory in MB
* @returns The total device memory in MB or a default value if unavailable
*/
protected override getTotalDeviceMemoryMB(): number {
try {
if (!isIOS) {
throw new Error('Not running on iOS platform');
}
// On iOS, we can use NSProcessInfo to get physical memory
const processInfo = NSProcessInfo.processInfo;
// Convert bytes to MB
const totalMemoryMB = Math.floor(processInfo.physicalMemory / (1024 * 1024));
Logger.debug(`[MatrixMemoryOptimizerIOS] Total device memory: ${totalMemoryMB}MB`);
return totalMemoryMB;
} catch (error) {
Logger.warn('[MatrixMemoryOptimizerIOS] Error getting device memory');
Logger.error('[MatrixMemoryOptimizerIOS] Error details:', error);
return 4096; // Default to a mid-range device
}
}
}