Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Shared/Data/CoreData/CoreDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ final class CoreDataManager {
let uuidString: String
if let uuidObj = uuid as? UUID {
uuidString = uuidObj.uuidString
} else if let uuidStr = uuid as? String {
uuidString = uuidStr
} else if uuid is String {
uuidString = uuid as! String
} else {
throw NSError(domain: "CoreDataManager", code: 1008,
userInfo: [NSLocalizedDescriptionKey: "Invalid UUID type: \(type(of: uuid))"])
Expand Down
41 changes: 33 additions & 8 deletions iOS/Operations/CoreML/CoreMLManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,8 @@ final class CoreMLManager {
// First create an observer variable
var memoryObserverLocal: NSObjectProtocol?

// Set up memory pressure observer
memoryObserverLocal = NotificationCenter.default.addObserver(
// Set up memory pressure observer - create the observer first
let memoryObserver = NotificationCenter.default.addObserver(
forName: UIApplication.didReceiveMemoryWarningNotification,
object: nil,
queue: .main
Expand All @@ -446,7 +446,8 @@ final class CoreMLManager {
completion?(false)
}

let memoryObserver = memoryObserverLocal!
// Store the observer in the local variable after creating it
memoryObserverLocal = memoryObserver

// Perform actual loading in background
predictionQueue.async { [weak self] in
Expand Down Expand Up @@ -1113,7 +1114,7 @@ final class CoreMLManager {
case "sign_app", "signing":
// Extract app name
let appNameMatches = text.extractMatch(
pattern: "(?i)sign\\s+(?:the\\s+)?app\\s+(?:called\\s+|named\\s+)?([^?.,]+)",
pattern: "(?i)sign\\s+(?:the\\s+)?app\\s+(?:called|named)\\s+\"?([^\".,?!]+)\"?",
groupIndex: 1
)
if let appName = appNameMatches {
Expand All @@ -1123,7 +1124,7 @@ final class CoreMLManager {
case "navigate", "navigation":
// Extract destination
let destinationMatches = text.extractMatch(
pattern: "(?i)(?:go\\s+to|navigate\\s+to|open|show)\\s+(?:the\\s+)?([^?.,]+?)\\s+(?:tab|screen|page|section)",
pattern: "(?i)(?:go\\s+to|navigate\\s+to|open|show)\\s+(?:the\\s+)?([^\".,?!]+?)\\s+(?:tab|screen|page|section)",
groupIndex: 1
)
if let destination = destinationMatches {
Expand All @@ -1133,7 +1134,7 @@ final class CoreMLManager {
case "add_source", "source":
// Extract URL
let urlMatches = text.extractMatch(
pattern: "(?i)add\\s+(?:a\\s+)?(?:new\\s+)?source\\s+(?:with\\s+url\\s+|at\\s+|from\\s+)?([^?.,\\s]+)",
pattern: "(?i)add\\s+(?:a\\s+)?(?:new\\s+)?source\\s+(?:with\\s+url\\s+|at\\s+|from\\s+)?([^\".,:;?!]+)",
groupIndex: 1
)
if let url = urlMatches {
Expand All @@ -1143,7 +1144,7 @@ final class CoreMLManager {
case "install_app", "install":
// Extract app name
let appNameMatches = text.extractMatch(
pattern: "(?i)install\\s+(?:the\\s+)?app\\s+(?:called\\s+|named\\s+)?([^?.,]+)",
pattern: "(?i)install\\s+(?:the\\s+)?app\\s+(?:called\\s+|named\\s+)?([^\".,?!]+)",
groupIndex: 1
)
if let appName = appNameMatches {
Expand All @@ -1153,7 +1154,7 @@ final class CoreMLManager {
case "question", "query":
// Extract question topic
let topicMatches = text.extractMatch(
pattern: "(?i)(?:about|regarding|related\\s+to)\\s+([^?.,]+)",
pattern: "(?i)(?:about|regarding|related\\s+to)\\s+([^\".,?!]+)",
groupIndex: 1
)
if let topic = topicMatches {
Expand Down Expand Up @@ -1313,6 +1314,30 @@ final class CoreMLManager {
}
}
}

/// Set up memory pressure monitoring
private func setupMemoryPressureMonitoring() {
// Create a local copy of the observer to avoid mutation after capture
var memoryObserverLocal: NSObjectProtocol?

// Create the observer before the closure to avoid capturing it in the closure
let memoryObserver = NotificationCenter.default.addObserver(
forName: UIApplication.didReceiveMemoryWarningNotification,
object: nil,
queue: .main
) { [weak self, weak loadingAlert] _ in
Debug.shared.log(message: "Memory warning received - unloading CoreML model", type: .warning)
self?.unloadModel()
}

// Store the observer in the local variable after creating it
memoryObserverLocal = memoryObserver

// Store the observer in the class property for later cleanup
if let observer = memoryObserverLocal {
memoryObservers.append(observer)
}
}
}

// Import the extension containing extractMatch from AppContextManager+AIIntegration.swift
Expand Down
18 changes: 7 additions & 11 deletions iOS/Operations/FloatingButtonManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -725,18 +725,14 @@ final class FloatingButtonManager {
}

private func performPresentation(_ viewController: UIViewController, from presenter: UIViewController) {
// Add a try-catch for presentation failures
do {
presenter.present(viewController, animated: true) { [weak self] in
// Log success
Debug.shared.log(message: "AI assistant presented successfully", type: .info)
}
} catch {
// If presentation fails for any reason, reset state
Debug.shared.log(message: "Failed to present AI assistant: \(error.localizedDescription)", type: .error)
isPresentingChat = false
show()
// Present directly without try-catch since UIKit presentation doesn't throw
presenter.present(viewController, animated: true) { [weak self] in
// Log success
Debug.shared.log(message: "AI assistant presented successfully", type: .info)
}

// Handle presentation failure through the completion handler if needed
// This is more reliable than a try-catch that will never be executed
}

private func showErrorAlert(message: String, on viewController: UIViewController) {
Expand Down
2 changes: 1 addition & 1 deletion iOS/Views/Apps/LibraryViewController+Import.swift
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ extension LibraryViewController {
}

let hostingController = UIHostingController(rootView: transferPreview)
hostingController.modalPresentationStyle = .pageSheet
hostingController.modalPresentationStyle = UIModalPresentationStyle.pageSheet

if let presentationController = hostingController.presentationController as? UISheetPresentationController {
let detent = UISheetPresentationController.Detent._detent(
Expand Down
24 changes: 15 additions & 9 deletions iOS/Views/Apps/LibraryViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -298,22 +298,28 @@ class LibraryViewController: UITableViewController {
section: Int,
getuuidonly: Bool = false) -> URL?
{
do {
if section == 0, let apps = signedApps, row < apps.count {
let signedApp = apps[row]
if section == 0, let apps = signedApps, row < apps.count {
let signedApp = apps[row]
do {
return try CoreDataManager.shared.getFilesForSignedApps(
for: signedApp,
getuuidonly: getuuidonly
)
} else if let apps = downloadedApps, row < apps.count {
let downloadedApp = apps[row]
} catch {
backdoor.Debug.shared.log(message: "Error getting file path: \(error)", type: LogType.error)
return nil
}
} else if let apps = downloadedApps, row < apps.count {
let downloadedApp = apps[row]
do {
return try CoreDataManager.shared.getFilesForDownloadedApps(
for: downloadedApp,
getuuidonly: getuuidonly
)
} catch {
backdoor.Debug.shared.log(message: "Error getting file path: \(error)", type: LogType.error)
return nil
}
} catch {
backdoor.Debug.shared.log(message: "Error getting file path: \(error)", type: LogType.error)
}
return nil
}
Expand Down Expand Up @@ -732,8 +738,8 @@ extension LibraryViewController {
// This method is kept for compatibility with existing code
@available(*, deprecated, message: "Use startSigning(app:) instead")
func startSigning(meow: NSManagedObject) {
// Call the method with the original parameter name to match caller expectations
startSigning(meow: meow)
// Call the new method with the renamed parameter to avoid recursion
startSigning(app: meow)
}

override func tableView(
Expand Down
7 changes: 7 additions & 0 deletions iOS/Views/Extra/TransferPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ struct TransferPreview: View {
@State private var showShareSheet = false
@State private var shareURL: URL?

init(installer: Installer, appPath: String, appName: String, isSharing: Bool = false) {
_installer = StateObject(wrappedValue: installer)
_appPath = State(initialValue: appPath)
_appName = State(initialValue: appName)
_isSharing = State(initialValue: isSharing)
}

var icon: String {
if packaging {
return "archivebox.fill"
Expand Down
4 changes: 4 additions & 0 deletions iOS/Views/Home/Core/HomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,10 @@ class HomeViewController: UIViewController, UISearchResultsUpdating, UIDocumentP
}

/// Initiates the file import process
@objc func importFile() {
fileHandlers.importFile(viewController: self)
}

@objc func performFileImport() {
fileHandlers.importFile(viewController: self)
}
Expand Down
35 changes: 26 additions & 9 deletions iOS/Views/TabbarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,32 @@ struct TabbarView: View {
) { _ in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// Apply flowing LED effect to all tab bars
UIApplication.shared.windows.compactMap { $0.rootViewController as? UITabBarController }
.forEach { tabController in
tabController.tabBar.addFlowingLEDEffect(
color: UIColor(hex: "#FF6482") ?? .systemPink,
intensity: 0.5,
width: 2,
speed: 5.0
)
}
if #available(iOS 15.0, *) {
// Use UIWindowScene.windows on iOS 15+
UIApplication.shared.connectedScenes
.compactMap { $0 as? UIWindowScene }
.flatMap { $0.windows }
.compactMap { $0.rootViewController as? UITabBarController }
.forEach { tabController in
tabController.tabBar.addFlowingLEDEffect(
color: UIColor(hex: "#FF6482"),
intensity: 0.5,
width: 2,
speed: 5.0
)
}
} else {
// Use deprecated windows property on older iOS versions
UIApplication.shared.windows.compactMap { $0.rootViewController as? UITabBarController }
.forEach { tabController in
tabController.tabBar.addFlowingLEDEffect(
color: UIColor(hex: "#FF6482"),
intensity: 0.5,
width: 2,
speed: 5.0
)
}
}
}
}

Expand Down