How to get Printer URL from NetService

877 Views Asked by At

I'm trying to fetch all the local printer by using this way;

let serviceBrowser = NetServiceBrowser()
serviceBrowser.delegate = self
serviceBrowser.schedule(in: .current, forMode: .defaultRunLoopMode)
serviceBrowser.searchForServices(ofType: "_ipp._tcp.", inDomain:"local.")

It finds all the printers which are connected but I'd like to know the urls of them for to create UIPrinter with URL like UIPrinter(url: URL("urlstring"))

func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) {
    print(service)
    // output: <NSNetService 0x1c0228960> local. _ipp._tcp. RICOH imagio MP C3302 [002673499B5F] -1
}

I don't know if using this way is a solution for to find Local/Air Printers.

Note: UIPrinterPickerController is not an option for resolution.

1

There are 1 best solutions below

2
On

You'll need to resolve the net services after you find them. Then you can do something like this to build a UIPrinter to send to AirPrint.

let printerPath = "\(uri)://\(host):\(port)/" + (service.textRecordField(field: "rp") ?? "")
guard let printerUrl = URL(string: printerPath)
        else { return nil }
let printer = UIPrinter(url: printerUrl)
  • uri: "ipp", "ipps", "lpd", "socket". You can figure out which to use by checking the type field from the NetService object.
  • host: host name field from the NetService object
  • port: port name field from the NetService object
  • rp: The queue name (path) of the printer. You get this by decoding the 'rp' field from the NetService object's text record dictionary.

Here's my extension for getting txtRecord data from a NetService object:

 extension NetService {
     func textRecordField(field: String) -> String?
     {
         guard
             let data = self.txtRecordData(),
             let field = NetService.dictionary(fromTXTRecord: data)[field]
             else { return nil }

         return String(data: field, encoding: String.Encoding.utf8)
     } 
}