Domanda

Sto scrivendo un programma (per Mac OS X, usando Objective-C) e ho bisogno di creare un gruppo di file .webloc a livello di codice.

Il file .webloc è semplicemente un file creato dopo aver trascinato e trascinato un URL dalla barra degli indirizzi di Safari in alcune cartelle.

In generale, ho bisogno di un approccio per creare elementi in un filesystem che puntino a una posizione nel Web. A quanto ho capito, i file .webloc dovrebbero essere usati per questo su Mac OS X.

Quindi, è possibile creare un file .webloc con un URL valido e un titolo per esso?

È stato utile?

Soluzione

È poco noto, ma esiste anche un semplice formato di file basato su plist per i webloc.

Quando crei file webloc, NON AVETE BISOGNO per salvarli usando il metodo delle risorse descritto dagli altri tre poster. Puoi anche scrivere un semplice 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>

Il formato delle risorse binarie è ancora in uso attivo e se si desidera leggere un file plist, assicurarsi di aver bisogno di leggere entrambi i formati di file. Ma quando si scrive il file, utilizzare il formato basato su plist, è molto più semplice.

Altri suggerimenti

I file

.webloc (più genericamente, file di posizione Internet) sono scritti in un formato la cui definizione risale a Mac OS 8.x. È basato sulle risorse, derivato dal formato di ritaglio che si ottiene quando si crea un file da oggetti trascinati come testo o immagini.

Le risorse scritte sono 'url' 256 e 'TEXT' 256, che memorizzano l'URL, e facoltativamente 'urln' 256, contenente il testo associato all'URL . 'trascina' 128 punti per le altre due (o tre) risorse.

NTWeblocFile, parte del Framework open source Cocoatech CocoaTechFoundation (licenza BSD), supporta la scrittura di questi file da Objective-C. Se desideri specificare un titolo separatamente nell'URL, dovrai modificare la classe in modo che scriva qualcosa di diverso dall'URL nella risorsa 'urln' .

In Mac OS X 10.3 e versioni successive, l'URL viene anche scritto (può anche essere scritto) in un elenco di proprietà nel fork dei dati del file. Vedi l'altra risposta per come funziona ...

Un file .webloc non ha nulla nel suo fork dei dati; memorizza invece l'URL a cui si riferisce come risorsa nel relativo fork delle risorse. Puoi vederlo sulla riga di comando usando DeRez (1) strumento

Qui l'ho eseguito su un file .webloc che ho trascinato fuori dalla barra degli indirizzi di Safari per questa domanda:

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

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

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

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

Le uniche risorse che probabilmente devono essere presenti sono le risorse 'url' e 'TEXT' di ID 256, e quelle probabilmente non hanno bisogno di nomi di risorse o. La risorsa 'urln' potrebbe essere utile se si desidera includere anche il titolo del documento a cui punta l'URL. La risorsa 'trascina' dice al sistema che si tratta di un file di ritaglio, ma non sono sicuro che debba essere presente al giorno d'oggi.

Per lavorare con le risorse e il fork delle risorse di un file, si utilizza Resource Manager, uno dei pezzi sottostanti di Carbon che risale al Mac originale. Vi sono, tuttavia, un paio di wrapper di cacao per il gestore delle risorse, come Nathan Day's NDResourceFork .

Un altro modo per creare " collegamento web " è il file .url già menzionato qui.
I contenuti sembrano (molto più semplici di quelli basati su XML):

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

Nota che il file ha 3 righe, l'ultima riga è vuota.

Ulteriori informazioni sul formato di file .url

Utilizza un formato binario basato su fork di risorse.

Soluzioni alternative valide:

  • Chiedi all'utente di trascinare un URL dall'applicazione (NSURLPboardType) nel Finder. Il Finder creerà un webloc per te.
  • Crea un collegamento Web di Windows (file .URL). Questi hanno un formato basato su fork di dati simile a INI e dovrebbero essere documentati da qualche parte su Internet; il sistema operativo li supporta in quanto supporta i webloc.

Ecco come funziona Google Chrome:

Esegue l'operazione di base, senza la necessità di librerie di terze parti. (Attenzione: controllo minimo degli errori.)

// 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);
                    }
                }
            }
        }
    }
}
scroll top