Skip to content
Open
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
16 changes: 16 additions & 0 deletions Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@
AFCE353527E4ED5900FEA6C2 /* DateFormatter+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */; };
AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */; };
AFCE353927E5DE0500FEA6C2 /* Shareable.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* Shareable.swift */; };
AFCE353927E5DE0500FEA6C2 /* NCShare+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */; };
B5D45E732DA5172900773929 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D45E712DA5172900773929 /* AppUpdater.swift */; };
C04E2F232A17BB4D001BAD85 /* FilesIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04E2F222A17BB4D001BAD85 /* FilesIntegrationTests.swift */; };
D575039F27146F93008DC9DC /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extension.swift */; };
D5B6AA7827200C7200D49C24 /* NCActivityTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */; };
F310B1EF2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = F310B1EE2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift */; };
F321DA8A2B71205A00DDA0E6 /* NCTrashSelectTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F321DA892B71205A00DDA0E6 /* NCTrashSelectTabBar.swift */; };
Expand Down Expand Up @@ -1221,6 +1225,8 @@
AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extension.swift"; sourceTree = "<group>"; };
AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCells.swift; sourceTree = "<group>"; };
AFCE353827E5DE0400FEA6C2 /* Shareable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shareable.swift; sourceTree = "<group>"; };
AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCShare+Helper.swift"; sourceTree = "<group>"; };
B5D45E712DA5172900773929 /* AppUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdater.swift; sourceTree = "<group>"; };
C0046CDA2A17B98400D87C9D /* NextcloudUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C04E2F202A17BB4D001BAD85 /* NextcloudIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivityTableViewCell.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2062,6 +2068,14 @@
path = Advanced;
sourceTree = "<group>";
};
B5D45E722DA5172900773929 /* AppUpdate */ = {
isa = PBXGroup;
children = (
B5D45E712DA5172900773929 /* AppUpdater.swift */,
);
path = AppUpdate;
sourceTree = "<group>";
};
C0046CDB2A17B98400D87C9D /* NextcloudUITests */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3226,6 +3240,7 @@
isa = PBXGroup;
children = (
AA517BB42D66149900F8D37C /* .tx */,
B5D45E722DA5172900773929 /* AppUpdate */,
F702F2CC25EE5B4F008F8E80 /* AppDelegate.swift */,
F794E13E2BBC0F70003693D7 /* SceneDelegate.swift */,
F7CF067A2E0FF38F0063AD04 /* NCAppStateManager.swift */,
Expand Down Expand Up @@ -4504,6 +4519,7 @@
F70898692EDDB51700EF85BD /* NCSelectOpen+SelectDelegate.swift in Sources */,
F7D4BF412CA2E8D800A5E746 /* TOPasscodeViewControllerAnimatedTransitioning.m in Sources */,
F7D4BF422CA2E8D800A5E746 /* TOPasscodeSettingsViewController.m in Sources */,
B5D45E732DA5172900773929 /* AppUpdater.swift in Sources */,
F7D4BF432CA2E8D800A5E746 /* TOPasscodeCircleImage.m in Sources */,
F78026102E9CFA3700B63436 /* NCTransfersView.swift in Sources */,
F7D4BF442CA2E8D800A5E746 /* TOPasscodeView.m in Sources */,
Expand Down
95 changes: 95 additions & 0 deletions iOSClient/AppUpdate/AppUpdater.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//
// AppUpdater.swift
// Nextcloud
//
// Created by Amrut Waghmare on 09/10/23.
// Copyright © 2023 Marino Faggiana. All rights reserved.
//

import Foundation
import FirebaseRemoteConfig

struct AppUpdaterKey {
static let lastUpdateCheckDate : String = "lastUpdateCheckDate"
}

class AppUpdater {
func checkForUpdate() {
checkUpdate{ (version, isForceupdate) in
DispatchQueue.main.async {
if let version = version, let isForceupdate = isForceupdate {
if (isForceupdate) {
self.showUpdateAlert(version: version, isForceUpdate: isForceupdate)
} else {
if self.checkLastUpdate() {
self.showUpdateAlert(version: version, isForceUpdate: isForceupdate)
}
}
}
}
}
}

func showUpdateAlert(version: String, isForceUpdate: Bool) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, let viewControlller = appDelegate.window?.rootViewController else { return }
let descriptionMsg = String(format: NSLocalizedString("update_description", comment: ""), version)
let alert = UIAlertController(title: NSLocalizedString("update_available", comment: ""), message: descriptionMsg, preferredStyle: .alert)
let updateAction = UIAlertAction(title: NSLocalizedString("update", comment: ""), style: .default, handler: { action in
guard let url = URL(string: NCBrandOptions.shared.appStoreUrl) else { return }
UIApplication.shared.open(url)
})
alert.addAction(updateAction)
if !isForceUpdate {
alert.addAction(UIAlertAction(title: NSLocalizedString("not_now", comment: ""), style: .default, handler: { action in
self.saveAppUpdateCheckDate()
}))
}
alert.preferredAction = updateAction
viewControlller.present(alert, animated: true, completion: {})
}

func checkLastUpdate() -> Bool {
if let lastUpdateCheckDate = UserDefaults.standard.object(forKey: AppUpdaterKey.lastUpdateCheckDate) as? Date {
return daysBetweenDate(from: lastUpdateCheckDate) > 7
} else {
return true
}
}

func checkUpdate(completion: @escaping (String?, Bool?) -> Void) {
let remoteConfig = RemoteConfig.remoteConfig()
remoteConfig.fetch(withExpirationDuration: 1) { (status, error) in
if status == .success {
remoteConfig.activate { value, error in
// Remote config values fetched successfully
let iOSVersionString = remoteConfig["ios_app_version"].stringValue ?? "default_value"
let isForcheUpdate = remoteConfig["ios_force_update"].boolValue
if let currentVersionString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
let currentVersion = Int(currentVersionString.replacingOccurrences(of: ".", with: "")),
let iOSVersion = Int(iOSVersionString.replacingOccurrences(of: ".", with: "")) {
// if let currentVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
if iOSVersion != currentVersion {
// There is an update available
completion(iOSVersionString, isForcheUpdate)
} else {
completion(nil, nil)
}
}

}
} else {
// Handle error
print("Error fetching remote config: \(error?.localizedDescription ?? "Unknown error")")
completion(nil, nil)
}
}
}

func saveAppUpdateCheckDate() {
UserDefaults.standard.setValue(Date(), forKey: AppUpdaterKey.lastUpdateCheckDate)
}

func daysBetweenDate(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: Date()).day ?? 0
}
}
38 changes: 32 additions & 6 deletions iOSClient/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
window?.makeKeyAndVisible()
}
} else {
if let navigationController = UIStoryboard(name: "NCIntro", bundle: nil).instantiateInitialViewController() as? UINavigationController {
if let viewController = UIStoryboard(name: "NCIntro", bundle: nil).instantiateInitialViewController() as? NCIntroViewController {
let navigationController = UINavigationController(rootViewController: viewController)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
}
Expand Down Expand Up @@ -197,20 +198,41 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {

func sceneWillEnterForeground(_ scene: UIScene) {
hidePrivacyProtectionWindow()

if let rootHostingController = scene.rootHostingController() {
if rootHostingController.anyRootView is Maintenance {
return
}
}
let session = SceneManager.shared.getSession(scene: scene)
let controller = SceneManager.shared.getController(scene: scene)


DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
Task {
if let tableAccount = await self.database.getTableAccountAsync(account: session.account) {
let num = await NCAutoUpload.shared.initAutoUpload(tblAccount: tableAccount)
nkLog(start: "Auto upload with \(num) photo")
}
}
}
AppUpdater().checkForUpdate()

NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterRichdocumentGrabFocus)
activateSceneForAccount(scene, account: session.account, controller: controller)
}

func sceneDidBecomeActive(_ scene: UIScene) {
hidePrivacyProtectionWindow()
// if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
// for window in windowScene.windows {
// let imageViews = window.allImageViews()
// // Do something with the imageViews
// for imageView in imageViews {
// print("Found image view: \(imageView)")
// imageView.tintColor = UITraitCollection.current.userInterfaceStyle == .dark ? .white : .black
// }
// }
// }
}

func sceneWillResignActive(_ scene: UIScene) {
Expand All @@ -221,6 +243,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
return
}

WidgetCenter.shared.reloadAllTimelines()

if NCPreferences().privacyScreenEnabled {
if SwiftEntryKit.isCurrentlyDisplaying {
SwiftEntryKit.dismiss {
Expand All @@ -236,6 +260,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
let app = UIApplication.shared
var bgID: UIBackgroundTaskIdentifier = .invalid
let isBackgroundRefreshStatus = (UIApplication.shared.backgroundRefreshStatus == .available)
// Must be outside the Task otherwise isSuspendingDatabaseOperation suspends it
let session = SceneManager.shared.getSession(scene: scene)
guard let tblAccount = NCManageDatabase.shared.getTableAccount(predicate: NSPredicate(format: "account == %@", session.account)) else {
return
Expand Down Expand Up @@ -488,9 +513,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {

Task {
try? await Task.sleep(nanoseconds: 1_000_000_000)

let num = await NCAutoUpload.shared.initAutoUpload()
nkLog(start: "Auto upload with \(num) photo")
if let tblAccount = await NCManageDatabase.shared.getTableAccountAsync(account: account) {
let num = await NCAutoUpload.shared.initAutoUpload(tblAccount: tblAccount)
nkLog(start: "Auto upload with \(num) photo")
}

try? await Task.sleep(nanoseconds: 1_500_000_000)
await NCService().startRequestServicesServer(account: account, controller: controller)
Expand Down