Use the Terminal app to run the install script on the Mac with the printer to be shared over airprint. It obviously has to be on the same local network as the iOS client. First install a necessary dependency used for Bonjour browsing
gem install dnssd
Then to test the feature run
./airprintfix.rb -t
The existing shared printers should now be available to iOS clients. You will need to use CTRL-C
to stop the server. To install permanently run:
sudo airprintfix.rb -i
The script will find existing shared printers and make them available over airprint. Make sure printer sharing has been enabled in Printer Preferences.
The script has a -h option to get more information
./airprintfix.rb -h
The rest of this document explains how it works if you want to customise the install.
- Airprint servers use CUPS aka IPP over tcp
- This means you need to enable printer sharing in Prefences.
- They advertise themselves using Apple's Bonjour dynamic DNS
- Normal Apple print sharing uses the type _ipp._tcp
- They appear in the local domain (and also icloud.com if BackToMyMac is supported)
- You can see these services either
- in terminal using the ugly command line utility dns-sd
- A better way is to get the free Bonjour Browser app from the here
- You will see your shared printers under the _ipp._tcp type
- The bold line is the printer name
- the keyword= lines are DNS TXT records advertising capabilities
- txtvers=1 is required and should be the first keyword pair.
- note= is the subtitle shown below the printer name in choose printer dialogues
- qtotal=1 is the number of queues and is required
- rp= is the queue name and is required.
- ty= is the printer type and is optional
- the pdl= keyword list the MIME types supported
- However airprint requires:
- advertising with the _ipp._tcp,_universal subtype
- advertising a pdl list including application/pdf and image/urf
- there must be a URF= keyword though the value does not matter
- Make sure you have printer sharing enabled for your printer
- Run dns-sd or Bonjour Browser to find out the details of your printer and what TXT lines it advertises
- Fire up whatever text editor you prefer (if you use Apple's TextEdit make sure it is in plain text mode in the preferences).
- Paste into it the dns script
- The bits inside double asterisks are unique to your setup's TXT lines and should be changed to agree
- Note each line (except the last) ends in a backspace to continue across multiple lines
- Also spaces inside keyword values have to be protected by a backslash
- The last line should replace the existing pdl
- Save this in Documents as airprint.sh (in plain text format!)
To test it run Terminal.app from Applications/Utilities and type
cd Documents
sh airprint.sh
This will then hang. While it is running the Mac should be acting as an Airprint server. Try to print from some iOS app to verify this. You can use CTRL-C to break the hang and exit to end the terminal session.
To ensure the service runs at all times we need to have it run automatically in the background when the Mac boots.
- Start another new document in your editor and paste in the launch script
- Replace hostname in line 6 of the text with the Mac's actual hostname
- Save this in Documents as local.hostname.airprint.plist replacing hostname with the Mac's actual hostname
- Start another Document and paste in the terminal script. Again swap out the hostname to your actual Mac's hostname.
- Save it as t.sh
- Fire up Terminal.app from Applications/Utilities
- Type in sudo sh t.sh and enter your admin password when prompted
- Try it out from iOS
- Profit!
dns-sd -R "name_to_be advertised" _ipp._tcp.,_universal . 631 \
URF=none txtvers=1 qtotal=1 \
rp=printers/"queue name" \
note="descriptive text" \
priority=0 \
pdl=application/pdf,image/urf
- The text in quotes will need to be edited. Any embedded blanks or newlines outside quotes need to be
protected with backslashes.
- "name to be advertised" is the name you want to give to this print queue
- "queue name" is the name the host computer gives to the queue, see printers page in preferences on the host
- descriptive text is subtitle for the printer. Enter any useful description here.
An example script might be:
dns-sd -R "SamsungLaser@macmini airprint" _ipp._tcp.,_universal . 631 \
URF=none txtvers=1 qtotal=1 \
rp=printers/SamsungLaser \
note="USB connected" \
priority=0 \
pdl=application/pdf,image/urf
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version='1.0'>
<dict>
<key>Label</key>
<string>local.hostname.airprint</string>
<key>ProgramArguments</key>
<array>
<string>/Library/LaunchDaemons/airprint.sh</string>
</array>
<key>LowPriorityIO</key>
<true/>
<key>Nice</key>
<integer>1</integer>
<key>UserName</key>
<string>root</string>
<key>RunAtLoad</key>
<true/>
<key>Keeplive</key>
<true/>
</dict>
</plist>
cd /Library/LaunchDaemons
mv ~/Documents/airprint.sh .
mv ~/Documents/local.hostname.plist .
chmod +x airprint.sh
launchctl load /Library/LaunchDaemons/local.hostname.plist
This annoying command line program only runs as a daemon so you need to use CTRL-C to break out.
To browse all IPP services on a machine
dns-sd -B _ipp._tcp local
Typical output might be
$ dns-sd -B _ipp._tcp local
Browsing for _ipp._tcp.local
DATE: ---Sun 17 Nov 2013---
14:17:42.275 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
14:17:42.275 Add 3 4 local. _ipp._tcp. Samsung Laser macmini
To see more about a particular service you need to know the service name from the last column of the browse display
dns-sd -L "name goes here" _ipp._tcp local
which will show the TXT output for that name
$ dns-sd -L "Samsung ML-1630W Series @ macmini" _ipp._tcp local
Lookup Samsung ML-1630W Series @ macmini._ipp._tcp.local
DATE: ---Sun 17 Nov 2013---
15:31:01.625 ...STARTING...
15:31:02.087 Samsung\032ML-1630W\032Series\032@\032macmini._ipp._tcp.local. can be reached at macmini.local.:631 (interface 4)
txtvers=1 qtotal=1 rp=printers/Samsung_ML_1630W_Series ty=Samsung\ ML-1630W\ Series adminurl=https://macmini.local.:631/printers/Samsung_ML_1630W_Series note=macmini priority=0 product=\(Samsung\ ML-1630W\ Series\) pdl=application/octet-stream,application/pdf,application/postscript,image/jpeg,image/png,image/pwg-raster UUID=c0bd8783-3e06-30da-4657-11000328a59d TLS=1.2 printer-state=3 printer-type=0x9006
Note that this is a network printer on another machine.