CGDataConsumer
解説
CGDataConsumer は、CGContext の出力をカスタムデータストリーム(ファイルやメモリなど)に書き込むための Core Graphics の仕組みです。たとえば、PDF をファイルに保存したり、メモリバッファに直接書き込んだりできます。
CGDataConsumerCreateWithCFDataを除いて、画像やPDFデータ、すべてを書き込むためにデータのコンシューマオブジェクトを使用することができます、Mac OS X10.0またはそれ以降で利用可能です。
アプリケーションをMac OS X10.4以降で実行している場合は、データコンシューマーではなく、CGImageDestinationオブジェクトを使用する必要があります。CGImageDestinationリファレンスを参照してください。
SwiftUI PDFを書き出し
// // ContentView.swift // CGDataConsumer // // Created on 2025/02/24. // import SwiftUI import CoreGraphics import UniformTypeIdentifiers struct ContentView: View { @State private var pdfURL: URL? var body: some View { VStack { Button("PDF を作成") { pdfURL = createPDF() } .padding() if let pdfURL = pdfURL { ShareLink(item: pdfURL, preview: SharePreview("PDF ファイル")) } } } /// PDF を作成し、保存する func createPDF() -> URL? { let fileManager = FileManager.default let tempDir = fileManager.temporaryDirectory let pdfPath = tempDir.appendingPathComponent("output.pdf") guard let consumer = CGDataConsumer(url: pdfPath as CFURL) else { return nil } guard let pdfContext = CGContext(consumer: consumer, mediaBox: nil, nil) else { return nil } pdfContext.beginPDFPage(nil) // 描画内容 let text = "Hello, SwiftUI & CGDataConsumer!" let attributes: [NSAttributedString.Key: Any] = [ .font: CTFontCreateWithName("Helvetica" as CFString, 24, nil), .foregroundColor: CGColor(red: 0, green: 0, blue: 0, alpha: 1) ] let attributedString = NSAttributedString(string: text, attributes: attributes) let line = CTLineCreateWithAttributedString(attributedString) pdfContext.textPosition = CGPoint(x: 100, y: 700) CTLineDraw(line, pdfContext) // 長方形の描画 pdfContext.setFillColor(CGColor(red: 0, green: 0, blue: 1, alpha: 1)) pdfContext.fill(CGRect(x: 50, y: 600, width: 200, height: 100)) pdfContext.endPDFPage() pdfContext.closePDF() return pdfPath } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
SwiftUI PDFデータをメモリに展開
// // ContentView.swift // CGDataConsumer2 // // Created by on 2025/02/24. // import SwiftUI import CoreGraphics import PDFKit struct ContentView: View { @State private var pdfData: Data? var body: some View { VStack { Button("メモリに PDF を作成") { pdfData = createPDFInMemory() } .padding() if let pdfData = pdfData { PDFPreview(pdfData: pdfData) .frame(height: 400) // `frame` を適用 .border(Color.black, width: 1) } } } func createPDFInMemory() -> Data? { let mutableData = NSMutableData() guard let consumer = CGDataConsumer(data: mutableData as CFMutableData) else { return nil } // 📌 `mediaBox` に `CGRect` を指定 var pageRect = CGRect(x: 0, y: 0, width: 595, height: 842) // A4サイズ guard let pdfContext = CGContext(consumer: consumer, mediaBox: &pageRect, nil) else { return nil } pdfContext.beginPDFPage(nil) // 赤い長方形を描画 pdfContext.setFillColor(CGColor(red: 1, green: 0, blue: 0, alpha: 1)) pdfContext.fill(CGRect(x: 100, y: 600, width: 200, height: 100)) // テキストを描画 let text = "Hello, macOS 15!" let attributes: [NSAttributedString.Key: Any] = [ .font: NSFont.systemFont(ofSize: 24), .foregroundColor: NSColor.black ] let attributedString = NSAttributedString(string: text, attributes: attributes) let line = CTLineCreateWithAttributedString(attributedString) pdfContext.textPosition = CGPoint(x: 100, y: 750) CTLineDraw(line, pdfContext) pdfContext.endPDFPage() pdfContext.closePDF() return mutableData as Data } } /// **PDFKit を使ったプレビュー** struct PDFPreview: View { let pdfData: Data var body: some View { PDFKitView(data: pdfData) } } /// **PDFKit を使って PDF を表示(macOS 用)** struct PDFKitView: NSViewRepresentable { let data: Data func makeNSView(context: Context) -> PDFView { let pdfView = PDFView() pdfView.document = PDFDocument(data: data) pdfView.autoScales = true return pdfView } // 📌 `updateNSView` で `PDFDocument` を再設定 func updateNSView(_ nsView: PDFView, context: Context) { nsView.document = PDFDocument(data: data) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
機能別
データコンシューマーを作る
CGDataConsumerCreate - macOS/iOS API解説
CGDataConsumerCreate
CGDataConsumerCreateWithURL
CGDataConsumerCreateWithCFData
CFType IDの取得
CGDataConsumerGetTypeID
Data Consumerの保持と破棄
CGDataConsumerRelease
CGDataConsumerRetain