This document provides a possible (unofficial) Swift interpretation of Apple's Objective-C Technical Note TN2248 Using Cocoa and Core Printing Together (revision 2009.05.27).
| Modifying Print Settings | Programmatic Paper Selection | Resources |
Modifying Print Settings ▴
How to modify print settings information that is stored in an NSPrintInfo object. Error handling is not shown.
- obtain print settings from a printInfo object
- change the print settings
- synchronize by notifying Cocoa that the settings have been changed
Listing 1 Modify Print Settings.
// Obtain PrintInfo to be modified.
// NSPrintInfo init(dictionary: [NSPrintInfo.AttributeKey : Any])
let printInfo: NSPrintInfo = NSPrintInfo()
// NOTE: Use `Swift.print()` inside NSView subclass to not call `NSView.print()`
Swift.print("printInfo=\(printInfo)")
// Get PMPrintSettings object from printInfo.
let settings: PMPrintSettings = OpaquePointer(printInfo.pmPrintSettings())
// Modify/Set any settings
PMSetCopies(settings, 10, false) // copies to print
PMSetCollate(settings, true) // enable collation
// Notify Cocoa that the print settings have changed.
printInfo.updateFromPMPrintSettings()
Programmatic Paper Selection ▴
This code snippet illustrates how to replace one of the low level Core Printing objects stored in an NSPrintInfo with a custom object you obtain or create.
- Obtain a PMPaper object from those available for the currently selected printer. To do this:
- Obtain the currently selected printer.
- Get an array of the pre-defined papers for that printer.
- Choose a paper from that list that meets your criteria.
- Make that paper the current paper for your Cocoa print job. To do this:
- Create a PMPageFormat from the chosen paper.
- Copy that page format into the page format stored in the NSPrintInfo you want to modify.
- Tell Cocoa you have made a change to the PageFormat in the NSPrintInfo.
Listing 2 Replacing the PageFormat object.
public static func replacePageFormat() -> Int {
// Obtain the printInfo to be modified.
let printInfo = NSPrintInfo()
// Get the PMPrintSession from the printInfo.
// Definition: typealias PMPrintSession = OpaquePointer
let printSession = PMPrintSession(printInfo.pmPrintSession())
/// Get the current printer from the session.
var currentPrinter = unsafeBitCast(0, to: PMPrinter.self)
PMSessionGetCurrentPrinter(printSession, ¤tPrinter)
// Get the array of pre-defined PMPapers this printer supports.
// PMPrinterGetPaperList(PMPrinter, UnsafeMutablePointer<Unmanaged<CFArray>?>)
var paperListUnmanaged: Unmanaged<CFArray>?
let status: OSStatus = PMPrinterGetPaperList(currentPrinter, &paperListUnmanaged)
if status != noErr { return Int(status) } // place error handling here
guard let paperList = paperListUnmanaged?.takeUnretainedValue() else {
fatalError()
}
// Pick a paper from the list, using the appropriate criteria for your application.
// This code simply chooses the first paper in the list. More likely you would use
// information from your data (perhaps obtained from a database) to determine
// which paper in the paperList best meets the current need.
let chosenPaper = PMPaper(CFArrayGetValueAtIndex(paperList, 0))!
// --- EXTRA: shows an approach to handle <Unmanaged<CFString>? ---
//PMPaperGetPrinterID(PMPaper, UnsafeMutablePointer<Unmanaged<CFString>?>)
for idx in 0..<CFArrayGetCount(paperList) {
let paper = PMPaper(CFArrayGetValueAtIndex(paperList, idx))!
_ = PrintUtil.getPMPaperInfo(pmPaper: paper)
var width = 0.0, height = 0.0
PMPaperGetWidth(paper, &width)
PMPaperGetHeight(paper, &height)
print("width=\(width), height=\(height)")
}
// --- ------------------------------------------------------- ---
// Create a PMPageFormat from that paper.
// func PMCreatePageFormatWithPMPaper(UnsafeMutablePointer<PMPageFormat>, PMPaper) -> OSStatus
var chosenPageFormat: PMPageFormat = unsafeBitCast(0, to: PMPageFormat.self)
PMCreatePageFormatWithPMPaper(&chosenPageFormat, chosenPaper)
// Get the PMPageFormat contained in the printInfo.
let originalFormat = PMPageFormat(printInfo.pmPageFormat())
// Copy over the original format with the new format you want to use.
//PMCopyPageFormat(formatSrc: PMPageFormat, formatDest: PMPageFormat)
PMCopyPageFormat(chosenPageFormat, originalFormat)
// Notify Cocoa that page format has changed.
printInfo.updateFromPMPageFormat()
// Release the PMPageFormat this code created.
// func PMRelease(_ object: PMObject?) -> OSStatus
return Int( PMRelease(PMObject(chosenPageFormat)) )
}
Resources ▴
Apple/ApplicationServices: Core Printing ⇗
Apple/TechnicalNote: TN2248 Using Cocoa and Core Printing Together ⇗ 2009-05-27