6

次のコードを使用して、現在のマシンのアイコンを cocoa から取得できることを知っています。

NSImage *machineIcon = [NSImage imageNamed:NSImageNameComputer];

しかし、型番だけでアイコンを取得することは可能でしょうか? のようなMacBookPro11,3

これが必要な理由はMultiPeer Connectivity、接続したいネットワーク上のデバイスを参照するために使用しているためです。しかし、これらのデバイスのアイコンをカスタマイズされたブラウザー ビューで表示したいと考えています。

OS X には、次のフォルダー内のすべてのデバイスのほぼすべてのアイコンがあることを知っています。

/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/

しかし、アプリ内からそれらにアクセスする方法を知りたい:

discoveryInfoからデバイス広告のアイコンを送信することを考えましたMCNearbyServiceAdvertiserが、 ではそれほど多くのデータを送信できませんdiscoveryInfo。少量のテキスト用にのみ設計されています。そのため、代わりにマシンのモデル番号を送信することにしました。マシンのモデル番号を反対側のアイコンに解決したいと考えています。AirDropそれはどのように行うのですか?

4

3 に答える 3

5
  1. Mac App Store セーフ

モデル識別子をアイコン名に手動でマップしてから、例を使用します

[[NSWorkspace sharedWorkspace] iconForFileType:@"com.apple.macbookair"];

また

 [NSImage imageNamed:NSImageNameComputer]

imageNamed が提供するよりも高い解像度が必要な場合

  OSType code = UTGetOSTypeFromString((CFStringRef)CFSTR("root"));
  NSImage *computer = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(code)];

「root」文字列は、IconsCore.h ヘッダー ファイル (kComputer) からのものです。

この plist をコピーして識別子を取得します (アプリ サンドボックスからアクセスしないでください)。

/System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes.plist

  1. Mac App Store は安全ではありません

プライベート フレームワーク SPSupport.Framework をバイナリにリンクする フレームワーク検索パス変数を追加する

$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks

次のインターフェイスをプロジェクトに追加します

#import <Cocoa/Cocoa.h>

@interface SPDocument : NSDocument

- (NSImage *)modelIcon;
- (id)computerName;
- (id)serialNumber;
- (id)modelName;

@end

コードを呼び出します。

  SPDocument *document = [[SPDocument alloc] init];
  NSImage *icon = [document modelIcon];
  1. 最も難しい方法

このプライベート関数を使用して CoreFoundation ダンスを把握します (このコードは図であり、正しい型、パラメーターの数を見つけて適切に解放します)

  output = _LSCreateDeviceTypeIdentifierWithModelCode((CFStringRef)@"MacBookPro6,2");
  NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType: output];

編集: オプション番号1、3(特定のモデルのアイコン)が必要であることに気付きました。これと戦うGL。

EDIT2 メソッド 3 が追加されました。順番を変えて1番下に追加。

EDIT3 カラー バージョンの新しい UTI com.apple.macbook-retina-silver com.apple.device-model-code MacBook8,1@ECOLOR=225,225,223

com.apple.macbook-retina-gold com.apple.device-model-code MacBook8,1@ECOLOR=235,215,191

com.apple.macbook-retina-space-gray com.apple.device-model-code MacBook8,1@ECOLOR=155,158,159 MacBook8,1@ECOLOR=157,157,160

NSImage *image =[[NSWorkspace sharedWorkspace] iconForFileType:@"com.apple.macbook-retina-gold"];

モデル番号/識別子を取得する方法 (sysctl hw.model は system_profiler に置き換えられました)?

NSPipe *outputPipe = [NSPipe pipe];
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/sbin/system_profiler"];
[task setArguments:@[@"SPHardwareDataType"]];
[task setStandardOutput:outputPipe];
[task launch];
[task waitUntilExit];
NSData *outputData = [[outputPipe fileHandleForReading] readDataToEndOfFile];
NSString *hardware = [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];

モデル識別子またはプロパティリストのシリアル化を解析します

于 2015-09-03T11:09:52.287 に答える
1

これは Swift でのソリューションですが、プライベート API を使用しているため、文書化されていない変更や App Store での拒否を受ける可能性があることに注意してください。

struct MachineAttributes {

    let privateFrameworksURL = "/System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes.plist"

    var model: String?

    var attributes: [String:AnyObject]?

    var iconPath: String?

    init() {
        self.model = getModel()
        self.attributes = getAttributes()
        self.iconPath = getIconPath()
    }

    init(model: String) {
        self.model = model
        self.attributes = getAttributes()
        self.iconPath = getIconPath()
    }

    private func getModel() -> String? {
        let service: io_service_t = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
        let cfstr = "model" as CFString
        if let model = IORegistryEntryCreateCFProperty(service, cfstr, kCFAllocatorDefault, 0).takeUnretainedValue() as? NSData {
            if let nsstr = NSString(CString: UnsafePointer<Int8>(model.bytes), encoding: NSUTF8StringEncoding) {
                return String(nsstr)
            }
        }
        return nil
    }

    private func getAttributes() -> [String:AnyObject]? {
        if let dict = NSDictionary(contentsOfFile: privateFrameworksURL) as? [String:AnyObject],
            let id = model,
            let result = dict[id] as? [String:AnyObject] {
                return result
        }
        return nil
    }

    private func getIconPath() -> String? {
        if let attr = self.attributes, let path = attr["hardwareImageName"] as? String {
            return path
        }
        return nil
    }

}

モデルがわからない場合:

let myMachine = MachineAttributes()
if let model = myMachine.model {
    print(model)
}
if let iconPath = myMachine.iconPath {
    print(iconPath)
}

MacBookPro9,2

/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/com.apple.macbookpro-15-unibody.icns

モデルがわかっている場合、または別のモデルを使用したい場合:

let myNamedMachine = MachineAttributes(model: "iMac14,2")
if let iconPath = myNamedMachine.iconPath {
    print(iconPath)
}

/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/com.apple.imac-unibody-27-no-optical.icns

于 2015-09-03T16:45:36.850 に答える