diff --git a/NotificationService/NotificationService.swift b/NotificationService/NotificationService.swift index 8b609930..28aafcd2 100644 --- a/NotificationService/NotificationService.swift +++ b/NotificationService/NotificationService.swift @@ -86,7 +86,7 @@ class NotificationService: UNNotificationServiceExtension { } else { downloadAndAttachMedia } - + os_log("handleNotification downloading %{PUBLIC}@", log: .default, type: .info, attachmentURLString) downloadHandler(attachmentURL) { attachment in if let attachment { os_log("handleNotification attaching %{PUBLIC}@", log: .default, type: .info, attachmentURLString) @@ -152,12 +152,14 @@ class NotificationService: UNNotificationServiceExtension { func downloadAndAttachItemImage(attachmentURL: URL, completion: @escaping (UNNotificationAttachment?) -> Void) { guard let scheme = attachmentURL.scheme else { os_log("Could not find scheme %{PUBLIC}@", log: .default, type: .info) + completion(nil) return } let itemName = String(attachmentURL.absoluteString.dropFirst(scheme.count + 1)) - OpenHABItemCache.instance.getItem(name: itemName) { item in + let client = HTTPClient(username: Preferences.username, password: Preferences.username) + client.getItem(baseURLs: [Preferences.localUrl, Preferences.remoteUrl], itemName: itemName) { item, error in guard let item else { os_log("Could not find item %{PUBLIC}@", log: .default, type: .info, itemName) completion(nil) @@ -168,11 +170,9 @@ class NotificationService: UNNotificationServiceExtension { // Extract MIME type and base64 string let pattern = "^data:(.*?);base64,(.*)$" let regex = try NSRegularExpression(pattern: pattern, options: []) - if let match = regex.firstMatch(in: state, options: [], range: NSRange(location: 0, length: state.utf16.count)) { let mimeTypeRange = Range(match.range(at: 1), in: state) let base64Range = Range(match.range(at: 2), in: state) - if let mimeTypeRange, let base64Range { let mimeType = String(state[mimeTypeRange]) let base64String = String(state[base64Range]) @@ -196,10 +196,8 @@ class NotificationService: UNNotificationServiceExtension { } catch { os_log("Failed to parse data: %{PUBLIC}@", log: .default, type: .error, error.localizedDescription) } - completion(nil) - } else { - completion(nil) } + completion(nil) } } @@ -222,11 +220,11 @@ class NotificationService: UNNotificationServiceExtension { os_log("Unrecognized MIME type or file extension", log: .default, type: .error) attachment = nil } - completion(attachment) + return } catch { os_log("Failed to create UNNotificationAttachment: %{PUBLIC}@", log: .default, type: .error, error.localizedDescription) - completion(nil) } + completion(nil) } } diff --git a/OpenHABCore/Sources/OpenHABCore/Util/HTTPClient.swift b/OpenHABCore/Sources/OpenHABCore/Util/HTTPClient.swift index ab6fb724..49e185cc 100644 --- a/OpenHABCore/Sources/OpenHABCore/Util/HTTPClient.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/HTTPClient.swift @@ -12,12 +12,6 @@ import Foundation import os.log -// Define a custom log object -extension OSLog { - private static var subsystem = Bundle.main.bundleIdentifier! - static let networking = OSLog(subsystem: subsystem, category: "networking") -} - public class HTTPClient: NSObject, URLSessionDelegate { // MARK: - Properties @@ -41,14 +35,6 @@ public class HTTPClient: NSObject, URLSessionDelegate { session = URLSession(configuration: config, delegate: self, delegateQueue: nil) } - // MARK: - Basic Authentication - - private func basicAuthHeader() -> String { - let authString = "\(username):\(password)" - let authData = authString.data(using: .utf8)! - return "Basic \(authData.base64EncodedString())" - } - // MARK: - URLSessionDelegate for Client Certificates public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { @@ -74,8 +60,81 @@ public class HTTPClient: NSObject, URLSessionDelegate { } } + public func doGet(baseURLs: [String], path: String, completion: @escaping (Data?, URLResponse?, Error?) -> Void) { + doRequest(baseURLs: baseURLs, path: path, method: "GET", completion: completion) + } + + public func doPost(baseURLs: [String], path: String, body: String, completion: @escaping (Data?, URLResponse?, Error?) -> Void) { + doRequest(baseURLs: baseURLs, path: path, method: "POST", body: body, completion: completion) + } + + public func baseURLs(baseURLs: [String], path: String, body: String, completion: @escaping (Data?, URLResponse?, Error?) -> Void) { + doRequest(baseURLs: baseURLs, path: path, method: "PUT", body: body, completion: completion) + } + + public func getItems(baseURLs: [String], completion: @escaping ([OpenHABItem]?, Error?) -> Void) { + doGet(baseURLs: baseURLs, path: "/rest/items") { data, _, error in + if let error { + completion(nil, error) + } else { + do { + var items = [OpenHABItem]() + if let data { + os_log("getItemsInternal Data: %{public}@", log: .networking, type: .debug, String(data: data, encoding: .utf8) ?? "") + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .formatted(DateFormatter.iso8601Full) + + // if we are hitting an item, then its OpenHABItem.CodingData] not [OpenHABItem.CodingData] + let codingDatas = try data.decoded(as: [OpenHABItem.CodingData].self, using: decoder) + for codingDatum in codingDatas where codingDatum.openHABItem.type != OpenHABItem.ItemType.group { + items.append(codingDatum.openHABItem) + } + os_log("Loaded items to cache: %{PUBLIC}d", log: .networking, type: .info, items.count) + } + completion(items, nil) + } catch { + os_log("getItemsInternal ERROR: %{PUBLIC}@", log: .networking, type: .info, String(describing: error)) + completion(nil, error) + } + } + } + } + + public func getItem(baseURLs: [String], itemName: String, completion: @escaping (OpenHABItem?, Error?) -> Void) { + os_log("getItem from URsL %{public}@ and item %{public}@", log: .networking, type: .info, baseURLs, itemName) + doGet(baseURLs: baseURLs, path: "/rest/items/\(itemName)") { data, _, error in + if let error { + completion(nil, error) + } else { + do { + if let data { + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .formatted(DateFormatter.iso8601Full) + let item = try data.decoded(as: OpenHABItem.CodingData.self, using: decoder) + completion(item.openHABItem, nil) + } else { + completion(nil, NSError(domain: "HTTPClient", code: -1, userInfo: [NSLocalizedDescriptionKey: "No data for item"])) + } + } catch { + os_log("getItemsInternal ERROR: %{PUBLIC}@", log: .networking, type: .info, String(describing: error)) + completion(nil, error) + } + } + } + } + + // MARK: - Private Methods + + // MARK: - Basic Authentication + + private func basicAuthHeader() -> String { + let authString = "\(username):\(password)" + let authData = authString.data(using: .utf8)! + return "Basic \(authData.base64EncodedString())" + } + // Perform an HTTP request - public func performRequest(request: URLRequest, completion: @escaping (Data?, URLResponse?, Error?) -> Void) { + private func performRequest(request: URLRequest, completion: @escaping (Data?, URLResponse?, Error?) -> Void) { var request = request if alwaysSendBasicAuth { request.setValue(basicAuthHeader(), forHTTPHeaderField: "Authorization") @@ -131,19 +190,6 @@ public class HTTPClient: NSObject, URLSessionDelegate { } } } - sendRequest() } - - public func doGet(baseURLs: [String], path: String, completion: @escaping (Data?, URLResponse?, Error?) -> Void) { - doRequest(baseURLs: baseURLs, path: path, method: "GET", completion: completion) - } - - public func doPost(baseURLs: [String], path: String, body: String, completion: @escaping (Data?, URLResponse?, Error?) -> Void) { - doRequest(baseURLs: baseURLs, path: path, method: "POST", body: body, completion: completion) - } - - public func baseURLs(baseURLs: [String], path: String, body: String, completion: @escaping (Data?, URLResponse?, Error?) -> Void) { - doRequest(baseURLs: baseURLs, path: path, method: "PUT", body: body, completion: completion) - } } diff --git a/OpenHABCore/Sources/OpenHABCore/Util/OSLogExtension.swift b/OpenHABCore/Sources/OpenHABCore/Util/OSLogExtension.swift index 11c171d4..9e85df96 100644 --- a/OpenHABCore/Sources/OpenHABCore/Util/OSLogExtension.swift +++ b/OpenHABCore/Sources/OpenHABCore/Util/OSLogExtension.swift @@ -44,4 +44,7 @@ public extension OSLog { /// Logs WkWebView events static let wkwebview = OSLog(subsystem: subsystem, category: "wkwebview") + + /// Log Networking events + static let networking = OSLog(subsystem: subsystem, category: "networking") }