2008-09-28 26 views
17

Tôi đang viết một chương trình (cho Mac OS X, sử dụng Objective-C) và tôi cần tạo một nhóm các tệp .webloc theo lập trình.Crafting .webloc file

Tệp .webloc là tệp đơn giản được tạo sau khi bạn kéo-thả-thả một URL từ thanh vị trí của Safari vào một số thư mục.

Nói chung, tôi cần một cách tiếp cận để tạo các mục trong hệ thống tệp trỏ đến một số vị trí trong Web. Theo tôi hiểu các tệp .webloc nên được sử dụng cho điều này trên Mac OS X.

Vì vậy, có thể tạo tệp .webloc có url hợp lệ và một số tiêu đề cho nó không?

Trả lời

21

Nó ít được biết đến - nhưng cũng có định dạng tệp dựa trên plist đơn giản cho weblocs.

Khi tạo tệp webloc, bạn KHÔNG CẦN để lưu chúng bằng phương pháp tài nguyên mà ba áp phích khác mô tả. Bạn cũng có thể viết một plist đơn giản:

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

Định dạng tài nguyên nhị phân vẫn đang hoạt động và nếu bạn muốn đọc một tệp plist - thì chắc chắn bạn cần đọc cả hai định dạng tệp. Nhưng khi viết tệp - hãy sử dụng định dạng dựa trên định dạng plist - nó dễ dàng hơn rất nhiều.

+1

Có ai có thể xác nhận tệp webloc chỉ với một ngã ba dữ liệu hoạt động với Safari không? Tôi đã cố gắng lưu ví dụ XML plist của Schwa như một tệp tin webloc nhưng khi kéo nó vào Safari nó chỉ mở một cửa sổ trống. Tôi cũng đã thử lưu một tệp webloc với Firefox. Thật thú vị, Firefox viết một tập tin với cả một ngã ba dữ liệu (XML plist như trong ví dụ của Schwa) và một ngã ba tài nguyên. Kéo tệp đó vào Safari hoạt động. Nhưng khi tôi đã cố gắng loại bỏ các ngã ba tài nguyên (bằng cách ghi đè nó trên dòng lệnh với một dòng sản phẩm nào) nó không còn làm việc. Thử nghiệm được thực hiện bằng cách sử dụng Safari 4.0.5 và Firefox 3.6.3. – Rinzwind

+3

Làm rõ thêm cho nhận xét trước đó của tôi: Tôi đã không thử chỉ đơn giản là nhấp đúp vào tệp để mở tệp. Tôi vừa làm và DOES đó làm việc với tệp webloc-data-fork-only, nó sẽ mở URL trong Safari. Nhưng như tôi đã nói ở trên, DRAGGING tệp webloc vào Safari KHÔNG hoạt động, nó sẽ trả về một cửa sổ trống. (Ngoài ra, kéo tệp vào cửa sổ dấu trang Safari tạo dấu trang có URL: // URL cho tệp webloc, thay vì dấu trang cho URL chứa trong tệp webloc.) – Rinzwind

1

Sử dụng định dạng nhị phân dựa trên tài nguyên.

cách giải quyết hợp lệ:

  • Có người dùng kéo một URL từ ứng dụng của bạn (NSURLPboardType) để Finder. Trình tìm kiếm sẽ tạo một webloc cho bạn.
  • Tạo Lối tắt web Windows (tệp .URL). Chúng có định dạng dựa trên dữ liệu giống như INI và phải được ghi lại ở đâu đó trên Internet; hệ điều hành hỗ trợ chúng vì nó hỗ trợ weblocs.
6

A .webloc tệp không có bất kỳ nội dung nào trong dĩa dữ liệu; thay vào đó, nó lưu trữ URL mà nó đề cập đến như một tài nguyên trong ngã ba tài nguyên của nó. Bạn có thể thấy điều này trên dòng lệnh bằng công cụ DeRez(1)

Ở đây tôi đã chạy nó trên một tập tin .webloc mà tôi kéo ra khỏi thanh địa chỉ trình duyệt Safari của tôi cho câu hỏi này:

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

Các nguồn tài nguyên duy nhất mà có thể cần phải ở trong đó là các tài nguyên 'url ''TEXT' của ID 256 và những tài nguyên đó có thể không cần tên tài nguyên. Tài nguyên 'urln' có thể hữu ích nếu bạn muốn bao gồm tiêu đề của tài liệu mà URL trỏ tới. Tài nguyên 'drag' cho hệ thống biết đây là tệp cắt, nhưng tôi không chắc liệu nó có cần ở đó trong ngày và tuổi không.

Để làm việc với tài nguyên và nhánh tài nguyên của tệp, bạn sử dụng Trình quản lý tài nguyên - một trong những phần cơ bản của Carbon quay lại máy Mac gốc. Tuy nhiên, có một vài trình bao bọc Cocoa cho Trình quản lý tài nguyên, chẳng hạn như Nathan Day's NDResourceFork.

+1

Trong thử nghiệm của tôi với Safari và TextEdit, ' 'drag'' cần phải có mặt ở đó. Tên tài nguyên bị bỏ qua; kéo một liên kết từ một NSTextView không tạo ra chúng. –

7

.webloc tệp (tổng quát hơn, tệp vị trí Internet) được viết theo định dạng có định nghĩa quay lại Mac OS 8.x. Nó dựa trên tài nguyên, bắt nguồn từ định dạng cắt mà bạn nhận được khi bạn tạo một tệp từ các đối tượng được kéo như văn bản hoặc hình ảnh.

Tài nguyên được viết là 'url ' 256 và 'TEXT' 256, lưu trữ URL và tùy chọn 'urln' 256, chứa văn bản được liên kết với URL. 'drag' 128 điểm cho hai (hoặc ba) tài nguyên khác.

NTWeblocFile, một phần của Cocoatech Open Source framework CocoaTechFoundation (BSD được cấp phép), hỗ trợ ghi các tệp này từ Mục tiêu-C. Nếu bạn muốn chỉ định một tiêu đề riêng biệt cho URL, bạn sẽ cần phải sửa đổi lớp để nó viết một cái gì đó khác với URL vào tài nguyên 'urln'.

Trong Mac OS X 10.3 và sau đó, URL cũng được viết (cũng có thể được viết) vào danh sách thuộc tính trong ngã ba dữ liệu của tệp. Xem câu trả lời khác cho cách hoạt động này ...

+0

Định dạng plist đã được khoảng từ 10,3 - nó _is_ hỗ trợ đầy đủ. Tạo một trong công cụ tìm và nhấp đúp vào nó và nó sẽ được mở bởi FInder trong Safari (hoặc bất kỳ thứ gì). Một cách tuyệt vời để tạo một webloc plist là bằng cách kéo một URL từ BBEdit chẳng hạn. – schwa

+0

(Vì bất kỳ lý do gì tôi đã tạo ra các plists không hợp lệ trong các bài kiểm tra của mình. Bạn đang đúng, nó hoạt động.) –

2

Một cách khác để tạo "lối tắt web" là .url tệp được đề cập ở đây rồi.
Nội dung trông giống như (đơn giản hơn nhiều so với plist xml-based):

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

Lưu ý các tập tin có 3 dòng, dòng cuối cùng là sản phẩm nào.

More info on .url file format

+2

Thật không may, các tệp này được Safari xử lý chứ không phải hệ thống. Điều này có nghĩa là Safari sẽ cố gắng xử lý URL trong tệp, bất kể Safari là ứng dụng mặc định cho lược đồ của URL đó hay liệu nó có thể xử lý lược đồ đó hay không. –

0

Thao tác cơ bản này mà không cần thư viện của bên thứ ba. (Được cảnh báo: kiểm tra lỗi tối thiểu.)

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

dễ dàng hơn nhiều để chỉ cần cho nsdictionary làm plist cho bạn. \t \t NSMutableDictionary * dict = [NSMutableDictionary dictionaryWithCapacity: 1]; \t \t [dict setObject: @ "http: //" forKey: @ "URL"]; \t \t [dict writeToFile: @ "/ file" nguyên tử: NO]; – bigkm