Skip to content

Commit

Permalink
Use new HTTPClient class for downloading all data in notifications
Browse files Browse the repository at this point in the history
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
  • Loading branch information
digitaldan committed Jul 7, 2024
1 parent 8b3eca3 commit 5227aea
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 37 deletions.
16 changes: 7 additions & 9 deletions NotificationService/NotificationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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])
Expand All @@ -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)
}
}

Expand All @@ -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)
}
}
102 changes: 74 additions & 28 deletions OpenHABCore/Sources/OpenHABCore/Util/HTTPClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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) {
Expand All @@ -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")
Expand Down Expand Up @@ -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)
}
}
3 changes: 3 additions & 0 deletions OpenHABCore/Sources/OpenHABCore/Util/OSLogExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

0 comments on commit 5227aea

Please sign in to comment.