Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
5de1771
internal
marinofaggiana Jun 18, 2025
fa3e231
cod
marinofaggiana Jun 19, 2025
2388b97
cod
marinofaggiana Jun 19, 2025
e0c71e3
improved directEditing
marinofaggiana Jun 19, 2025
5d6cf44
NKCapabilities
marinofaggiana Jun 19, 2025
c5f9347
cod
marinofaggiana Jun 19, 2025
6559222
cleaning
marinofaggiana Jun 19, 2025
09c33cd
fix parser
marinofaggiana Jun 19, 2025
95b7572
rename
marinofaggiana Jun 19, 2025
3a9e89c
code
marinofaggiana Jun 19, 2025
00000cf
added init
marinofaggiana Jun 19, 2025
3be9a48
fix
marinofaggiana Jun 19, 2025
5e6c4bc
fix
marinofaggiana Jun 19, 2025
2db6281
argh
marinofaggiana Jun 19, 2025
0914963
new class
marinofaggiana Jun 19, 2025
d82e7ac
cod
marinofaggiana Jun 19, 2025
b4c1c12
NKTypeIdentifiersHelper
marinofaggiana Jun 19, 2025
9c23311
improvements
marinofaggiana Jun 20, 2025
b318a32
license
marinofaggiana Jun 20, 2025
1940d0d
cleaning
marinofaggiana Jun 20, 2025
8861239
SynchronizedNKSessionArray
marinofaggiana Jun 20, 2025
8f8ba70
added foreach
marinofaggiana Jun 20, 2025
2972bc7
UniformTypeIdentifiers
marinofaggiana Jun 20, 2025
5edeeb1
UniformTypeIdentifiers
marinofaggiana Jun 20, 2025
ec8e436
cod
marinofaggiana Jun 20, 2025
3037d44
fix
marinofaggiana Jun 20, 2025
b3f8f01
code improved
marinofaggiana Jun 20, 2025
2c2b362
improved
marinofaggiana Jun 20, 2025
249a2a2
cleaning
marinofaggiana Jun 20, 2025
d21f06e
fix
marinofaggiana Jun 20, 2025
4bfc6d7
fix
marinofaggiana Jun 20, 2025
e04c292
cleaning
marinofaggiana Jun 20, 2025
465cf95
remove old code
marinofaggiana Jun 20, 2025
2c92998
cleaning
marinofaggiana Jun 20, 2025
2555fd4
added typeidentifier
marinofaggiana Jun 22, 2025
9f3e0c8
fix
marinofaggiana Jun 22, 2025
95def40
memory issue remove Data
marinofaggiana Jun 23, 2025
9b1c141
replace with headers
marinofaggiana Jun 23, 2025
3fc8cc9
response.response?.allHeaderFields
marinofaggiana Jun 23, 2025
9c5cb8c
licence
marinofaggiana Jun 24, 2025
2ab0012
clean
marinofaggiana Jun 24, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ Package.resolved

/.env-vars
*.generated.swift
/.build
32 changes: 28 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import PackageDescription
let package = Package(
name: "NextcloudKit",
platforms: [
.macOS(.v10_15),
.iOS(.v13),
.tvOS(.v13),
.watchOS(.v6),
.iOS(.v14),
.macOS(.v11),
.tvOS(.v14),
.watchOS(.v7),
.visionOS(.v1)
],
products: [
Expand Down Expand Up @@ -41,4 +41,28 @@ let package = Package(
name: "NextcloudKitIntegrationTests",
dependencies: ["NextcloudKit", "Mocker"])
]

/* Test simulate 6
targets: [
.target(
name: "NextcloudKit",
dependencies: ["Alamofire", "SwiftyJSON", "SwiftyXMLParser"],
swiftSettings: [
.enableUpcomingFeature("StrictConcurrency"), // simulate Swift 6
.enableExperimentalFeature("StrictConcurrency"),
.unsafeFlags(["-Xfrontend", "-warn-concurrency"]),
.unsafeFlags(["-Xfrontend", "-enable-actor-data-race-checks"])
]
),
.testTarget(
name: "NextcloudKitUnitTests",
dependencies: ["NextcloudKit", "Mocker"],
resources: [
.process("Resources")
]),
.testTarget(
name: "NextcloudKitIntegrationTests",
dependencies: ["NextcloudKit", "Mocker"])
]
*/
)
8 changes: 4 additions & 4 deletions Sources/NextcloudKit/Log/NKLogFileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public enum NKLogTagEmoji: String {
/// A logger that writes log messages to a file in a subdirectory of the user's Documents folder,
/// rotates the log daily
/// Compatible with iOS 13.0+ and Swift 6.
public final class NKLogFileManager {
public final class NKLogFileManager: @unchecked Sendable {

// MARK: - Singleton

Expand All @@ -79,13 +79,13 @@ public final class NKLogFileManager {
private let logDirectory: URL
public var logLevel: NKLogLevel
private var currentLogDate: String
private let logQueue = DispatchQueue(label: "LogWriterQueue", attributes: .concurrent)
private let rotationQueue = DispatchQueue(label: "LogRotationQueue")
private let logQueue = DispatchQueue(label: "com.nextcloud.LogWriterQueue", attributes: .concurrent)
private let rotationQueue = DispatchQueue(label: "com.nextcloud.LogRotationQueue")
private let fileManager = FileManager.default

// Cache for dynamic format strings, populated at runtime. Thread-safe via serial queue.
private static var cachedDynamicFormatters: [String: DateFormatter] = [:]
private static let formatterAccessQueue = DispatchQueue(label: "com.yourapp.dateformatter.cache")
private static let formatterAccessQueue = DispatchQueue(label: "com.nextcloud.dateformatter.cache")

// MARK: - Initialization

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: Nextcloud GmbH
// SPDX-FileCopyrightText: 2025 Marino Faggiana
// SPDX-License-Identifier: GPL-3.0-or-later

import Foundation

public enum NKEditorDetailsConverter {

/// Parses and converts raw JSON `Data` into `[NKEditorDetailsEditors]` and `[NKEditorDetailsCreators]`.
/// - Parameter data: Raw JSON `Data` from the editors/creators endpoint.
/// - Returns: A tuple with editors and creators.
/// - Throws: Decoding error if parsing fails.
public static func from(data: Data) throws -> (editors: [NKEditorDetailsEditor], creators: [NKEditorDetailsCreator]) {
let decoded = try JSONDecoder().decode(NKEditorDetailsResponse.self, from: data)
let editors = decoded.ocs.data.editorsArray()
let creators = decoded.ocs.data.creatorsArray()

if NKLogFileManager.shared.logLevel == .verbose {
data.printJson()
}

Check warning on line 21 in Sources/NextcloudKit/Models/EditorDetails/NKEditorDetailsConverter.swift

View workflow job for this annotation

GitHub Actions / Lint

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
return (editors, creators)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: Nextcloud GmbH
// SPDX-FileCopyrightText: 2025 Marino Faggiana
// SPDX-License-Identifier: GPL-3.0-or-later

import Foundation

public extension NKEditorDetailsResponse.OCS.DataClass {
func editorsArray() -> [NKEditorDetailsEditor] {
Array(editors.values)
}

func creatorsArray() -> [NKEditorDetailsCreator] {
Array(creators.values)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-FileCopyrightText: Nextcloud GmbH
// SPDX-FileCopyrightText: 2025 Marino Faggiana
// SPDX-License-Identifier: GPL-3.0-or-later

import Foundation

public struct NKEditorDetailsResponse: Codable, Sendable {
public let ocs: OCS

public struct OCS: Codable, Sendable {
public let data: DataClass

public struct DataClass: Codable, Sendable {
public let editors: [String: NKEditorDetailsEditor]
public let creators: [String: NKEditorDetailsCreator]
}
}
}

public struct NKEditorTemplateResponse: Codable, Sendable {
public let ocs: OCS

public struct OCS: Codable, Sendable {
public let data: DataClass

public struct DataClass: Codable, Sendable {
public let editors: [NKEditorTemplate]
}
}
}

public struct NKEditorDetailsEditor: Codable, Sendable {
public let identifier: String
public let mimetypes: [String]
public let name: String
public let optionalMimetypes: [String]
public let secure: Bool

enum CodingKeys: String, CodingKey {
case identifier = "id"
case mimetypes
case name
case optionalMimetypes
case secure
}
}

public struct NKEditorDetailsCreator: Codable, Sendable {
public let identifier: String
public let templates: Bool
public let mimetype: String
public let name: String
public let editor: String
public let ext: String

enum CodingKeys: String, CodingKey {
case identifier = "id"
case templates
case mimetype
case name
case editor
case ext = "extension"
}
}

public struct NKEditorTemplate: Codable, Sendable {
public var ext: String
public var identifier: String
public var name: String
public var preview: String

enum CodingKeys: String, CodingKey {
case ext = "extension"
case identifier = "id"
case name
case preview
}

public init(ext: String = "", identifier: String = "", name: String = "", preview: String = "") {
self.ext = ext
self.identifier = identifier
self.name = name
self.preview = preview
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@
return xml["ocs", "data", "apppassword"].text
}

func convertDataFile(xmlData: Data, nkSession: NKSession, showHiddenFiles: Bool, includeHiddenFiles: [String]) -> [NKFile] {
func convertDataFile(xmlData: Data, nkSession: NKSession, showHiddenFiles: Bool, includeHiddenFiles: [String]) async -> [NKFile] {

Check warning on line 256 in Sources/NextcloudKit/Models/NKDataFileXML.swift

View workflow job for this annotation

GitHub Actions / Lint

Function Body Length Violation: Function body should span 200 lines or less excluding comments and whitespace: currently spans 247 lines (function_body_length)
var files: [NKFile] = []
let rootFiles = "/" + nkSession.dav + "/files/"
guard let baseUrl = self.nkCommonInstance.getHostName(urlString: nkSession.urlBase) else {
Expand Down Expand Up @@ -309,7 +309,7 @@
let propstat = element["d:propstat"][0]

if let getlastmodified = propstat["d:prop", "d:getlastmodified"].text,
let date = getlastmodified.parsedDate(using: "EEE, dd MMM y HH:mm:ss zzz") {

Check warning on line 312 in Sources/NextcloudKit/Models/NKDataFileXML.swift

View workflow job for this annotation

GitHub Actions / Lint

Trailing Whitespace Violation: Lines should not have trailing whitespace (trailing_whitespace)
file.date = date
}

Expand Down Expand Up @@ -534,12 +534,14 @@
file.downloadLimits.append(NKDownloadLimit(count: count, limit: limit, token: token))
}

let results = self.nkCommonInstance.getInternalType(fileName: file.fileName, mimeType: file.contentType, directory: file.directory, account: nkSession.account)
let results = await self.nkCommonInstance.typeIdentifiers.getInternalType(fileName: file.fileName, mimeType: file.contentType, directory: file.directory, account: nkSession.account)

file.contentType = results.mimeType
file.iconName = results.iconName
file.name = "files"
file.classFile = results.classFile
file.typeIdentifier = results.typeIdentifier

file.urlBase = nkSession.urlBase
file.user = nkSession.user
file.userId = nkSession.userId
Expand All @@ -557,8 +559,8 @@
}
if index < files.count - 1,
(files[index].fileName as NSString).deletingPathExtension == (files[index + 1].fileName as NSString) .deletingPathExtension,
files[index].classFile == NKCommon.TypeClassFile.image.rawValue,
files[index + 1].classFile == NKCommon.TypeClassFile.video.rawValue {
files[index].classFile == NKTypeClassFile.image.rawValue,
files[index + 1].classFile == NKTypeClassFile.video.rawValue {
files[index].livePhotoFile = files[index + 1].fileId
files[index + 1].livePhotoFile = files[index].fileId
}
Expand All @@ -567,7 +569,7 @@
return files
}

func convertDataTrash(xmlData: Data, nkSession: NKSession, showHiddenFiles: Bool) -> [NKTrash] {
func convertDataTrash(xmlData: Data, nkSession: NKSession, showHiddenFiles: Bool) async -> [NKTrash] {
var files: [NKTrash] = []
var first: Bool = true
guard let baseUrl = self.nkCommonInstance.getHostName(urlString: nkSession.urlBase) else {
Expand All @@ -581,7 +583,7 @@
first = false
continue
}
let file = NKTrash()
var file = NKTrash()
if let href = element["d:href"].text {
var fileNamePath = href

Expand Down Expand Up @@ -644,11 +646,12 @@
file.trashbinDeletionTime = Date(timeIntervalSince1970: trashbinDeletionTimeDouble)
}

let results = self.nkCommonInstance.getInternalType(fileName: file.trashbinFileName, mimeType: file.contentType, directory: file.directory, account: nkSession.account)
let results = await self.nkCommonInstance.typeIdentifiers.getInternalType(fileName: file.trashbinFileName, mimeType: file.contentType, directory: file.directory, account: nkSession.account)

file.contentType = results.mimeType
file.classFile = results.classFile
file.iconName = results.iconName
file.typeIdentifier = results.typeIdentifier

files.append(file)
}
Expand Down
15 changes: 0 additions & 15 deletions Sources/NextcloudKit/Models/NKEditorDetailsCreators.swift

This file was deleted.

13 changes: 0 additions & 13 deletions Sources/NextcloudKit/Models/NKEditorDetailsEditors.swift

This file was deleted.

15 changes: 0 additions & 15 deletions Sources/NextcloudKit/Models/NKEditorTemplates.swift

This file was deleted.

Loading
Loading