1

What I was trying to do is to print a file to a shared CUPS printer on the network without user to select from the UIPrinterPickerController or UIPrintInteractionController.

Using UIPrinterPickerController to select one from the list and then print works fine. But the problem is our network has way too many printers, and the user not always select the correct printer, so I need to set a printer from the app instead of letting user to select.

From Apple's dev document UIPrinter init(url:), I should be able to create a UIPrinter instance from a URL, and use contactPrinter(_:) to fetch all necessary fields of the printer.

Printer setup

The printer is connected and shared on a CUPS printer server, with static ip, and the printer shows, and prints fine from UIPrinterPickerController. And I logged url from UIPrinterPickerController

ipps://desktop.local.:631/printers/label_printer

Code I'm having issue

func testPrint(_ printingData: Data) {
        guard let url = URL(string: printerURLString) else {
            print("invalid url")
            return
        }
        let printer = UIPrinter(url: url)
        printer.contactPrinter { available in
            print(available, "from contactPrinter") // This line prints false every time
        }

        UIPrintInteractionController.shared.printingItem = printingData
        UIPrintInteractionController.shared.print(to: printer)
    }

printerURLString I tried

  • ipps://desktop.local.:631/printers/label_printer
  • ipps://10.1.0.2:631/printers/label_printer

when I try to contactPrinter, the completionHandler always retrieved false, and of course it won't print anything.

Apple Code-Level Support

I tried to ask help from Apple, but they rejected the ticket without giving any reason nor any response. Not sure what's going on

Other thoughts

I have searched all related questions on stack overflow, but not really finding anything works, this post from a few years ago mentioned

Shared printers on Linux will not work with this contactPrinter method. It requires that the printer attributes are returned successfully. We often still send a print job even if the other parts fail.

For these methods to work properly, the server has to be a licensed and correctly implemented AirPrint server. CUPS running somewhere isn’t enough.

This doesn't make sense when UIPrinterPickerController can select the printer and print, but not create from the URL.

I tried to create a new printer instance from the UIPrinterPickerController, using the selected printer url, and that still won't work

            picker.present(animated: true) { picker, _, _ in
                if let printer = picker.selectedPrinter {
                    print(printer.url.absoluteString)
//                    selectedPrinter = picker.selectedPrinter

                    let newPrinter = UIPrinter(url: printer.url)
                    newPrinter.contactPrinter { success in
                        print("new printer:\(success)")
                    }
                    selectedPrinter = newPrinter
                }

                context.coordinator.activePicker = nil
                self.showPrinterPicker = false
            }
Qiquan Lu
  • 615
  • 1
  • 5
  • 10

0 Answers0