Я весь день пытался получить метаданные гиперссылок из PDF файлов в своем приложении iPad. API CGPDF * - настоящий кошмар, и единственная часть информации, которую я нашел в сети, - это то, что мне нужно искать словарь "Annots", но я просто не могу найти его в своих PDF файлах.
Я даже использовал старый образец Voyeur Xcode для проверки моего тестового PDF файла, но никаких следов этого словаря "Annots"...
Вы знаете, это функция, которую я вижу в каждом PDF-читателе - этот же вопрос был спросил несколько здесь без реальных практических ответов. Обычно я никогда не прошу образец кода напрямую, но, видимо, на этот раз мне это действительно нужно... кто-нибудь получил эту работу, возможно, с образцом кода?
Обновление. Я просто понял, что парень, который сделал мой тестовый PDF, просто ввел URL-адрес в качестве текста, а не настоящую аннотацию. Он попытался поставить аннотацию, и мой код работает сейчас... Но это не то, что мне нужно, поэтому мне кажется, что мне придется анализировать текст и искать URL-адреса. Но эта другая история...
Обновление 2. Итак, я наконец придумал какой-то рабочий код. Я размещаю его здесь, поэтому, надеюсь, это поможет кому-то. Предполагается, что документ PDF содержит аннотации.
for(int i=0; i<pageCount; i++) {
CGPDFPageRef page = CGPDFDocumentGetPage(doc, i+1);
CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(page);
CGPDFArrayRef outputArray;
if(!CGPDFDictionaryGetArray(pageDictionary, "Annots", &outputArray)) {
return;
}
int arrayCount = CGPDFArrayGetCount( outputArray );
if(!arrayCount) {
continue;
}
for( int j = 0; j < arrayCount; ++j ) {
CGPDFObjectRef aDictObj;
if(!CGPDFArrayGetObject(outputArray, j, &aDictObj)) {
return;
}
CGPDFDictionaryRef annotDict;
if(!CGPDFObjectGetValue(aDictObj, kCGPDFObjectTypeDictionary, &annotDict)) {
return;
}
CGPDFDictionaryRef aDict;
if(!CGPDFDictionaryGetDictionary(annotDict, "A", &aDict)) {
return;
}
CGPDFStringRef uriStringRef;
if(!CGPDFDictionaryGetString(aDict, "URI", &uriStringRef)) {
return;
}
CGPDFArrayRef rectArray;
if(!CGPDFDictionaryGetArray(annotDict, "Rect", &rectArray)) {
return;
}
int arrayCount = CGPDFArrayGetCount( rectArray );
CGPDFReal coords[4];
for( int k = 0; k < arrayCount; ++k ) {
CGPDFObjectRef rectObj;
if(!CGPDFArrayGetObject(rectArray, k, &rectObj)) {
return;
}
CGPDFReal coord;
if(!CGPDFObjectGetValue(rectObj, kCGPDFObjectTypeReal, &coord)) {
return;
}
coords[k] = coord;
}
char *uriString = (char *)CGPDFStringGetBytePtr(uriStringRef);
NSString *uri = [NSString stringWithCString:uriString encoding:NSUTF8StringEncoding];
CGRect rect = CGRectMake(coords[0],coords[1],coords[2],coords[3]);
CGPDFInteger pageRotate = 0;
CGPDFDictionaryGetInteger( pageDictionary, "Rotate", &pageRotate );
CGRect pageRect = CGRectIntegral( CGPDFPageGetBoxRect( page, kCGPDFMediaBox ));
if( pageRotate == 90 || pageRotate == 270 ) {
CGFloat temp = pageRect.size.width;
pageRect.size.width = pageRect.size.height;
pageRect.size.height = temp;
}
rect.size.width -= rect.origin.x;
rect.size.height -= rect.origin.y;
CGAffineTransform trans = CGAffineTransformIdentity;
trans = CGAffineTransformTranslate(trans, 0, pageRect.size.height);
trans = CGAffineTransformScale(trans, 1.0, -1.0);
rect = CGRectApplyAffineTransform(rect, trans);
// do whatever you need with the coordinates.
// e.g. you could create a button and put it on top of your page
// and use it to open the URL with UIApplication openURL
}
}