2011-08-30 36 views
10

Tôi cần triển khai ứng dụng Mac OS X. Trong đơn đăng ký của tôi, tôi cần phải làm hai việc:Thực hiện một ứng dụng trên Mac OS X khi một loại thiết bị USB cụ thể được kết nối?

  1. Thực thi/Mở ứng dụng khi một loại thiết bị USB cụ thể được kết nối với hệ thống.
  2. Đọc dữ liệu từ USB và tải dữ liệu lên máy chủ web.

Tôi không có nhiều kinh nghiệm về phát triển Mac OS X. Bất cứ ai có thể xin đề nghị các tài liệu tốt nhất để đạt được mục tiêu của tôi?

Trả lời

1

Nó thực sự phụ thuộc vào loại ứng dụng bạn đang xem.

Có vẻ như không có cách nào để thực hiện theo cách tương tự như ví dụ udev.

Để giải quyết tranh cãi sẽ là:

  • Viết một tài xế wrapper tùy chỉnh cho thiết bị của bạn
  • Sử dụng libusb và có một daemon phải chờ cho điện thoại nhất định.

Và trên thực tế người ta có thể viết một chương trình với libusb mà sẽ xử lý loại này nhiệm vụ theo một tập tin cấu hình nhất định, đó cũng sẽ được cross-nền tảng từ libusb hỗ trợ khá nhiều nền tảng.

4

Tùy thuộc vào loại thiết bị bạn có thể đặt ứng dụng tự động mở thông qua tùy chọn iPhoto/Image Capture. Điều đó sẽ chỉ hoạt động đối với một loại thiết bị giới hạn, đối với một ứng dụng đã có trên máy tính và sẽ yêu cầu thay đổi các tùy chọn trên máy tính theo cách thủ công.

Nói chung, không có cách nào để tự động chạy các ứng dụng tùy ý trên đĩa CD/DVD/USB chèn vì đó là sự cố bảo mật.

1

Bạn có thể đặt Hành động thư mục để chạy lệnh trên gắn kết. Điều này sẽ cho rằng thiết bị luôn gắn kết ở cùng một vị trí, tức là/Âm lượng/My \ Device/- nếu thiết bị ngoại vi được thêm vào hoặc bị tháo ở giữa các giá lắp, điểm lắp có thể thay đổi. Bạn có thể tìm hiểu thêm về Tác vụ Thư mục bằng cách nhấp chuột phải vào thư mục và nhấp vào "Thiết lập Tác vụ Thư mục". Bí quyết là đảm bảo rằng thiết bị luôn gắn kết vào cùng một vị trí.

Hoặc, bạn có thể sử dụng launchd để chạy lệnh trên gắn kết. This link có thể hữu ích. Lingon là một ứng dụng tuyệt vời để chỉnh sửa daemon.

Dù bằng cách nào, bạn có thể sử dụng Hành động thư mục hoặc daemon để gọi một tập lệnh đơn giản để lấy nội dung của thiết bị và tải chúng lên bất cứ nơi nào bạn muốn.

19

Bạn có thể sử dụng launchd. Hãy thử man launchd và man launchd.plist.

Dường như launchd có thể hoạt động với các sự kiện USB, mặc dù tính năng này kém tài liệu. Tôi tìm thấy nó trên: man xpc_set_event_stream_handler

Đây là một ví dụ.Nếu bạn đặt thông tin sau vào: ~/Library/LaunchAgents/com.example.plist, chương trình của bạn sẽ bắt đầu khi thiết bị USB được kết nối.

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd > 
<plist version="1.0"> 
<dict> 
    <key>Label</key> 
    <string>com.example.program</string> 
    <key>ProgramArguments</key> 
    <array> 
    <string>/path/to/program</string> 
    </array> 
    <key>LaunchEvents</key> 
    <dict> 
      <key>com.apple.iokit.matching</key> 
      <dict> 
        <key>com.apple.device-attach</key> 
        <dict> 
          <key>idProduct</key> 
          <integer>1234</integer> 
          <key>idVendor</key> 
          <integer>1337</integer> 
          <key>IOProviderClass</key> 
          <string>IOUSBDevice</string> 
          <key>IOMatchLaunchStream</key> 
          <true/> 
        </dict> 
      </dict> 
    </dict> 
</dict> 
</plist> 
+1

chỉ cần đảm bảo rằng nếu bạn đi tuyến đường này và không muốn quá trình khởi chạy của bạn tiếp tục chạy (tức là KeepAlive = false) mã của bạn gọi xpc_set_event_stream_handler() nếu không bạn sẽ thấy ứng dụng của mình được respawned cứ sau 10 giây để phản hồi cùng một sự kiện trùng khớp lặp đi lặp lại. – rudy

+0

Tính năng này có hoạt động dưới OS X 10.6 không? Tôi nhận được "LaunchEvents chính không được công nhận". (Xem http://stackoverflow.com/q/15397304/558639) –

+4

Có cách nào để sử dụng điều này với các kịch bản shell được khởi chạy từ 'launchd' thay vì một ứng dụng Xcode (ví dụ:'/path/to/program' là một kịch bản lệnh shell). Kịch bản lệnh shell sẽ được khởi chạy lại sau mỗi 10 giây và tôi không thể tìm thấy biểu mẫu thay thế dòng lệnh 'xpc_set_event_stream_handler()' hoặc bất kỳ cách nào để xóa sự kiện khỏi luồng. – romeovs

2

Câu trả lời của Julien Pilet có hiệu quả đối với tôi. Tuy nhiên, để làm cho nó không ngừng relaunch ứng dụng khi thiết bị vẫn còn kết nối khi đóng ứng dụng, tôi phải:

  • gọi xpc_set_event_stream_handler() trong ứng dụng của tôi đại biểu applicationDidFinishLaunching:
xpc_set_event_stream_handler("com.apple.iokit.matching", NULL, ^(xpc_object_t event) {  
     // Every event has the key XPC_EVENT_KEY_NAME set to a string that 
     // is the name you gave the event in your launchd.plist. 
     const char *name = xpc_dictionary_get_string(event, XPC_EVENT_KEY_NAME); 

     // IOKit events have the IORegistryEntryNumber as a payload. 
     uint64_t id = xpc_dictionary_get_uint64(event, "IOMatchLaunchServiceID"); 
     // Reconstruct the node you were interested in here using the IOKit 
     // APIs. 
     NSLog(@"Received event: %s: %llu",name,id); 
    }); 
  • thêm cặp khóa/giá trị KeepAlive/false vào plist
  • thêm IOMatchLaunchStream/true cặp khóa/giá trị vào số com.apple.device-attach dict trong plist. Đây là ngoài khóa IOMatchStream đã có. Bạn không chắc chắn lý do tại sao mà đã có mặt ở đó, tôi thấy một tham chiếu đến nó ở đây: http://asciiwwdc.com/2013/sessions/702

Cũng đừng quên đăng ký plist với hệ thống sử dụng

launchctl load <path to your plist> 

Lưu ý rằng điều này dường như làm việc , nhưng tôi chưa bao giờ nhận được thông điệp NSLog từ trình xử lý luồng xpc.

+0

Từ [tài liệu] (https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/xpc_set_event_stream_handler.3.html): Khóa IOMatchLaunchStream là bắt buộc để có mặt và là một bộ Boolean đúng để sử dụng với Sự kiện XPC. Nó sẽ được lọc ra khỏi phần còn lại của từ điển khi đưa cho IOKit để khớp. Lý do cho điều này là lịch sử và không áp dụng cho các luồng sự kiện khác. – Mitar

Các vấn đề liên quan