### SMB Client Example for File Operations Source: https://github.com/amosavian/amsmb2/blob/master/README.md This example demonstrates how to create an SMB client, connect to a share, list directory contents, and move files. Ensure proper error handling and consider explicit disconnection if needed. ```swift import AMSMB2 class SMBClient: @unchecked Sendable { /// connect to: `smb://guest@XXX.XXX.XX.XX/share` let serverURL = URL(string: "smb://XXX.XXX.XX.XX")! let credential = URLCredential(user: "guest", password: "", persistence: URLCredential.Persistence.forSession) let share = "share" lazy private var client = SMB2Manager(url: self.serverURL, credential: self.credential)! private func connect() async throws -> SMB2Manager { // AMSMB2 can handle queueing connection requests try await client.connectShare(name: self.share) return self.client } func listDirectory(path: String) { Task { do { let client = try await connect() let files = try await client.contentsOfDirectory(atPath: path) for entry in files { print( "name:", entry[.nameKey] as! String, ", path:", entry[.pathKey] as! String, ", type:", entry[.fileResourceTypeKey] as! URLFileResourceType, ", size:", entry[.fileSizeKey] as! Int64, ", modified:", entry[.contentModificationDateKey] as! Date, ", created:", entry[.creationDateKey] as! Date) } } catch { print(error) } } } func moveItem(path: String, to toPath: String) { Task { do { let client = try await self.connect() try await client.moveItem(atPath: path, toPath: toPath) print("\(path) moved successfully.") // Disconnecting is optional, it will be called eventually // when `AMSMB2` object is freed. // You may call it explicitly to detect errors. try await client.disconnectShare() } catch { print(error) } } } } ``` -------------------------------- ### NTLM Authentication Configuration Example Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Example of initializing SMB2Manager with NTLM authentication details, including server URL, domain, and user credentials. ```swift let manager = SMB2Manager( url: URL(string: "smb://server.local")!, domain: "COMPANY", credential: URLCredential(user: "username", password: "pass", persistence: .forSession) ) ``` -------------------------------- ### Basic Server URL Example Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Example of creating a URL for an SMB server using its IP address. ```swift // Basic server address let url = URL(string: "smb://192.168.1.100")! ``` -------------------------------- ### Iterate and Print Directory Entry Details Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/types.md Example demonstrating how to use the dictionary extensions to print details for each entry in a directory. ```swift let entries = try await manager.contentsOfDirectory(atPath: "/documents") for entry in entries { print("Name: \(entry.name ?? "?")") print("Size: \(entry.fileSize ?? 0) bytes") print("Modified: \(entry.contentModificationDate ?? Date())") if entry.isDirectory { print("(directory)") } } ``` -------------------------------- ### Server URL with Embedded Credentials Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Example of creating a URL for an SMB server including username and password. ```swift // With embedded credentials let url = URL(string: "smb://user:password@server.local")! ``` -------------------------------- ### Server URL with Domain Prefix Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Example of creating a URL for an SMB server with credentials including a domain prefix. ```swift // With domain prefix let url = URL(string: "smb://DOMAIN\user:password@server.local")! ``` -------------------------------- ### Server URL with Explicit Port Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Example of creating a URL for an SMB server with a specified port number. ```swift // With explicit port let url = URL(string: "smb://server.local:445")! ``` -------------------------------- ### Retrieve and Print File System Attributes Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/types.md Example showing how to fetch file system attributes and access specific values like total size and free space. ```swift let attrs = try await manager.attributesOfFileSystem(forPath: "/documents") if let totalSize = attrs[.systemSize] as? NSNumber { print("Total size: \(totalSize.int64Value) bytes") } if let freeSize = attrs[.systemFreeSize] as? NSNumber { print("Free space: \(freeSize.int64Value) bytes") } ``` -------------------------------- ### attributesOfFileSystem(forPath:completionHandler:) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/INDEX.md Get information about the file system for a given path. ```APIDOC ## attributesOfFileSystem(forPath:completionHandler:) ### Description Get information about the file system for a given path. ### Method [Method details not specified in source] ### Endpoint [Endpoint details not specified in source] ### Parameters #### Path Parameters - **forPath** (string) - Required - The path to query file system information for. #### Query Parameters [No query parameters specified] #### Request Body [No request body specified] ### Request Example [No request example specified] ### Response #### Success Response [Success response details not specified in source] #### Response Example [No response example specified] ``` -------------------------------- ### Stream Data to File Using AsyncSequence Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/types.md Example of writing data to a file by streaming it using an AsyncSequence. ```swift func dataStream() -> AsyncThrowingStream { AsyncThrowingStream { continuation in for i in 0..<100 { let chunk = "Chunk \(i)\n".data(using: .utf8)! continuation.yield(chunk) } continuation.finish() } } try await manager.write(stream: dataStream(), toPath: "/output.txt") ``` -------------------------------- ### Set SMB2 Manager Timeout Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/types.md Example of setting the timeout property for an SMB2Manager instance. ```swift manager.timeout = 30.0 // 30 second timeout manager.timeout = 0 // Disable timeout ``` -------------------------------- ### Monitor File Changes with SMB2FileChangeType Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/types.md Example of how to use `SMB2FileChangeType` to monitor specific file system changes. You can combine options or use predefined convenience values like `.contentModify`. ```swift let filter: SMB2FileChangeType = [.fileName, .size] try await manager.monitorItem(atPath: "/documents", for: filter) // Predefined combination: try await manager.monitorItem(atPath: "/documents", for: .contentModify) ``` -------------------------------- ### Create Directory if Missing Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/README.md This pattern safely creates a directory only if it does not already exist. It first attempts to get attributes of the path and proceeds with creation if the attributes are nil (indicating the path doesn't exist). ```swift let attrs = try? await manager.attributesOfItem(atPath: path) if attrs == nil { try await manager.createDirectory(atPath: path) } ``` -------------------------------- ### Install AMSMB2 Swift Package Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/README.md Add the AMSMB2 Swift package to your Package.swift file to include the library in your project. Use the .upToNextMinor version for compatibility. ```swift .package(url: "https://github.com/amosavian/AMSMB2", .upToNextMinor(from: "3.0.0")) ``` -------------------------------- ### Get File System Space Information Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Retrieves total capacity and available free space of the file system. Displays the information in gigabytes for readability. ```swift let fsAttrs = try await manager.attributesOfFileSystem(forPath: "/") if let totalSize = fsAttrs[.systemSize] as? NSNumber { let sizeGB = Double(totalSize.int64Value) / (1024 * 1024 * 1024) print("Total capacity: \(String(format: "%.1f", sizeGB)) GB") } if let freeSize = fsAttrs[.systemFreeSize] as? NSNumber { let freeGB = Double(freeSize.int64Value) / (1024 * 1024 * 1024) print("Available space: \(String(format: "%.1f", freeGB)) GB") } ``` -------------------------------- ### Get File Information using Convenience Properties Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Accesses file attributes using convenient properties provided by the library. Simplifies retrieving common file details like name, path, size, modification date, and directory status. ```swift let attrs = try await manager.attributesOfItem(atPath: path) print("Name: \(attrs.name ?? "?")") print("Path: \(attrs.path ?? "?")") print("Size: \(attrs.fileSize ?? 0) bytes") print("Modified: \(attrs.contentModificationDate ?? Date())") print("Is directory: \(attrs.isDirectory)") ``` -------------------------------- ### Get File System Attributes (Async) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Asynchronously retrieves file system attributes. Use this for checking disk space and other file system metrics with Swift concurrency. ```swift open func attributesOfFileSystem(forPath path: String) async throws -> [FileAttributeKey: Any] ``` -------------------------------- ### Initialize and Connect to SMB Share Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/00-START-HERE.txt Demonstrates the basic steps to initialize the SMB2Manager and establish a connection to an SMB share using provided credentials. ```swift import AMSMB2 let manager = SMB2Manager( host: "your_server_address", port: 445, username: "your_username", password: "your_password", domain: "your_domain" ) Task { do { try await manager.connect() print("Successfully connected to SMB share.") } catch { print("Connection failed: \(error)") } } ``` -------------------------------- ### Initialize SMB2Manager with Domain Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Shows how to initialize SMB2Manager when the domain needs to be specified separately from the username. ```swift let manager = SMB2Manager( url: url, domain: "MYCOMPANY", credential: credential ) ``` -------------------------------- ### attributesOfItem(atPath:completionHandler:) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/INDEX.md Get the attributes of a file or directory at the specified path. ```APIDOC ## attributesOfItem(atPath:completionHandler:) ### Description Get the attributes of a file or directory at the specified path. ### Method [Method details not specified in source] ### Endpoint [Endpoint details not specified in source] ### Parameters #### Path Parameters - **atPath** (string) - Required - The path to the item. #### Query Parameters [No query parameters specified] #### Request Body [No request body specified] ### Request Example [No request example specified] ### Response #### Success Response [Success response details not specified in source] #### Response Example [No response example specified] ``` -------------------------------- ### Initialize SMB2Manager for Guest Access (Explicit) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Shows how to explicitly create a guest credential for anonymous access. ```swift // Explicitly create guest credential: let credential = URLCredential(user: "guest", password: "", persistence: .forSession) let manager = SMB2Manager(url: url, credential: credential) ``` -------------------------------- ### destinationOfSymbolicLink(atPath:completionHandler:) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/INDEX.md Get the target path of a symbolic link at the specified path. ```APIDOC ## destinationOfSymbolicLink(atPath:completionHandler:) ### Description Get the target path of a symbolic link at the specified path. ### Method [Method details not specified in source] ### Endpoint [Endpoint details not specified in source] ### Parameters #### Path Parameters - **atPath** (string) - Required - The path to the symbolic link. #### Query Parameters [No query parameters specified] #### Request Body [No request body specified] ### Request Example [No request example specified] ### Response #### Success Response [Success response details not specified in source] #### Response Example [No response example specified] ``` -------------------------------- ### Initialize SMB2Manager with Domain in Username (Semicolon) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Demonstrates initializing SMB2Manager by separating the domain and username with a semicolon. ```swift let credential = URLCredential( user: "MYCOMPANY;username", password: "password", persistence: .forSession ) let manager = SMB2Manager(url: url, credential: credential) ``` -------------------------------- ### Initialize SMB2Manager for Guest Access (Nil Credential) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Illustrates initializing SMB2Manager with a nil credential to use guest access by default. ```swift // Or pass nil to use guest as default: let manager = SMB2Manager(url: url, credential: nil) ``` -------------------------------- ### Basic SMB2 Manager Initialization and Connection Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Initializes the SMB2Manager with a server URL and credentials, then connects to a specific share. Ensure the URL and credentials are valid. ```swift import AMSMB2 // Create a manager with server URL and credentials let url = URL(string: "smb://192.168.1.100")! let credential = URLCredential( user: "username", password: "password", persistence: .forSession ) guard let manager = SMB2Manager(url: url, credential: credential) else { print("Invalid URL") return } // Connect to a share do { try await manager.connectShare(name: "Documents") print("Connected!") } catch { print("Connection failed: \(error)") } ``` -------------------------------- ### Initialize SMB2Directory Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Initializes an `SMB2Directory` object to begin directory enumeration. Requires a path and an SMB2Client instance. ```swift final class SMB2Directory { init(_ path: String, on client: SMB2Client) throws } ``` -------------------------------- ### Project Navigation Structure Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/MANIFEST.md Illustrates the hierarchical relationship between key documentation files, starting from the entry point. ```text 00-START-HERE.txt (Entry point) ↓ INDEX.md (Find anything by topic) ↓ README.md (Understanding overview) ↓ smb2manager.md (API reference) ├── types.md (Type definitions) ├── configuration.md (Setup) ├── errors.md (Error handling) ├── file-operations.md (Advanced) └── examples.md (Usage code) ``` -------------------------------- ### echo(completionHandler:) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/INDEX.md Test the connectivity to the SMB server. ```APIDOC ## echo(completionHandler:) ### Description Test the connectivity to the SMB server. ### Method [Method details not specified in source] ### Endpoint [Endpoint details not specified in source] ### Parameters [No parameters specified] ### Request Example [No request example specified] ### Response #### Success Response [Success response details not specified in source] #### Response Example [No response example specified] ``` -------------------------------- ### Initialize SMB2Manager with URL and Credentials Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Initializes an SMB2Manager instance with a server URL and optional user credentials. The URL must have a valid host and use the 'smb' scheme. Supports NTLM authentication or guest access if credentials are not provided. ```swift public init?(url: URL, domain: String = "", credential: URLCredential?) ``` ```swift let url = URL(string: "smb://192.168.1.100")! let credential = URLCredential(user: "username", password: "password", persistence: .forSession) let manager = SMB2Manager(url: url, credential: credential) ``` ```swift let url = URL(string: "smb://user@192.168.1.100")! let manager = SMB2Manager(url: url) ``` -------------------------------- ### Read Symbolic Link Target Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Get the path that a symbolic link points to. This is useful for inspecting link destinations. ```swift let target = try await manager.destinationOfSymbolicLink(atPath: "/shortcuts/link") print("Link points to: \(target)") ``` -------------------------------- ### Initialize SMB2Manager with Domain in Username (Backslash) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Illustrates initializing SMB2Manager by prefixing the username with the domain and a backslash. ```swift let credential = URLCredential( user: "MYCOMPANY\username", password: "password", persistence: .forSession ) let manager = SMB2Manager(url: url, credential: credential) ``` -------------------------------- ### Recursive Directory Listing Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Retrieves all files within a directory and its subdirectories. Useful for getting a complete list of all items. ```swift let allFiles = try await manager.contentsOfDirectory( atPath: "/documents", recursive: true ) print("Total files: \(allFiles.count)") ``` -------------------------------- ### Basic SMB Share Operations Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/README.md Demonstrates creating a manager, connecting to a share, listing files, reading and writing files, and disconnecting. Ensure you have the AMSMB2 library imported. ```swift import AMSMB2 // Create manager let url = URL(string: "smb://192.168.1.100")! let credential = URLCredential(user: "user", password: "pass", persistence: .forSession) let manager = SMB2Manager(url: url, credential: credential)! // Connect to share try await manager.connectShare(name: "Documents") // List files let files = try await manager.contentsOfDirectory(atPath: "/") for file in files { print(file.name ?? "?") } // Read file let data = try await manager.contents(atPath: "/file.txt") let text = String(data: data, encoding: .utf8) print(text) // Write file let newData = "Hello".data(using: .utf8)! try await manager.write(data: newData, toPath: "/greeting.txt") // Disconnect try await manager.disconnectShare() ``` -------------------------------- ### Get File Attributes (Async) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Asynchronously retrieves attributes of a file or directory. This is the modern Swift concurrency approach for accessing file metadata. ```swift open func attributesOfItem(atPath path: String) async throws -> [URLResourceKey: any Sendable] ``` -------------------------------- ### Create a Directory Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/00-START-HERE.txt Creates a new directory at the specified path on the SMB share. The parent directory must exist. ```swift import AMSMB2 // Assuming manager is already initialized and connected let manager = SMB2Manager( host: "your_server_address", port: 445, username: "your_username", password: "your_password", domain: "your_domain" ) Task { do { try await manager.connect() let directoryPath = "/path/to/new/directory" try await manager.createDirectory(directoryPath) print("Successfully created directory.") } catch { print("Failed to create directory: \(error)") } } ``` -------------------------------- ### Connect to an SMB Share (Async/Await) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Connects to a specified SMB share using async/await syntax. Optionally enables SMB3 encryption. Throws an error if the connection fails. ```swift open func connectShare(name: String, encrypted: Bool = false) async throws ``` ```swift do { try await manager.connectShare(name: "Documents") print("Connected") } catch { print("Failed: \(error)") } ``` -------------------------------- ### Get Symbolic Link Destination (Async) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Asynchronously retrieves the target path of a symbolic link. Use this with Swift concurrency for resolving symbolic links. ```swift open func destinationOfSymbolicLink(atPath path: String) async throws -> String ``` -------------------------------- ### Populating smb2_stat_64 with timespec from Date Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Shows how to initialize an smb2_stat_64 structure using a Swift Date converted to timespec. ```swift let now = Date() var stat = smb2_stat_64() let ts = timespec(now) stat.smb2_btime = ts.tv_sec stat.smb2_btime_nsec = ts.tv_nsec ``` -------------------------------- ### SMB2FileHandle Convenience Initializers Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Offers convenience initializers for `SMB2FileHandle` to quickly open files with common access modes and options, simplifying file opening logic. ```APIDOC ## SMB2FileHandle Convenience Initializers ### Description Offers convenience initializers for `SMB2FileHandle` to quickly open files with common access modes and options, simplifying file opening logic. ### Initializers - `convenience init(forReadingAtPath path: String, on client: SMB2Client)` - `convenience init(forWritingAtPath path: String, on client: SMB2Client)` - `convenience init(forUpdatingAtPath path: String, on client: SMB2Client)` - `convenience init(forOverwritingAtPath path: String, on client: SMB2Client)` - `convenience init(forOutputAtPath path: String, on client: SMB2Client)` - `convenience init(forCreatingIfNotExistsAtPath path: String, on client: SMB2Client)` ### Notes These initializers wrap a generic initializer with predefined access modes and options suitable for common use cases such as reading, writing, appending, overwriting, creating new files, or creating files if they don't exist. ``` -------------------------------- ### Get Symbolic Link Destination (Completion Handler) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Retrieves the path that a symbolic link points to using a completion handler. The returned path may be relative. ```swift open func destinationOfSymbolicLink( atPath path: String, completionHandler: @Sendable @escaping (_ result: Result) -> Void ) ``` -------------------------------- ### Create Directory Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Create a new directory at the specified path. The parent directories must already exist. ```swift try await manager.createDirectory(atPath: "/documents/new_folder") ``` -------------------------------- ### SMB2FileHandle Convenience Initializers for File Opening Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Offers convenience initializers for opening files with specific access modes and options, simplifying common file operations. ```swift convenience init(forReadingAtPath path: String, on client: SMB2Client) convenience init(forWritingAtPath path: String, on client: SMB2Client) convenience init(forUpdatingAtPath path: String, on client: SMB2Client) convenience init(forOverwritingAtPath path: String, on client: SMB2Client) convenience init(forOutputAtPath path: String, on client: SMB2Client) convenience init(forCreatingIfNotExistsAtPath path: String, on client: SMB2Client) ``` -------------------------------- ### SMBSyncService Class Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md This Swift class manages periodic synchronization with an SMB2 server. It starts and stops a timer to perform synchronization tasks and includes a method to monitor for item changes. ```swift class SMBSyncService { let manager: SMB2Manager var syncTimer: Timer? func startSync(interval: TimeInterval = 60) { syncTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { _ in Task { try await self.performSync() } } } func stopSync() { syncTimer?.invalidate() } private func performSync() async throws { try await manager.echo() // Keep connection alive // Perform sync operations let changes = try await manager.monitorItem( atPath: "/sync", for: .contentModify ) // Handle changes for change in changes { print("Syncing: \(change.fileName)") } } } ``` -------------------------------- ### List Files in a Directory Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/00-START-HERE.txt Shows how to list the contents of a specified directory on the connected SMB share. Requires an active connection. ```swift import AMSMB2 // Assuming manager is already initialized and connected let manager = SMB2Manager( host: "your_server_address", port: 445, username: "your_username", password: "your_password", domain: "your_domain" ) Task { do { try await manager.connect() let files = try await manager.list("/path/to/directory") for file in files { print("\(file.name) - \(file.isDirectory ? "Directory" : "File")") } } catch { print("Failed to list directory: \(error)") } } ``` -------------------------------- ### Get File System Attributes (Completion Handler) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Retrieves attributes of the file system containing a given path using a completion handler. Useful for checking disk space or node counts. ```swift open func attributesOfFileSystem( forPath path: String, completionHandler: @Sendable @escaping (_ result: Result<[FileAttributeKey: any Sendable], any Error>) -> Void ) ``` -------------------------------- ### SMB2Manager Initialization Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Initializes an SMB2Manager with a server URL and optional credentials. Supports NTLM authentication and guest access. ```APIDOC ## init?(url:domain:credential:) ### Description Initializes an SMB2Manager with a server URL and optional credentials. Supports NTLM authentication and guest access. ### Parameters #### Path Parameters * **url** (URL) - Required - SMB server URL (scheme must be "smb") * **domain** (String) - Optional - User's domain/workgroup, if applicable (Default: "") * **credential** (URLCredential?) - Optional - Username and password for authentication (Default: nil) ### Returns An initialized `SMB2Manager` instance, or `nil` if the URL scheme is invalid. ### Note Only NTLM user/password authentication is currently supported. The URL must have a valid host component. If credentials are not provided, the connection defaults to guest access. ### Example ```swift let url = URL(string: "smb://192.168.1.100")! let credential = URLCredential(user: "username", password: "password", persistence: .forSession) let manager = SMB2Manager(url: url, credential: credential) // Using credentials embedded in the URL: let urlWithCreds = URL(string: "smb://user@192.168.1.100")! let managerWithCreds = SMB2Manager(url: urlWithCreds) ``` ``` -------------------------------- ### Get File Attributes (Completion Handler) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Retrieves attributes of a file or directory using a completion handler. Use this when you need to access file metadata like size or modification date asynchronously. ```swift open func attributesOfItem( atPath path: String, completionHandler: @Sendable @escaping (_ result: Result<[URLResourceKey: any Sendable], any Error>) -> Void ) ``` ```swift manager.attributesOfItem(atPath: "/documents/file.txt") { result in switch result { case .success(let attrs): if let size = attrs[.fileSizeKey] as? Int64 { print("File size: \(size) bytes") } if let modified = attrs[.contentModificationDateKey] as? Date { print("Modified: \(modified)") } case .failure(let error): print("Failed to get attributes: \(error)") } } ``` -------------------------------- ### Get File Information Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Retrieves detailed attributes for a specific file, including size, modification date, creation date, and whether it's a directory. Accesses attributes using dictionary keys. ```swift let attrs = try await manager.attributesOfItem(atPath: "/documents/report.pdf") if let size = attrs[.fileSizeKey] as? Int64 { print("File size: \(size) bytes") } if let modified = attrs[.contentModificationDateKey] as? Date { print("Last modified: \(modified)") } if let created = attrs[.creationDateKey] as? Date { print("Created: \(created)") } let isDir = (attrs[.isDirectoryKey] as? NSNumber)?.boolValue ?? false print("Is directory: \(isDir)") ``` -------------------------------- ### Manual File Reading with Seek and Close Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Demonstrates manual file reading from an SMB share using SMB2FileHandle, including seeking to a specific offset and closing the file handle. ```swift let file = try SMB2FileHandle(forReadingAtPath: "/large.bin", on: client) try file.seek(offset: 1_000_000, from: .start) let chunk = try file.read(length: 65536) try file.close() ``` -------------------------------- ### Configure SMB2 Manager with URLCredential Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/types.md Demonstrates creating an SMB2Manager instance with a URLCredential for authentication. ```swift let credential = URLCredential( user: "username", password: "password", persistence: .forSession ) let manager = SMB2Manager(url: url, credential: credential) ``` -------------------------------- ### Handle POSIX Errors in Production Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md In production code, use standard Swift error handling to catch and log specific POSIX errors. This example demonstrates how to cast an error to POSIXError and print its code and description. ```swift do { try await manager.connectShare(name: "share") } catch let error as POSIXError { print("Debug: errno=\(error.code.rawValue), description=\(error.localizedDescription)") } ``` -------------------------------- ### SMB2Manager Constructor Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md The SMB2Manager is initialized with the server URL, an optional domain, and authentication credentials. ```swift public init?(url: URL, domain: String = "", credential: URLCredential?) ``` -------------------------------- ### Connection Methods Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/README.md Methods for establishing, testing, and closing connections to SMB2 shares, as well as enumerating available shares. ```APIDOC ## Connection Methods ### `connectShare(name:encrypted:)` Establishes a connection to a specified SMB2 share. ### `disconnectShare(gracefully:)` Closes the connection to the SMB2 share. The `gracefully` parameter controls whether to attempt a graceful shutdown. ### `echo()` Tests the connectivity to the SMB2 server. ### `listShares(enumerateHidden:)` Enumerates all available shares on the SMB2 server. The `enumerateHidden` parameter can be used to include hidden shares. ``` -------------------------------- ### Connect to an SMB Share (Completion Handler) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Connects to a specified SMB share using a completion handler. Optionally enables SMB3 encryption. Handles connection failures and attempts reconnection if necessary. ```swift open func connectShare( name: String, encrypted: Bool = false, completionHandler: SimpleCompletionHandler ) ``` ```swift manager.connectShare(name: "Documents") { error in if let error = error { print("Connection failed: \(error)") } else { print("Connected successfully") } } ``` -------------------------------- ### createDirectory(atPath:completionHandler:) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/INDEX.md Create a new directory at the specified path. ```APIDOC ## createDirectory(atPath:completionHandler:) ### Description Create a new directory at the specified path. ### Method [Method details not specified in source] ### Endpoint [Endpoint details not specified in source] ### Parameters #### Path Parameters - **atPath** (string) - Required - The path where the directory should be created. #### Query Parameters [No query parameters specified] #### Request Body [No request body specified] ### Request Example [No request example specified] ### Response #### Success Response [Success response details not specified in source] #### Response Example [No response example specified] ``` -------------------------------- ### Build and Test AMSMB2 Swift Project Source: https://github.com/amosavian/amsmb2/blob/master/CLAUDE.md Commands for building the Swift project, running all tests, filtering specific tests, and performing Linux testing via Docker. ```bash swift build ``` ```bash swift test ``` ```bash swift test --filter SMB2ManagerTests/testName ``` ```bash make linuxtest # Uses local volume mount ``` ```bash make cleanlinuxtest # Clean Docker build ``` -------------------------------- ### uploadItem(at:toPath:progress:completionHandler:) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/INDEX.md Upload a local file to a specified path on the SMB server. Supports progress reporting. ```APIDOC ## uploadItem(at:toPath:progress:completionHandler:) ### Description Upload a local file to a specified path on the SMB server. Supports progress reporting. ### Method [Method details not specified in source] ### Endpoint [Endpoint details not specified in source] ### Parameters #### Path Parameters - **at** (URL) - Required - The URL of the local file to upload. - **toPath** (string) - Required - The destination path on the SMB server. - **progress** (Progress) - Optional - A progress object to report upload progress. #### Query Parameters [No query parameters specified] #### Request Body [No request body specified] ### Request Example [No request example specified] ### Response #### Success Response [Success response details not specified in source] #### Response Example [No response example specified] ``` -------------------------------- ### Populating File Attributes from smb2_stat_64 Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Demonstrates how to populate URLResourceKey attributes from an smb2_stat_64 structure. ```swift let stat = try client.stat(path) if stat.isDirectory { print("Is directory") } var attrs: [URLResourceKey: Any] = [: ] stat.populateResourceValue(&attrs) ``` -------------------------------- ### Directory Methods Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/README.md Methods for managing directories on the SMB2 share, including listing contents, creating, and deleting directories. ```APIDOC ## Directory Methods ### `contentsOfDirectory(atPath:recursive:)` Lists the contents of a directory at the specified path. The `recursive` parameter can be used to list contents of subdirectories as well. ### `createDirectory(atPath:)` Creates a new directory at the specified path. ### `removeDirectory(atPath:recursive:)` Deletes a directory at the specified path. The `recursive` parameter allows for the deletion of non-empty directories. ``` -------------------------------- ### Create Directory Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Creates a new directory at the specified path. The completion handler is called upon completion. This method may throw a POSIXError if the parent directory does not exist or if permissions are denied. ```swift open func createDirectory(atPath path: String, completionHandler: SimpleCompletionHandler) ``` ```swift open func createDirectory(atPath path: String) async throws ``` -------------------------------- ### connectShare(name:encrypted:completionHandler:) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/INDEX.md Connect to a specified SMB share. Allows for encrypted connections. ```APIDOC ## connectShare(name:encrypted:completionHandler:) ### Description Connect to a specified SMB share. Allows for encrypted connections. ### Method [Method details not specified in source] ### Endpoint [Endpoint details not specified in source] ### Parameters #### Path Parameters - **name** (string) - Required - The name of the share to connect to. - **encrypted** (bool) - Required - Whether to use an encrypted connection. #### Query Parameters [No query parameters specified] #### Request Body [No request body specified] ### Request Example [No request example specified] ### Response #### Success Response [Success response details not specified in source] #### Response Example [No response example specified] ``` -------------------------------- ### Monitor File Changes in a Directory Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/00-START-HERE.txt Sets up a monitor to receive notifications about changes (creation, deletion, modification) within a specified directory on the SMB share. ```swift import AMSMB2 // Assuming manager is already initialized and connected let manager = SMB2Manager( host: "your_server_address", port: 445, username: "your_username", password: "your_password", domain: "your_domain" ) Task { do { try await manager.connect() let directoryToMonitor = "/path/to/monitor" let monitor = try await manager.monitorDirectory(directoryToMonitor) print("Monitoring directory: \(directoryToMonitor)") for try await change in monitor { print("File change detected: \(change.action) on \(change.name)") // Handle different SMB2FileChangeAction types } } catch { print("Failed to monitor directory: \(error)") } } ``` -------------------------------- ### downloadItem(atPath:to:progress:completionHandler:) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/INDEX.md Download a file from a specified path on the SMB server to a local destination. Supports progress reporting. ```APIDOC ## downloadItem(atPath:to:progress:completionHandler:) ### Description Download a file from a specified path on the SMB server to a local destination. Supports progress reporting. ### Method [Method details not specified in source] ### Endpoint [Endpoint details not specified in source] ### Parameters #### Path Parameters - **atPath** (string) - Required - The path of the file on the SMB server to download. - **to** (URL) - Required - The local destination URL for the downloaded file. - **progress** (Progress) - Optional - A progress object to report download progress. #### Query Parameters [No query parameters specified] #### Request Body [No request body specified] ### Request Example [No request example specified] ### Response #### Success Response [Success response details not specified in source] #### Response Example [No response example specified] ``` -------------------------------- ### listShares(enumerateHidden:completionHandler:) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/INDEX.md List all available shares on the connected SMB server. Can include hidden shares. ```APIDOC ## listShares(enumerateHidden:completionHandler:) ### Description List all available shares on the connected SMB server. Can include hidden shares. ### Method [Method details not specified in source] ### Endpoint [Endpoint details not specified in source] ### Parameters #### Path Parameters - **enumerateHidden** (bool) - Required - Whether to enumerate hidden shares. #### Query Parameters [No query parameters specified] #### Request Body [No request body specified] ### Request Example [No request example specified] ### Response #### Success Response [Success response details not specified in source] #### Response Example [No response example specified] ``` -------------------------------- ### Handle Connection Errors with Retry Logic Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/00-START-HERE.txt Illustrates how to implement retry logic for connection attempts to handle transient network issues or server unavailability. ```swift import AMSMB2 func connectWithRetry(manager: SMB2Manager, maxRetries: Int = 3) async throws { for attempt in 1...maxRetries { do { try await manager.connect() print("Connected on attempt \(attempt).") return } catch { print("Attempt \(attempt) failed: \(error)") if attempt == maxRetries { throw error // Re-throw the last error if all retries fail } try await Task.sleep(nanoseconds: UInt64(attempt) * 1_000_000_000) // Wait 1 second, then 2, then 3... } } } let manager = SMB2Manager( host: "your_server_address", port: 445, username: "your_username", password: "your_password", domain: "your_domain" ) Task { do { try await connectWithRetry(manager: manager) } catch { print("Failed to connect after multiple retries: \(error)") } } ``` -------------------------------- ### File Browser Class Implementation Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md A class that implements a file browser using SMB2Manager. It allows connecting to shares, listing directory contents, and navigating the file system. ```swift class SMBFileBrowser { let manager: SMB2Manager var currentPath = "/" init(url: URL, credential: URLCredential) { self.manager = SMB2Manager(url: url, credential: credential)! } func connect(share: String) async throws { try await manager.connectShare(name: share) } func listCurrent() async throws -> [String] { let entries = try await manager.contentsOfDirectory(atPath: currentPath) return entries.compactMap { $0.name } } func enterDirectory(_ name: String) { currentPath.append("/\(name)") } func goUp() { if currentPath != "/" { currentPath = currentPath.deletingLastPathComponent } } } ``` -------------------------------- ### Create Symbolic Link Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Create a symbolic link at a specified path that points to a destination path. This allows for creating shortcuts to files or directories. ```swift try await manager.createSymbolicLink( atPath: "/shortcuts/my_link", withDestinationPath: "/documents/important.txt" ) ``` -------------------------------- ### Monitor File Item for Changes Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Sets up monitoring for file or directory changes. Specify the path, the types of changes to watch for, and a completion handler to receive notifications. ```swift try await manager.monitorItem( atPath: "/watched", for: [.contentModify, .fileName, .recursive] ) { result in switch result { case .success(let changes): for change in changes { print("\(change.fileName): \(change.action)") } case .failure(let error): print("Watch failed: \(error)") } } ``` -------------------------------- ### createDirectory Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Creates a new directory at the specified path. This operation may fail if the parent directory does not exist or due to permission issues. ```APIDOC ## createDirectory ### Description Creates a new directory at the specified path. ### Method `open func createDirectory(atPath path: String, completionHandler: SimpleCompletionHandler)` ### Parameters #### Path Parameters - **atPath** (String) - Required - Path for the new directory #### Closure Parameters - **completionHandler** (SimpleCompletionHandler) - Optional - Closure called on completion. ### Throws (via handler) POSIXError if directory creation fails (e.g., parent doesn't exist, permission denied). ### Async Version `open func createDirectory(atPath path: String) async throws` ``` -------------------------------- ### Build and Test AMSMB2 Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/README.md Commands to build the project, run its tests, and execute tests on Linux using Docker. ```bash # Build swift build ``` ```bash # Run tests swift test ``` ```bash # Linux (Docker) make linuxtest ``` -------------------------------- ### Manual Stream Management for File Reading Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Demonstrates manual management of an InputStream to read data in chunks from a local file. Ensures the stream is properly opened and closed. ```swift let stream = InputStream(fileAtPath: "/tmp/local.bin")! try stream.withOpenStream { while true { let chunk = try stream.readData(maxLength: 65536) if chunk.isEmpty { break } // Process chunk } } ``` -------------------------------- ### Create URLCredential Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/configuration.md Demonstrates how to create a URLCredential object for authentication, specifying user, password, and persistence. ```swift let credential = URLCredential( user: "username", password: "password", persistence: URLCredential.Persistence.forSession ) ``` -------------------------------- ### Disconnect from SMB Share (Async/Await) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Disconnects from the currently connected SMB share using async/await syntax. Set `gracefully` to true to wait for all queued operations to complete before disconnecting. Throws an error if disconnection fails. ```swift open func disconnectShare(gracefully: Bool = false) async throws ``` -------------------------------- ### Handle File Not Found Error Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Catch and handle the specific POSIX error for 'No such file or directory' when attempting to operate on a non-existent file. ```swift do { try await manager.removeFile(atPath: "/missing.txt") } catch let error as POSIXError where error.code == .noSuchFileOrDirectory { print("File not found") } ``` -------------------------------- ### Upload/Download Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/README.md Methods for uploading local files to the SMB2 share and downloading files from the share to the local system. ```APIDOC ## Upload/Download ### `uploadItem(at:toPath:progress:)` Uploads a local file to the specified path on the SMB2 share, with optional progress reporting. ### `downloadItem(atPath:to:progress:)` Downloads a file from the SMB2 share at the specified path to a local destination, with optional progress reporting. ``` -------------------------------- ### Define SMB2FileChangeType OptionSet Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/types.md Defines the bitmask-style option set for specifying file system changes to monitor. Use this to configure the filter for `monitorItem()`. ```swift public struct SMB2FileChangeType: OptionSet, Hashable, Sendable, CustomStringConvertible { public var rawValue: UInt32 public init(rawValue: UInt32) } ``` -------------------------------- ### Platform-Specific File Descriptor Open Options Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Defines platform-specific open options for file descriptors, including 'sync' and conditional 'symlink'. ```swift extension FileDescriptor.OpenOptions { static var sync: FileDescriptor.OpenOptions { get } #if !canImport(Darwin) static var symlink: FileDescriptor.OpenOptions { get } #endif } ``` -------------------------------- ### InputStream and OutputStream Extensions for Data Handling Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Provides extensions for InputStream and OutputStream to simplify reading data in chunks and writing data, respectively. Also includes a utility to manage stream opening and closing. ```swift extension InputStream { func readData(maxLength length: Int) throws -> Data } extension OutputStream { func write(_ data: DataType) throws -> Int } extension Stream { func withOpenStream(_ handler: () throws -> Void) rethrows func withOpenStream(_ handler: () async throws -> Void) async rethrows } ``` -------------------------------- ### List Available Shares Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md List all available network shares, optionally including hidden administrative shares. Returns a dictionary of share names and their descriptions. ```swift let shares = try await manager.listShares(enumerateHidden: false) for (name, comment) in shares { print("Share: \(name)") if !comment.isEmpty { print(" Description: \(comment)") } } ``` -------------------------------- ### Connect with Retry Logic Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Connect to an SMB share with a specified number of retries and a delay between attempts. Throws an error if all retries fail. ```swift func connectWithRetry(share: String, maxRetries: Int = 3) async throws { for attempt in 1...maxRetries { do { try await manager.connectShare(name: share) return } catch { if attempt == maxRetries { throw error } print("Attempt \(attempt) failed, retrying...") try await Task.sleep(nanoseconds: 2_000_000_000) // 2 seconds } } } try await connectWithRetry(share: "Documents") ``` -------------------------------- ### Handle Async POSIXError Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/errors.md Demonstrates the standard pattern for catching and handling POSIXError exceptions thrown by async methods. ```swift do { try await manager.connectShare(name: "Documents") } catch let error as POSIXError { print("Error code: \(error.code)") print("Description: \(error.localizedDescription)") } ``` -------------------------------- ### Copy Directory Recursively Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/examples.md Copy an entire directory, including its contents, to a new location. Progress is reported as a percentage. ```swift try await manager.copyItem( atPath: "/source_folder", toPath: "/destination_folder", recursive: true, progress: { bytes, total in let percent = Int(bytes * 100 / total) print("Copy progress: \(percent)%") return true } ) ``` -------------------------------- ### Download Item (Async) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Asynchronously downloads a file from a specified server path to a local URL. This method overwrites existing files at the destination URL. ```swift open func downloadItem(atPath path: String, to url: URL, progress: ReadProgressHandler ) async throws ``` -------------------------------- ### File Attribute Helpers using String Extensions Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/file-operations.md Provides extensions for Swift strings to easily extract path components and manage file paths. ```swift extension String { var pathComponents: (directory: String, file: String) { get } var trimmedPath: String { get } func appendingPath(_ component: String, isDirectory: Bool) -> String } ``` -------------------------------- ### Download Item (Completion Handler) Source: https://github.com/amosavian/amsmb2/blob/master/_autodocs/smb2manager.md Downloads a file from a specified server path to a local URL using completion handlers for progress and completion. This method overwrites existing files at the destination URL. ```swift open func downloadItem( atPath path: String, to url: URL, progress: ReadProgressHandler, completionHandler: SimpleCompletionHandler ) ``` ```swift let destination = URL(fileURLWithPath: "/tmp/download.pdf") manager.downloadItem( atPath: "/documents/report.pdf", to: destination, progress: { bytes, total in print("Downloaded \(bytes)/\(total) bytes") return true } ) { if let error = error { print("Download failed: \(error)") } } ```