2008-09-28 14 views
17

Piszę program (dla Mac OS X, używając Objective-C) i potrzebuję programowo utworzyć kilka plików .webloc.Tworzenie pliku .webloc

Plik .webloc jest po prostu plikiem, który jest tworzony po przeciągnięciu i upuszczeniu adresu URL z paska lokalizacji Safari do wybranego folderu.

Ogólnie rzecz biorąc, potrzebuję podejścia do tworzenia elementów w systemie plików wskazującym pewną lokalizację w sieci. Jak rozumiem, pliki .bloc powinny być w tym celu używane w systemie Mac OS X.

Czy istnieje możliwość utworzenia pliku .webloc z poprawnym adresem URL i jakimś tytułem?

Odpowiedz

21

Jest to mało znany - ale istnieje również prosty format plików plist dla weblocs.

Podczas tworzenia plików webloc, NIE POTRZEBUJESZ, aby zapisać je przy użyciu metody zasobów opisanej przez pozostałe trzy plakaty. Można również napisać prosty plist:

?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
<dict> 
    <key>URL</key> 
    <string>http://apple.com</string> 
</dict> 
</plist> 

Format zasób binarny jest wciąż aktywnego używania i jeśli chcesz przeczytać plik plist - wtedy na pewno trzeba przeczytać oba formaty plików. Ale podczas pisania pliku - użyj formatu opartego na plist - jest o wiele łatwiej.

+1

Czy ktoś może potwierdzić, że plik webloc z widelcem danych działa z Safari? Próbowałem zapisać przykładowy plik XML Schwa jako plik webloc, ale przeciągając go do Safari, po prostu otwiera puste okno. Próbowałem też zapisać plik webloc w Firefoksie. Co ciekawe, Firefox zapisuje plik zarówno z widelcem danych (plist XML, jak w przykładzie Schwa), jak i widełką zasobów. Przeciąganie tego pliku do Safari działa. Ale gdy próbowałem usunąć widełki zasobów (przez nadpisanie go w wierszu poleceń pustym strumieniem) nie działało. Test wykonany przy użyciu Safari 4.0.5 i Firefox 3.6.3. – Rinzwind

+3

Dalsze wyjaśnienia do mojego wcześniejszego komentarza: Nie próbowałem po prostu dwukrotnie kliknąć plik, aby go otworzyć. Właśnie zrobiłem i to działa z plikiem webloc, który otwiera adres URL w Safari. Ale jak już wspomniałem powyżej, DRAGGING pliku webloc do Safari NIE działa, wyświetla puste okno. (Ponadto przeciągnięcie pliku do okna zakładek przeglądarki Safari tworzy zakładkę z plikiem: // URL dla pliku webloc, zamiast zakładki dla adresu URL zawartego w pliku webloc.) – Rinzwind

1

Używa formatu binarnego opartego na widłach.

Prawidłowe obejścia:

  • Czy użytkownik przeciągnąć URL z aplikacji (NSURLPboardType) do Finder. Finder utworzy dla Ciebie webloc.
  • Utwórz skrót Web Web (plik .URL). Mają one format danych widżetowych typu INI i powinny być udokumentowane gdzieś w Internecie; system operacyjny obsługuje je, ponieważ obsługuje webloki.
6

Plik .webloc nie ma niczego w widelecie danych; zamiast tego przechowuje adres URL, który określa jako zasób w widełce zasobów. Widać to w wierszu poleceń za pomocą narzędzia DeRez(1)

Tutaj Zabrakło mi go na .webloc pliku, że wyciągnięty z moim pasku adresu Safari na to pytanie:

% DeRez "Desktop/Crafting .webloc file - Stack Overflow.webloc" 
data 'drag' (128, "Crafting .webloc file -#1701953") { 
    $"0000 0001 0000 0000 0000 0000 0000 0003"   /* ................ */ 
    $"5445 5854 0000 0100 0000 0000 0000 0000"   /* TEXT............ */ 
    $"7572 6C20 0000 0100 0000 0000 0000 0000"   /* url ............ */ 
    $"7572 6C6E 0000 0100 0000 0000 0000 0000"   /* urln............ */ 
}; 

data 'url ' (256, "Crafting .webloc file -#1701953") { 
    $"6874 7470 3A2F 2F73 7461 636B 6F76 6572"   /* http://stackover */ 
    $"666C 6F77 2E63 6F6D 2F71 7565 7374 696F"   /* flow.com/questio */ 
    $"6E73 2F31 3436 3537 352F 6372 6166 7469"   /* ns/146575/crafti */ 
    $"6E67 2D77 6562 6C6F 632D 6669 6C65"     /* ng-webloc-file */ 
}; 

data 'TEXT' (256, "Crafting .webloc file -#1701953") { 
    $"6874 7470 3A2F 2F73 7461 636B 6F76 6572"   /* http://stackover */ 
    $"666C 6F77 2E63 6F6D 2F71 7565 7374 696F"   /* flow.com/questio */ 
    $"6E73 2F31 3436 3537 352F 6372 6166 7469"   /* ns/146575/crafti */ 
    $"6E67 2D77 6562 6C6F 632D 6669 6C65"     /* ng-webloc-file */ 
}; 

data 'urln' (256, "Crafting .webloc file -#1701953") { 
    $"4372 6166 7469 6E67 202E 7765 626C 6F63"   /* Crafting .webloc */ 
    $"2066 696C 6520 2D20 5374 6163 6B20 4F76"   /* file - Stack Ov */ 
    $"6572 666C 6F77"          /* erflow */ 
}; 

Jedyne środki, które prawdopodobnie muszą tam być zasoby IDi 'TEXT' o identyfikatorze 256, a te prawdopodobnie również nie potrzebują nazw zasobów. Zasób 'urln' może być przydatny, jeśli chcesz dołączyć tytuł dokumentu, do którego prowadzi adres URL. Zasób 'drag' informuje system, że jest to plik obcinania, ale nie jestem pewien, czy musi on być obecny w tym dniu i wieku.

Do pracy z zasobami i widelcem zasobów pliku służy Menedżer zasobów - jeden z podstawowych elementów węgla, który powraca do oryginalnego komputera Mac. Istnieje jednak kilka zawijaków kakao dla Menedżera zasobów, takich jak Nathan Day's NDResourceFork.

+1

W moich próbach z Safari i TextEdit, ' 'drag'' musi tam być. Nazwy zasobów są ignorowane; przeciągnięcie linku z NSTextView nie powoduje ich utworzenia. –

7

Pliki (bardziej ogólnie, pliki lokalizacji internetowych) są zapisywane w formacie, którego definicja powraca do systemu Mac OS 8.x. Jest oparty na zasobach, wywodzi się z formatu obcinania, który powstaje podczas tworzenia pliku z przeciągniętych obiektów, takich jak tekst lub obrazy.

Zapisane zasoby: 'url ' 256 i 'TEXT' 256, które przechowują adres URL i opcjonalnie "urln" 256, zawierające tekst związany z adresem URL. 'drag' 128 punktów do pozostałych dwóch (lub trzech) zasobów.

NTWeblocFile, część Cocoatech Open Source framework CocoaTechFoundation (licencjonowana na BSD), obsługuje zapisywanie tych plików z Objective-C. Jeśli chcesz określić tytuł oddzielnie do adresu URL, musisz zmodyfikować klasę, aby zapisywać coś innego niż adres URL w zasobie 'urln'.

W systemie Mac OS X 10.3 i później adres URL jest również zapisywany (może również być zapisany) na liście właściwości w widelecie danych pliku. Zobacz drugą odpowiedź, aby dowiedzieć się, jak to działa ...

+0

Format pliku plist istnieje od 10.3 - jest w pełni obsługiwany. Utwórz jeden w wyszukiwarce i kliknij go dwukrotnie, a otworzy go FInder w Safari (lub cokolwiek innego). Świetnym sposobem na utworzenie plist webloc jest na przykład przeciągnięcie adresu URL z BBEdit. – schwa

+0

(Z jakiegoś powodu podczas testowania wygenerowałem nieprawidłowe pliki plist.) Masz rację, działa.) –

2

Innym sposobem na utworzenie "skrótu sieciowego" jest już wymieniony plik .url.
Zawartość wyglądać (znacznie prostsza niż plist oparty na XML):

[InternetShortcut] 
URL=http://www.apple.com/ 

Uwaga plik ma 3 linie, ostatnia linia jest pusta.

More info on .url file format

+2

Niestety, są one obsługiwane przez Safari, a nie system. Oznacza to, że Safari spróbuje obsłużyć adres URL w pliku, niezależnie od tego, czy Safari jest domyślną aplikacją dla schematu tego URL, czy może nawet obsłużyć ten schemat. –

0

to robi podstawowe zadanie, bez konieczności żadnych bibliotek innych firm. (Uwaga: minimalny sprawdzanie błędów.)

// data for 'drag' resource (it's always the same) 
#define DRAG_DATA_LENGTH 64 
static const unsigned char _dragData[DRAG_DATA_LENGTH]={ 
    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 
    0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x75, 0x72, 0x6C, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x75, 0x72, 0x6C, 0x6E, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 

static void _addData(NSData *data, ResType type, short resId, ResFileRefNum refNum) 
{ 
    Handle handle; 
    if (PtrToHand([data bytes], &handle, [data length])==noErr) { 
     ResFileRefNum previousRefNum=CurResFile(); 
     UseResFile(refNum); 

     HLock(handle); 
     AddResource(handle, type, resId, "\p"); 
     HUnlock(handle); 

     UseResFile(previousRefNum); 
    } 
} 

void WeblocCreateFile(NSString *location, NSString *name, NSURL *fileUrl) 
{ 
    NSString *contents=[NSString stringWithFormat: 
         @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 
         @"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" 
         @"<plist version=\"1.0\">\n" 
         @"<dict>\n" 
         @"<key>URL</key>\n" 
         @"<string>%@</string>\n" 
         @"</dict>\n" 
         @"</plist>\n", location]; 

    if ([[contents dataUsingEncoding:NSUTF8StringEncoding] writeToURL:fileUrl options:NSDataWritingAtomic error:nil]) 
    {   
     // split into parent and filename parts 
     NSString *parentPath=[[fileUrl URLByDeletingLastPathComponent] path]; 
     NSString *fileName=[fileUrl lastPathComponent]; 

     FSRef parentRef; 
     if(FSPathMakeRef((const UInt8 *)[parentPath fileSystemRepresentation], &parentRef, NULL)==noErr) 
     { 
      unichar fileNameBuffer[[fileName length]]; 
      [fileName getCharacters:fileNameBuffer]; 

      FSCreateResFile(&parentRef, [fileName length], fileNameBuffer, 0, NULL, NULL, NULL); 
      if (ResError()==noErr) 
      { 
       FSRef fileRef; 
       if(FSPathMakeRef((const UInt8 *)[[fileUrl path] fileSystemRepresentation], &fileRef, NULL)==noErr) 
       { 
        ResFileRefNum resFileReference = FSOpenResFile(&fileRef, fsWrPerm); 
        if (resFileReference>0 && ResError()==noErr) 
        { 
         _addData([NSData dataWithBytes:_dragData length:DRAG_DATA_LENGTH], 'drag', 128, resFileReference); 
         _addData([location dataUsingEncoding:NSUTF8StringEncoding], 'url ', 256, resFileReference); 
         _addData([location dataUsingEncoding:NSUTF8StringEncoding], 'TEXT', 256, resFileReference); 
         _addData([name dataUsingEncoding:NSUTF8StringEncoding], 'urln', 256, resFileReference); 
         CloseResFile(resFileReference); 
        } 
       } 
      } 
     } 
    } 
} 
+1

o wiele łatwiej po prostu pozwolić, aby nsdictionary zrobił plist dla ciebie. \t \t NSMutableDictionary * dict = [Słownik NSMutableDictionaryWithCapacity: 1]; \t [dict setObject: @ "http: //" forKey: @ "URL"]; \t \t [Dict writeToFile: @ "/ file" atomically: NO]; – bigkm