[Service] New UI
This commit is contained in:
@@ -118,6 +118,7 @@ public final class PortalClient: @unchecked Sendable {
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "POST"
|
||||
request.setValue("application/json", forHTTPHeaderField: "Accept")
|
||||
PortalClientIdentity.apply(to: &request)
|
||||
|
||||
let data: Data
|
||||
let response: URLResponse
|
||||
@@ -190,6 +191,7 @@ public final class PortalClient: @unchecked Sendable {
|
||||
request.httpMethod = "POST"
|
||||
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
request.setValue("application/json", forHTTPHeaderField: "Accept")
|
||||
PortalClientIdentity.apply(to: &request)
|
||||
|
||||
let payload: [String: String] = [
|
||||
"pairingId": session.pairingId,
|
||||
@@ -447,6 +449,7 @@ public final class PortalClient: @unchecked Sendable {
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "POST"
|
||||
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
PortalClientIdentity.apply(to: &request)
|
||||
|
||||
let payload: [String: String] = [
|
||||
"pairingId": session.pairingId,
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// PortalClientIdentity.swift
|
||||
// PortalKit
|
||||
//
|
||||
// Identity headers sent on pairing (and available for other Portal requests).
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Darwin
|
||||
|
||||
/// Values for `X-Client-Name`, `X-Client-Version`, `X-Device-Model`, and `User-Agent`.
|
||||
public enum PortalClientIdentity {
|
||||
public static var clientName: String {
|
||||
if let name = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String,
|
||||
!name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
return name
|
||||
}
|
||||
if let name = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String,
|
||||
!name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
return name
|
||||
}
|
||||
return "PortalCam"
|
||||
}
|
||||
|
||||
public static var clientVersion: String {
|
||||
if let v = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
|
||||
!v.isEmpty {
|
||||
return v
|
||||
}
|
||||
return PortalKitVersion.version
|
||||
}
|
||||
|
||||
/// Hardware model identifier, e.g. `MacBookPro18,1`.
|
||||
public static var deviceModel: String {
|
||||
hwModel() ?? "Mac"
|
||||
}
|
||||
|
||||
public static var userAgent: String {
|
||||
"PortalCam/\(clientVersion) (macOS; \(deviceModel))"
|
||||
}
|
||||
|
||||
/// Apply identity headers used by Portal TV pairing.
|
||||
public static func apply(to request: inout URLRequest) {
|
||||
request.setValue(clientName, forHTTPHeaderField: "X-Client-Name")
|
||||
request.setValue(clientVersion, forHTTPHeaderField: "X-Client-Version")
|
||||
request.setValue(deviceModel, forHTTPHeaderField: "X-Device-Model")
|
||||
request.setValue(userAgent, forHTTPHeaderField: "User-Agent")
|
||||
}
|
||||
|
||||
private static func hwModel() -> String? {
|
||||
var size = 0
|
||||
guard sysctlbyname("hw.model", nil, &size, nil, 0) == 0, size > 0 else { return nil }
|
||||
var buf = [CChar](repeating: 0, count: size)
|
||||
guard sysctlbyname("hw.model", &buf, &size, nil, 0) == 0 else { return nil }
|
||||
let s = String(cString: buf).trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return s.isEmpty ? nil : s
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user