diff --git a/Gemini/AppDelegate.swift b/Gemini/AppDelegate.swift index eefd4d5..08c2dbc 100644 --- a/Gemini/AppDelegate.swift +++ b/Gemini/AppDelegate.swift @@ -7,13 +7,16 @@ import Cocoa import SwiftUI +import GeminiProtocol @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { var window: NSWindow! - + var connection: GeminiConnection! + let url = URL(string: "gemini://localhost:1965/overview.gmi")! + func applicationDidFinishLaunching(_ aNotification: Notification) { // Create the SwiftUI view that provides the window contents. let contentView = ContentView() @@ -29,12 +32,38 @@ class AppDelegate: NSObject, NSApplicationDelegate { window.contentView = NSHostingView(rootView: contentView) window.title = "Gemini" window.makeKeyAndOrderFront(nil) + + connection = GeminiConnection(endpoint: .url(url), delegate: self) } func applicationWillTerminate(_ aNotification: Notification) { // Insert code here to tear down your application } + var alreadyReceived = false } +extension AppDelegate: GeminiConnectionDelegate { + func connectionReady(_ connection: GeminiConnection) { + print("!! Ready") + let req = try! GeminiRequest(url: url) + connection.sendRequest(req) + } + + func connection(_ connection: GeminiConnection, receivedData data: Data?, header: GeminiResponseHeader) { + if !alreadyReceived { + alreadyReceived = true + print("!! Status: \(header.status)") + print("!! Meta: '\(header.meta)'") + } + if let data = data { + print(String(data: data, encoding: .utf8)!) + } + } + + func connectionCompleted(_ connection: GeminiConnection) { + print("!! completed") + } +} + diff --git a/Gemini/Gemini.entitlements b/Gemini/Gemini.entitlements index f2ef3ae..625af03 100644 --- a/Gemini/Gemini.entitlements +++ b/Gemini/Gemini.entitlements @@ -2,9 +2,11 @@ - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-only + + com.apple.security.network.client + diff --git a/GeminiProtocol/GeminiConnection.swift b/GeminiProtocol/GeminiConnection.swift index 4e91cda..eae02af 100644 --- a/GeminiProtocol/GeminiConnection.swift +++ b/GeminiProtocol/GeminiConnection.swift @@ -8,19 +8,19 @@ import Foundation import Network -protocol GeminiConnectionDelegate: class { +public protocol GeminiConnectionDelegate: class { func connectionReady(_ connection: GeminiConnection) func connection(_ connection: GeminiConnection, receivedData data: Data?, header: GeminiResponseHeader) func connectionCompleted(_ connection: GeminiConnection) } -class GeminiConnection { +public class GeminiConnection { - weak var delegate: GeminiConnectionDelegate? + public weak var delegate: GeminiConnectionDelegate? private var connection: NWConnection? - init(endpoint: NWEndpoint, delegate: GeminiConnectionDelegate? = nil) { + public init(endpoint: NWEndpoint, delegate: GeminiConnectionDelegate? = nil) { self.connection = NWConnection(to: endpoint, using: .gemini) self.delegate = delegate @@ -49,7 +49,7 @@ class GeminiConnection { var report: NWConnection.PendingDataTransferReport! - func sendRequest(_ request: GeminiRequest) { + public func sendRequest(_ request: GeminiRequest) { guard let connection = connection else { return } let message = NWProtocolFramer.Message(geminiRequest: request) diff --git a/GeminiProtocol/GeminiRequest.swift b/GeminiProtocol/GeminiRequest.swift index 32fc95e..1e74347 100644 --- a/GeminiProtocol/GeminiRequest.swift +++ b/GeminiProtocol/GeminiRequest.swift @@ -7,10 +7,10 @@ import Foundation -struct GeminiRequest { - let url: URL +public struct GeminiRequest { + public let url: URL - init(url: URL) throws { + public init(url: URL) throws { if url.absoluteString.count > 1024 { throw Error.urlTooLong } @@ -24,7 +24,7 @@ struct GeminiRequest { } } -extension GeminiRequest { +public extension GeminiRequest { enum Error: Swift.Error { case urlTooLong } diff --git a/GeminiProtocol/GeminiResponse.swift b/GeminiProtocol/GeminiResponse.swift index 3ac54c6..6d0ca23 100644 --- a/GeminiProtocol/GeminiResponse.swift +++ b/GeminiProtocol/GeminiResponse.swift @@ -8,11 +8,14 @@ import Foundation import UniformTypeIdentifiers -struct GeminiResponse { - let status: StatusCode - let meta: String - let body: Data? +public struct GeminiResponse { + public let status: StatusCode + public let meta: String + public let body: Data? +} + +public extension GeminiResponse { // Helpers var rawMimeType: String? { guard status.isSuccess else { return nil } @@ -53,7 +56,7 @@ struct GeminiResponse { } } -extension GeminiResponse { +public extension GeminiResponse { enum StatusCode: Int { // All statuses and subtypes case input = 10 @@ -89,7 +92,7 @@ extension GeminiResponse { } extension GeminiResponse.StatusCode: CustomStringConvertible { - var description: String { + public var description: String { switch self { case .input: return "input" diff --git a/GeminiProtocol/GeminiResponseHeader.swift b/GeminiProtocol/GeminiResponseHeader.swift index 909244a..38aeb17 100644 --- a/GeminiProtocol/GeminiResponseHeader.swift +++ b/GeminiProtocol/GeminiResponseHeader.swift @@ -7,7 +7,7 @@ import Foundation -struct GeminiResponseHeader { - let status: GeminiResponse.StatusCode - let meta: String +public struct GeminiResponseHeader { + public let status: GeminiResponse.StatusCode + public let meta: String }