是否可以从CGPDFDocumentRef
答案 0 :(得分:5)
通过“文档名称”,您的意思是文档文件名或标题吗?
如果文档“title”包含在元数据中,则可以像这样检索它:
char *titleKey = "Title";
CGPDFStringRef titleStringRef;
CGPDFDictionaryRef info = CGPDFDocumentGetInfo(myDocumentRef);
CGPDFDictionaryGetString(info, titleKey, &titleStringRef);
const unsigned char *titleCstring = CGPDFStringGetBytePtr(titleStringRef);
printf("title: %s", titleCstring);
其他密钥在PDF 1.7规范的第10.2节中列出:Adobe PDF Reference Archives
答案 1 :(得分:1)
这是在Swift 5中执行此操作的方法:
extension CGPDFDocument {
var title: String? {
guard let infoDict = self.info else {
return nil
}
let titleKey = ("Title" as NSString).cString(using: String.Encoding.ascii.rawValue)!
var titleStringRef: CGPDFStringRef?
CGPDFDictionaryGetString(infoDict, titleKey, &titleStringRef)
if let stringRef = titleStringRef,
let cTitle = CGPDFStringGetBytePtr(stringRef) {
let length = CGPDFStringGetLength(stringRef)
let encoding = CFStringBuiltInEncodings.UTF8.rawValue
let allocator = kCFAllocatorDefault
let optionalTitle: UnsafePointer<UInt8>! = Optional<UnsafePointer<UInt8>>(cTitle)
if let title = CFStringCreateWithBytes(allocator, optionalTitle, length, encoding, true) {
return title as String
}
}
return nil
}
}
这是我对其工作方式的理解:
首先,我们检查PDF文档是否附有信息字典。 PDF信息字典可以包含包含文档标题的元数据。*
guard let infoDict = self.info else {
return nil
}
如果确实如此,我们尝试使用CGPDFDictionary
API从该词典中获取标题。该API仅接受C类型,因此我们需要执行一些转换才能将Swift String ”Title”
表示为C字符串。
let titleKey = ("Title" as NSString).cString(using: String.Encoding.ascii.rawValue)!
CGPDFDictionaryGetString
调用将指向CGPDFStringRef?
变量的指针作为其第三个参数。要将Swift引用转换为指针,我们在其前面加上&
。如果在创建PDF时未指定标题,则字典查找的结果可能为nil。
var titleStringRef: CGPDFStringRef?
CGPDFDictionaryGetString(infoDict, titleKey, &titleStringRef)
if let stringRef = titleStringRef,
let cTitle = CGPDFStringGetBytePtr(stringRef) {
至此,我们知道有一个标题字符串,但是尚不在可用的Swift字符串中。要从内存中读取C字符串(使用CFStringCreateWithBytes
),我们需要知道它的起始位置(指针)以及停止读取多少字节后的长度(长度)。此外,我们指定应使用UTF-8编码读取字符串,并使用默认的内存布局。我们需要的最后一项是对C字符串的正确键入引用。 C字符串的类型是指向char
的指针,该指针在内存中表示为UInt8
。所以我们以Optional<UnsafePointer<UInt8>>
结尾。
let length = CGPDFStringGetLength(stringRef)
let encoding = CFStringBuiltInEncodings.UTF8.rawValue
let allocator = kCFAllocatorDefault
let optionalTitle: UnsafePointer<UInt8>! = Optional<UnsafePointer<UInt8>>(cTitle)
收集到这些信息后,现在该从C字符串中获取Swift字符串了。值得庆幸的是,CFString是免费的桥接到Swift的String,这意味着我们可以使用CFStringCreateWithBytes
调用并将结果简单地转换为String。
if let title = CFStringCreateWithBytes(allocator, optionalTitle, length, encoding, true) {
return title as String
}
}
return nil
*此字典中各个值的键可在第Adobe PDF Reference book,表8.4的表10.2“文档信息字典中的条目”中找到。