Pergunta

Eu estou escrevendo um programa (para Mac OS X, utilizando Objective-C) e eu preciso para criar um monte de arquivos .webloc programação.

O arquivo .webloc é simplesmente arquivo que é criado depois de arrastar e soltar um URL na barra de localização do Safari para alguma pasta.

De um modo geral, eu preciso de uma abordagem para criar itens em um sistema de arquivos que apontam para algum local na Web. Como eu entendo arquivos .webloc deve ser usado para isso no Mac OS X.

Assim, é possível criar um arquivo .webloc ter um url válido e algum título para ele?

Foi útil?

Solução

É pouco conhecido -. Mas há também um formato de arquivo plist baseado simples para weblocs

Ao criar webloc arquivos você não precisa para salvá-los usando o método recurso os outros três cartazes descrever. Você também pode escrever um plist simples:

?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>

O formato de recurso binário ainda está em uso ativo e se você quiser ler um arquivo plist - então certeza você precisa ler ambos os formatos de arquivo. Mas ao escrever o arquivo - use o formato baseado plist -., É muito mais fácil

Outras dicas

arquivos .webloc (mais genericamente, arquivos de localização na Internet) são escritos em um formato cuja definição remonta ao Mac OS 8.x É baseada em recursos, derivado do formato de recorte que você começa quando você cria um arquivo de objetos arrastados, como texto ou imagens.

Os recursos escritos são 'url ' 256 e 'TEXT' 256, que armazenam o URL e, opcionalmente, 'urln' 256, que contém o texto associado ao URL. 'drag' 128 pontos para as outras duas (ou três) recursos.

NTWeblocFile, parte do quadro Cocoatech Open Source CocoaTechFoundation (BSD licenciado), suportes escrever estas arquivos de Objective-C. Se você quiser especificar um título separado para a URL, você precisará modificar a classe para que ele escreve algo diferente do URL para o recurso 'urln'.

No Mac OS X 10.3 e posterior, a URL é também escrito (também pode ser escrita) em uma lista de propriedades na bifurcação de dados do arquivo. Veja a outra resposta para como isso funciona ...

Um arquivo .webloc não tem nada em seu bifurcação de dados; em vez disso, ele armazena o URL refere-se a como um recurso em seu bifurcação de recursos. Você pode ver isso na linha de comando usando o Derez (1) ferramenta

Aqui eu executá-lo em um arquivo .webloc que eu arrastado para fora da minha barra de endereços do Safari para esta pergunta:

% 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 */
};

Os únicos recursos que provavelmente precisa ser lá são os 'url ' e 'TEXT' recursos de ID 256, e esses nomes de recursos provavelmente não precisa de qualquer um. O recurso 'urln' pode ser útil se você quiser incluir o título do documento a URL aponta para bem. O recurso 'drag' informa ao sistema que este é um ficheiro de recorte, mas não estou certo sobre se ele precisa estar lá neste dia e idade.

Para trabalhar com recursos e a bifurcação de recursos de um arquivo, use o Gerenciador de recursos - uma das peças fundamentais de carbono que vai voltar para o Mac originais. Há, no entanto, um par de invólucros de cacau para o Gerenciador de recursos, tais como Nathan Day NDResourceFork .

Outra maneira de fazer "atalho web" é o arquivo .url mencionado aqui já.
O conteúdo parecido com (muito mais simples do que plist-xml base):

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

Observe o arquivo tem 3 linhas, a última linha está vazia.

Mais informações sobre o formato de arquivo .url

Ele usa um formato binário baseado em bifurcação de recursos.

soluções alternativas válidas:

  • Que o usuário arraste uma URL do seu aplicativo (NSURLPboardType) para o Finder. O Finder irá criar um webloc para você.
  • Criar uma apresentação (arquivo .url) Windows Web Atalho. Estes têm um INI-like formato baseado em bifurcação de dados e deve ser documentado em algum lugar na Internet; os suportes OS-los, pois suporta weblocs.

Veja como o Google Chrome faz isso: WriteURLToNewWebLocFileResourceFork

Este faz a tarefa básica, sem a necessidade de quaisquer bibliotecas de terceiros. (Esteja avisado:. Mínimo verificação de erros)

// 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);
                    }
                }
            }
        }
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top