Skip to content
Open
52 changes: 39 additions & 13 deletions Brand/NCBrand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,43 @@ let userAgent: String = {
The codename embodies the concept of dynamic, living matter — reflecting our vision of a platform that is not only powerful and reliable, but also capable of continuous transformation and intelligent adaptation.
*/

struct NextcloudVersion: Comparable {
let major: Int
let minor: Int
let micro: Int

init(_ major: Int, _ minor: Int = 0, _ micro: Int = 0) {
self.major = major
self.minor = minor
self.micro = micro
}

init(_ capabilities: NKCapabilities.Capabilities) {
self.major = capabilities.serverVersionMajor
self.minor = capabilities.serverVersionMinor
self.micro = capabilities.serverVersionMicro
}

static let v18 = NextcloudVersion(18)
static let v20 = NextcloudVersion(20)
static let v23 = NextcloudVersion(23)
static let v24 = NextcloudVersion(24)
static let v25 = NextcloudVersion(25)
static let v26 = NextcloudVersion(26)
static let v27 = NextcloudVersion(27)
static let v28 = NextcloudVersion(28)
static let v30 = NextcloudVersion(30)
static let v31 = NextcloudVersion(31)
static let v32 = NextcloudVersion(32)
static let v32_0_2 = NextcloudVersion(32, 0, 2)
static let v33 = NextcloudVersion(33)
static let v34 = NextcloudVersion(34)

static func < (lhs: NextcloudVersion, rhs: NextcloudVersion) -> Bool {
(lhs.major, lhs.minor, lhs.micro) < (rhs.major, rhs.minor, rhs.micro)
}
}

final class NCBrandOptions: @unchecked Sendable {
static let shared = NCBrandOptions()

Expand Down Expand Up @@ -129,19 +166,8 @@ final class NCBrandOptions: @unchecked Sendable {
}

func isServerVersion(_ capabilities: NKCapabilities.Capabilities,
greaterOrEqualTo major: Int,
_ minor: Int,
_ micro: Int) -> Bool {

let server = (
capabilities.serverVersionMajor,
capabilities.serverVersionMinor,
capabilities.serverVersionMicro
)

let required = (major, minor, micro)

return server >= required
greaterOrEqualTo version: NextcloudVersion) -> Bool {
return NextcloudVersion(capabilities) >= version
}
}

Expand Down
5 changes: 4 additions & 1 deletion File Provider Extension/FileProviderData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class FileProviderData: NSObject {
return isPaginated
} else if serverUrl == NCUtilityFileSystem().getHomeServer(session: session),
let capabilities = await NextcloudKit.shared.getCapabilitiesAsync(account: session.account).capabilities,
NCBrandOptions.shared.isServerVersion(capabilities, greaterOrEqualTo: 32, 0, 2) {
NCBrandOptions.shared.isServerVersion(capabilities, greaterOrEqualTo: .v32_0_2) {
isPaginated = true
return true
}
Expand Down Expand Up @@ -197,6 +197,8 @@ class FileProviderData: NSObject {
etag: String?,
date: Date?,
size: Int64,
ownerId: String?,
permissions: String?,
task: URLSessionTask,
error: NKError) async {
guard let metadata = await NCManageDatabase.shared.getMetadataAsync(predicate: NSPredicate(format: "serverUrl == %@ AND fileName == %@ AND sessionTaskIdentifier == %d", serverUrl, fileName, task.taskIdentifier)) else {
Expand Down Expand Up @@ -229,6 +231,7 @@ class FileProviderData: NSObject {
if let fileId = fileProviderUtility().ocIdToFileId(ocId: ocId) {
metadata.fileId = fileId
}
await NCNetworking.shared.applyUploadResponse(to: metadata, ownerId: ownerId, permissions: permissions)

metadata.sceneIdentifier = nil
metadata.session = ""
Expand Down
12 changes: 11 additions & 1 deletion Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@
F3F442F02DDE2A7700FD701F /* NCMetadataPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F442ED2DDE292600FD701F /* NCMetadataPermissions.swift */; };
F3F442F12DDE2A7700FD701F /* NCMetadataPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F442ED2DDE292600FD701F /* NCMetadataPermissions.swift */; };
F3F442F42DDE2A7700FD701F /* NCMetadataPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F442ED2DDE292600FD701F /* NCMetadataPermissions.swift */; };
F6E0A1012FAD000100000001 /* NCNetworking+UploadResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E0A1002FAD000100000001 /* NCNetworking+UploadResponse.swift */; };
F6E0A1022FAD000100000001 /* NCNetworking+UploadResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E0A1002FAD000100000001 /* NCNetworking+UploadResponse.swift */; };
F6E0A1032FAD000100000001 /* NCNetworking+UploadResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E0A1002FAD000100000001 /* NCNetworking+UploadResponse.swift */; };
F6E0A1042FAD000100000001 /* NCNetworking+UploadResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E0A1002FAD000100000001 /* NCNetworking+UploadResponse.swift */; };
F700222C1EC479840080073F /* Custom.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F700222B1EC479840080073F /* Custom.xcassets */; };
F700222D1EC479840080073F /* Custom.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F700222B1EC479840080073F /* Custom.xcassets */; };
F700510122DF63AC003A3356 /* NCShare.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F700510022DF63AC003A3356 /* NCShare.storyboard */; };
Expand Down Expand Up @@ -1313,6 +1317,7 @@
F3E173AF2C9AF637006D177A /* ScreenAwakeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenAwakeManager.swift; sourceTree = "<group>"; };
F3E173BF2C9B1067006D177A /* AwakeMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AwakeMode.swift; sourceTree = "<group>"; };
F3F442ED2DDE292600FD701F /* NCMetadataPermissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMetadataPermissions.swift; sourceTree = "<group>"; };
F6E0A1002FAD000100000001 /* NCNetworking+UploadResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCNetworking+UploadResponse.swift"; sourceTree = "<group>"; };
F700222B1EC479840080073F /* Custom.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Custom.xcassets; sourceTree = "<group>"; };
F700510022DF63AC003A3356 /* NCShare.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCShare.storyboard; sourceTree = "<group>"; };
F700510422DF6A89003A3356 /* NCShare.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShare.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2492,6 +2497,7 @@
F74230F22C79B57200CA1ACA /* NCNetworking+Task.swift */,
F785129A2D79899E0087DDD0 /* NCNetworking+TermsOfService.swift */,
F71916102E2901E800E13E96 /* NCNetworking+Upload.swift */,
F6E0A1002FAD000100000001 /* NCNetworking+UploadResponse.swift */,
F7327E2F2B73A86700A462C7 /* NCNetworking+WebDAV.swift */,
F70D8D8024A4A9BF000A5756 /* NCNetworkingProcess.swift */,
F755BD9A20594AC7008C5FBB /* NCService.swift */,
Expand Down Expand Up @@ -4279,6 +4285,7 @@
F763413E2EBE5DC00056F538 /* FileProviderItem.swift in Sources */,
F7490E8729882CA8009DCE94 /* ThreadSafeDictionary.swift in Sources */,
F7E742FA2EC0A5BC00E2362A /* NCManageDatabase+Metadata.swift in Sources */,
F6E0A1032FAD000100000001 /* NCNetworking+UploadResponse.swift in Sources */,
F7E742FC2EC0A5FD00E2362A /* NCManageDatabase+Metadata+Session.swift in Sources */,
F3E173C52C9B1067006D177A /* AwakeMode.swift in Sources */,
F76341392EBE5CF80056F538 /* FileProviderData.swift in Sources */,
Expand Down Expand Up @@ -4328,6 +4335,7 @@
F740BEF02A35C2AD00E9B6D5 /* UILabel+Extension.swift in Sources */,
F7C30E01291BD2610017149B /* NCNetworkingE2EERename.swift in Sources */,
AF4BF61A27562A4B0081CEEF /* NCManageDatabase+Metadata.swift in Sources */,
F6E0A1022FAD000100000001 /* NCNetworking+UploadResponse.swift in Sources */,
AF4BF615275629E20081CEEF /* NCManageDatabase+Account.swift in Sources */,
F798F0E225880608000DAFFD /* UIColor+Extension.swift in Sources */,
F7C9B9202B582F550064EA91 /* NCManageDatabase+SecurityGuard.swift in Sources */,
Expand Down Expand Up @@ -4520,6 +4528,7 @@
F7E742F72EC0A4CD00E2362A /* NCManageDatabase+LocalFile.swift in Sources */,
F7E742F52EC0A3DD00E2362A /* NCManageDatabase+Directory.swift in Sources */,
F7E742F92EC0A5BC00E2362A /* NCManageDatabase+Metadata.swift in Sources */,
F6E0A1042FAD000100000001 /* NCNetworking+UploadResponse.swift in Sources */,
F763412E2EBE255B0056F538 /* NCNetworking+NextcloudKitDelegate.swift in Sources */,
F78E2D6929AF02DB0024D4F3 /* Database.swift in Sources */,
F771E3F320E239A600AFB62D /* FileProviderData.swift in Sources */,
Expand Down Expand Up @@ -4610,6 +4619,7 @@
F755CB402B8CB13C00CE27E9 /* NCMediaLayout.swift in Sources */,
F73EF7B72B0224AB0087E6E9 /* NCManageDatabase+ExternalSites.swift in Sources */,
AF4BF61927562A4B0081CEEF /* NCManageDatabase+Metadata.swift in Sources */,
F6E0A1012FAD000100000001 /* NCNetworking+UploadResponse.swift in Sources */,
F78A18B623CDD07D00F681F3 /* NCViewerRichWorkspaceWebView.swift in Sources */,
AFA2AC8527849604008E1EA7 /* NCActivityCommentView.swift in Sources */,
AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */,
Expand Down Expand Up @@ -6346,7 +6356,7 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/nextcloud/NextcloudKit";
requirement = {
branch = 7.3.2;
branch = main;
kind = branch;
};
};
Expand Down
2 changes: 1 addition & 1 deletion iOSClient/Assistant/NCAssistantModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class NCAssistantModel {
self.session = NCSession.shared.getSession(controller: controller)
let capabilities = NCNetworking.shared.capabilities[session.account] ?? NKCapabilities.Capabilities()

useV2 = capabilities.serverVersionMajor >= NCGlobal.shared.nextcloudVersion30
useV2 = NCBrandOptions.shared.isServerVersion(capabilities, greaterOrEqualTo: .v30)
loadAllTypes()
}

Expand Down
8 changes: 7 additions & 1 deletion iOSClient/Data/NCMetadataTranfersSuccess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ actor NCMetadataTranfersSuccess {
delegates.removeAll { $0 as AnyObject === delegate as AnyObject }
}

func append(metadata: tableMetadata, ocId: String, date: Date?, etag: String?) async {
func append(metadata: tableMetadata,
ocId: String,
date: Date?,
etag: String?,
ownerId: String? = nil,
permissions: String? = nil) async {
let status = metadata.status

metadata.ocId = ocId
Expand All @@ -41,6 +46,7 @@ actor NCMetadataTranfersSuccess {
if let fileId = self.utility.ocIdToFileId(ocId: ocId) {
metadata.fileId = fileId
}
await NCNetworking.shared.applyUploadResponse(to: metadata, ownerId: ownerId, permissions: permissions)

metadata.session = ""
metadata.sessionError = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
await banner.dismissAsync()
}

if results.nkError == .success || results.afError?.isExplicitlyCancelledError ?? false {
if results.nkError == .success || results.nkError == .cancelled {
print("ok")
} else {
await showErrorBanner(windowScene: windowScene, text: results.nkError.errorDescription, errorCode: results.nkError.errorCode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extension NCCollectionViewCommon {
setSearchBarLoading(true)
networkSearchInProgress = true

if capabilities.serverVersionMajor >= global.nextcloudVersion20 {
if NCBrandOptions.shared.isServerVersion(capabilities, greaterOrEqualTo: .v20) {
await unifiedSearch(text: text)
} else {
await searchLiteral(text: text)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class NCUploadAssetsModel: ObservableObject, NCCreateFormUploadConflictDelegate
self.uploadInProgress.toggle()
return
}
let autoMkcol = capabilities.serverVersionMajor >= NCGlobal.shared.nextcloudVersion33
let autoMkcol = NCBrandOptions.shared.isServerVersion(capabilities, greaterOrEqualTo: .v33)

func createProcessUploads() {
if !self.dismissView {
Expand Down
17 changes: 3 additions & 14 deletions iOSClient/Media/NCMedia+Netwoking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,12 @@ extension NCMedia {
guard let nkSession = NextcloudKit.shared.nkCommonInstance.nksessions.session(forAccount: account) else {
return (account, nil, .urlError)
}
let capabilities = await NKCapabilities.shared.getCapabilities(for: account)
let files: [NKFile] = []
let href = "/files/" + nkSession.userId + path

let elementDate: String
var lessDateString: String
var greaterDateString: String

if capabilities.serverVersionMajor >= self.global.nextcloudVersionFuture {
elementDate = "nc:metadata-photos-original_date_time"
lessDateString = String(lessDate.timeIntervalSince1970)
greaterDateString = String(greaterDate.timeIntervalSince1970)
} else {
Comment on lines -29 to -33
Copy link
Copy Markdown
Collaborator Author

@mpivchev mpivchev May 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ex: 32 >= 999999?
This never happens? I removed it @marinofaggiana

elementDate = "d:getlastmodified"
lessDateString = lessDate.formatted(using: "yyyy-MM-dd'T'HH:mm:ssZZZZZ")
greaterDateString = greaterDate.formatted(using: "yyyy-MM-dd'T'HH:mm:ssZZZZZ")
}
let elementDate = "d:getlastmodified"
let lessDateString = lessDate.formatted(using: "yyyy-MM-dd'T'HH:mm:ssZZZZZ")
let greaterDateString = greaterDate.formatted(using: "yyyy-MM-dd'T'HH:mm:ssZZZZZ")

let httpBodyString = String(format: getRequestBodySearchMedia(
createProperties: options.createProperties,
Expand Down
26 changes: 3 additions & 23 deletions iOSClient/Media/NCMediaDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,11 @@ extension NCMedia {
guard let tblAccount = await self.database.getTableAccountAsync(predicate: NSPredicate(format: "account == %@", self.session.account)) else {
return
}
let capabilities = await NKCapabilities.shared.getCapabilities(for: self.session.account)
let mediaPredicate = self.imageCache.getMediaPredicate(session: self.session,
mediaPath: tblAccount.mediaPath,
showOnlyImages: self.showOnlyImages,
showOnlyVideos: self.showOnlyVideos)
var sortedByKeyPath: String
if capabilities.serverVersionMajor >= self.global.nextcloudVersionFuture {
sortedByKeyPath = "datePhotosOriginal"
} else {
Comment on lines -20 to -22
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This never happens? I removed it @marinofaggiana

sortedByKeyPath = "date"
}
let sortedByKeyPath = "date"

if let metadatas = await self.database.getMetadatasAsync(predicate: mediaPredicate, sortedByKeyPath: sortedByKeyPath, ascending: false) {
self.database.filterAndNormalizeLivePhotos(from: metadatas) { metadatas in
Expand Down Expand Up @@ -71,7 +65,6 @@ extension NCMedia {
return
}

let capabilities = await NKCapabilities.shared.getCapabilities(for: session.account)
var lessDate = Date.distantFuture
var greaterDate = Date.distantPast
var visibleCells: [NCMediaCell] = []
Expand Down Expand Up @@ -175,18 +168,11 @@ extension NCMedia {
showOnlyImages: self.showOnlyImages,
showOnlyVideos: self.showOnlyVideos)

var predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [
NSPredicate(format: "date >= %@ AND date <= %@ AND mediaSearch == true", greaterDate as NSDate, lessDate as NSDate),
mediaPredicate
])

if capabilities.serverVersionMajor >= self.global.nextcloudVersionFuture {
predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [
NSPredicate(format: "datePhotosOriginal >= %@ AND datePhotosOriginal <= %@ AND mediaSearch == true", greaterDate as NSDate, lessDate as NSDate),
mediaPredicate
])
}
Comment on lines -183 to -188
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This never happens? I removed it @marinofaggiana


let localMetadatas = await self.database.getMetadatasAsync(predicate: predicate)

await MainActor.run {
Expand Down Expand Up @@ -257,13 +243,7 @@ public class NCMediaDataSource: NSObject {
}

private func getMetadataFromTableMetadata(_ metadata: tableMetadata) -> Metadata {
let capabilities = NCNetworking.shared.capabilities[metadata.account] ?? NKCapabilities.Capabilities()
let date: Date
if capabilities.serverVersionMajor >= self.global.nextcloudVersionFuture {
date = metadata.datePhotosOriginal as Date
} else {
date = metadata.date as Date
}
let date = metadata.date as Date
return Metadata(date: date,
etag: metadata.etag,
imageSize: CGSize(width: metadata.width, height: metadata.height),
Expand Down
2 changes: 1 addition & 1 deletion iOSClient/Menu/NCContextMenuPlus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class NCContextMenuPlus: NSObject {

// ------------------------------- RICHDOCUMENT TEXT

if capabilities.serverVersionMajor >= NCGlobal.shared.nextcloudVersion18,
if NCBrandOptions.shared.isServerVersion(capabilities, greaterOrEqualTo: .v18),
Copy link
Copy Markdown
Collaborator Author

@mpivchev mpivchev May 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better way to version check @marinofaggiana.
Can include only major or major minor and micro

directory?.richWorkspace == nil,
!isDirectoryE2EE,
isNetworkReachable {
Expand Down
2 changes: 1 addition & 1 deletion iOSClient/Menu/NCContextMenuProfile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class NCContextMenuProfile: NSObject {
func viewMenu() -> UIMenu {
let capabilities = NCNetworking.shared.capabilities[session.account] ?? NKCapabilities.Capabilities()

guard capabilities.serverVersionMajor >= NCGlobal.shared.nextcloudVersion23 else {
guard NCBrandOptions.shared.isServerVersion(capabilities, greaterOrEqualTo: .v23) else {
return UIMenu()
}

Expand Down
22 changes: 0 additions & 22 deletions iOSClient/NCGlobal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,6 @@ final class NCGlobal: Sendable {
let twoFactorNotificatioName = "twofactor_nextcloud_notification"
let termsOfServiceName = "terms_of_service"

// Nextcloud version
//
let nextcloudVersion18: Int = 18
let nextcloudVersion20: Int = 20
let nextcloudVersion23: Int = 23
let nextcloudVersion24: Int = 24
let nextcloudVersion25: Int = 25
let nextcloudVersion26: Int = 26
let nextcloudVersion27: Int = 27
let nextcloudVersion28: Int = 28
let nextcloudVersion30: Int = 30
let nextcloudVersion31: Int = 31
let nextcloudVersion32: Int = 32
let nextcloudVersion33: Int = 33
let nextcloudVersionFuture: Int = 99999


// Nextcloud unsupported
//
let nextcloud_unsupported_version: Int = 20

// Intro selector
//
let introLogin: Int = 0
Expand Down Expand Up @@ -146,7 +125,6 @@ final class NCGlobal: Sendable {

// Error
//
let errorRequestExplicityCancelled: Int = 15
let errorNotModified: Int = 304
let errorBadRequest: Int = 400
let errorUnauthorized401: Int = 401
Expand Down
Loading
Loading