compiles again but that's about it

This commit is contained in:
Casey Fleser 2022-05-20 05:31:45 -05:00
parent 61fe44e6df
commit b64dc063f6
12 changed files with 120 additions and 115 deletions

View file

@ -170,6 +170,7 @@
developmentRegion = English; developmentRegion = English;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
English,
en, en,
Base, Base,
); );
@ -266,6 +267,7 @@
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_VERSION = 5.0;
}; };
name = Debug; name = Debug;
}; };
@ -301,6 +303,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.9; MACOSX_DEPLOYMENT_TARGET = 10.9;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_VERSION = 5.0;
}; };
name = Release; name = Release;
}; };

View file

@ -0,0 +1,8 @@
<?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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View file

@ -13,7 +13,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(aNotification: NSNotification) { func applicationDidFinishLaunching(aNotification: NSNotification) {
} }
func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool { func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true return true
} }
} }

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS"> <document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10116"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
</dependencies> </dependencies>
<scenes> <scenes>
<!--Application--> <!--Application-->

View file

@ -17,8 +17,8 @@ class SimApp: OutlineProvider, PropertyProvider {
var minOSVersion : String? var minOSVersion : String?
var icon : NSImage? var icon : NSImage?
var hasValidPaths : Bool { return self.validatedBundlePath != nil || self.validatedSandboxPath != nil } var hasValidPaths : Bool { return self.validatedBundlePath != nil || self.validatedSandboxPath != nil }
var bundleURL : NSURL? { return self.validatedBundlePath.map { NSURL(fileURLWithPath: $0) } } var bundleURL : URL? { return self.validatedBundlePath.map { URL(fileURLWithPath: $0) } }
var sandboxURL : NSURL? { return self.validatedSandboxPath.map { NSURL(fileURLWithPath: $0) } } var sandboxURL : URL? { return self.validatedSandboxPath.map { URL(fileURLWithPath: $0) } }
private var validatedBundlePath : String? private var validatedBundlePath : String?
private var validatedSandboxPath : String? private var validatedSandboxPath : String?
@ -50,12 +50,12 @@ class SimApp: OutlineProvider, PropertyProvider {
self.loadInfoPlist() self.loadInfoPlist()
} }
func updateFromLastLaunchMapInfo(launchBundleInfo: [String : AnyObject]) { func updateFrom(launchBundleInfo: [String : AnyObject]) {
self.bundlePath = launchBundleInfo["BundleContainer"] as? String self.bundlePath = launchBundleInfo["BundleContainer"] as? String
self.sandboxPath = launchBundleInfo["Container"] as? String self.sandboxPath = launchBundleInfo["Container"] as? String
} }
func updateFromAppStateInfo(appStateInfo: [String : AnyObject]) { func updateFrom(appStateInfo: [String : AnyObject]) {
guard let compatInfo = appStateInfo["compatibilityInfo"] as? [String : AnyObject] else { return } guard let compatInfo = appStateInfo["compatibilityInfo"] as? [String : AnyObject] else { return }
self.bundlePath = compatInfo["bundlePath"] as? String self.bundlePath = compatInfo["bundlePath"] as? String
@ -64,16 +64,13 @@ class SimApp: OutlineProvider, PropertyProvider {
func refinePaths() { func refinePaths() {
guard let bundleURL = self.bundleURL else { return } guard let bundleURL = self.bundleURL else { return }
let fileMgr = NSFileManager.defaultManager() let fileMgr = FileManager.default
if let lastPathComponent = bundleURL.lastPathComponent where !lastPathComponent.containsString(".app") { if bundleURL.lastPathComponent.contains("app") == true {
if let dirEnumerator = fileMgr.enumeratorAtURL(bundleURL, includingPropertiesForKeys: nil, options: [ .SkipsSubdirectoryDescendants, .SkipsHiddenFiles ], errorHandler: nil) { if let dirEnumerator = fileMgr.enumerator(at: bundleURL, includingPropertiesForKeys: nil, options: [ .skipsSubdirectoryDescendants, .skipsHiddenFiles ]) {
let dirURLs = dirEnumerator.allObjects.flatMap { $0 as? NSURL }
for appURL in dirEnumerator.allObjects.compactMap({ $0 as? URL}) {
for appURL in dirURLs { if appURL.lastPathComponent.contains(".app") {
guard let lastPathComponent = appURL.lastPathComponent else { continue }
if lastPathComponent.containsString(".app") {
self.validatedBundlePath = appURL.path self.validatedBundlePath = appURL.path
break break
} }
@ -84,9 +81,9 @@ class SimApp: OutlineProvider, PropertyProvider {
func loadInfoPlist() { func loadInfoPlist() {
guard let bundleURL = self.bundleURL else { return } guard let bundleURL = self.bundleURL else { return }
let infoPlistURL = bundleURL.URLByAppendingPathComponent("Info.plist") let infoPlistURL = bundleURL.appendingPathComponent("Info.plist")
if let plistInfo = NSPropertyListSerialization.propertyListWithURL(infoPlistURL) { if let plistInfo = PropertyListSerialization.propertyListWithURL(infoPlistURL) {
self.bundleName = plistInfo[String(kCFBundleNameKey)] as? String ?? "" self.bundleName = plistInfo[String(kCFBundleNameKey)] as? String ?? ""
self.displayName = plistInfo["CFBundleDisplayName"] as? String ?? "" self.displayName = plistInfo["CFBundleDisplayName"] as? String ?? ""
self.shortVersion = plistInfo["CFBundleShortVersionString"] as? String ?? "" self.shortVersion = plistInfo["CFBundleShortVersionString"] as? String ?? ""
@ -101,7 +98,7 @@ class SimApp: OutlineProvider, PropertyProvider {
let primaryIconValue = bundleIcons["CFBundlePrimaryIcon"].flatMap { item -> [String : AnyObject]? in let primaryIconValue = bundleIcons["CFBundlePrimaryIcon"].flatMap { item -> [String : AnyObject]? in
switch item { switch item {
case let dict as [String : AnyObject]: return dict case let dict as [String : AnyObject]: return dict
case let str as String: return ["CFBundleIconFiles" : [str]] case let str as String: return ["CFBundleIconFiles" : [str]] as [String : AnyObject]
default: return nil default: return nil
} }
} }
@ -109,12 +106,11 @@ class SimApp: OutlineProvider, PropertyProvider {
if let primaryIcon = primaryIconValue { if let primaryIcon = primaryIconValue {
if let bundleIconFiles = primaryIcon["CFBundleIconFiles"] as? [String] { if let bundleIconFiles = primaryIcon["CFBundleIconFiles"] as? [String] {
for iconName in bundleIconFiles { for iconName in bundleIconFiles {
var iconURL = bundleURL.URLByAppendingPathComponent(iconName) var iconURL = bundleURL.appendingPathComponent(iconName)
let icon2XURL = bundleURL.URLByAppendingPathComponent("\(iconName)@2x.png") let icon2XURL = bundleURL.appendingPathComponent("\(iconName)@2x.png")
let missingExt = iconURL.pathExtension.map({ return $0.isEmpty }) ?? true
if missingExt { if iconURL.pathExtension.isEmpty {
iconURL = iconURL.URLByAppendingPathExtension("png") iconURL = iconURL.appendingPathComponent("png")
} }
// .car files not yet working :/ // .car files not yet working :/
@ -143,13 +139,13 @@ class SimApp: OutlineProvider, PropertyProvider {
// } // }
// } // }
// else { // else {
if let icon = NSImage(contentsOfURL: iconURL) { if let icon = NSImage(contentsOf: iconURL) {
if self.icon?.size.width ?? 0 < icon.size.width { if self.icon?.size.width ?? 0 < icon.size.width {
self.icon = icon self.icon = icon
} }
} }
if let icon = NSImage(contentsOfURL: icon2XURL) { if let icon = NSImage(contentsOf: icon2XURL) {
if self.icon?.size.width ?? 0 < icon.size.width { if self.icon?.size.width ?? 0 < icon.size.width {
self.icon = icon self.icon = icon
} }
@ -172,7 +168,7 @@ class SimApp: OutlineProvider, PropertyProvider {
var outlineImage : NSImage? { return self.icon } var outlineImage : NSImage? { return self.icon }
var childCount : Int { return 0 } var childCount : Int { return 0 }
func childAtIndex(index: Int) -> OutlineProvider? { func childAt(index: Int) -> OutlineProvider? {
return nil return nil
} }

View file

@ -12,13 +12,13 @@ class SimDevice: OutlineProvider, PropertyProvider {
let name : String let name : String
let type : String let type : String
let udid : String let udid : String
let baseURL : NSURL let baseURL : URL
var platformName = "Unknown" var platformName = "Unknown"
var platformVersion = "" var platformVersion = ""
var platformBuild = "" var platformBuild = ""
var apps = [SimApp]() var apps = [SimApp]()
init(name: String, type: String, udid: String, baseURL: NSURL) { init(name: String, type: String, udid: String, baseURL: URL) {
self.name = name self.name = name
self.type = type self.type = type
self.udid = udid self.udid = udid
@ -39,12 +39,12 @@ class SimDevice: OutlineProvider, PropertyProvider {
for app in self.apps { for app in self.apps {
app.completeScan() app.completeScan()
} }
self.apps.sortInPlace { $0.displayName < $1.displayName } self.apps.sort(by: { $0.displayName < $1.displayName })
} }
func gatherBuildInfo() { func gatherBuildInfo() {
let buildInfoURL = self.baseURL.URLByAppendingPathComponent("data/Library/MobileInstallation/LastBuildInfo.plist") let buildInfoURL = self.baseURL.appendingPathComponent("data/Library/MobileInstallation/LastBuildInfo.plist")
guard let buildInfo = NSPropertyListSerialization.propertyListWithURL(buildInfoURL) else { return } guard let buildInfo = PropertyListSerialization.propertyListWithURL(buildInfoURL) else { return }
self.platformVersion = buildInfo["ProductVersion"] as? String ?? "" self.platformVersion = buildInfo["ProductVersion"] as? String ?? ""
self.platformBuild = buildInfo["ProductBuildVersion"] as? String ?? "" self.platformBuild = buildInfo["ProductBuildVersion"] as? String ?? ""
@ -52,30 +52,30 @@ class SimDevice: OutlineProvider, PropertyProvider {
// LastLaunchServicesMap.plist seems to be the most reliable location to gather app info // LastLaunchServicesMap.plist seems to be the most reliable location to gather app info
func gatherAppInfoFromLastLaunchMap() { func gatherAppInfoFromLastLaunchMap() {
let launchMapInfoURL = self.baseURL.URLByAppendingPathComponent("data/Library/MobileInstallation/LastLaunchServicesMap.plist") let launchMapInfoURL = self.baseURL.appendingPathComponent("data/Library/MobileInstallation/LastLaunchServicesMap.plist")
guard let launchInfo = NSPropertyListSerialization.propertyListWithURL(launchMapInfoURL) else { return } guard let launchInfo = PropertyListSerialization.propertyListWithURL(launchMapInfoURL) else { return }
guard let userInfo = launchInfo["User"] as? [String : AnyObject] else { return } guard let userInfo = launchInfo["User"] as? [String : AnyObject] else { return }
for (bundleID, bundleInfo) in userInfo { for (bundleID, bundleInfo) in userInfo {
guard let bundleInfo = bundleInfo as? [String : AnyObject] else { continue } guard let bundleInfo = bundleInfo as? [String : AnyObject] else { continue }
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) }) let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
simApp.updateFromLastLaunchMapInfo(bundleInfo) simApp.updateFrom(launchBundleInfo: bundleInfo)
} }
} }
// applicationState.plist sometimes has info that LastLaunchServicesMap.plist doesn't // applicationState.plist sometimes has info that LastLaunchServicesMap.plist doesn't
func gatherAppInfoFromAppState() { func gatherAppInfoFromAppState() {
for pathComponent in ["data/Library/FrontBoard/applicationState.plist", "data/Library/BackBoard/applicationState.plist"] { for pathComponent in ["data/Library/FrontBoard/applicationState.plist", "data/Library/BackBoard/applicationState.plist"] {
let appStateInfoURL = self.baseURL.URLByAppendingPathComponent(pathComponent) let appStateInfoURL = self.baseURL.appendingPathComponent(pathComponent)
guard let stateInfo = NSPropertyListSerialization.propertyListWithURL(appStateInfoURL) else { continue } guard let stateInfo = PropertyListSerialization.propertyListWithURL(appStateInfoURL) else { continue }
for (bundleID, bundleInfo) in stateInfo { for (bundleID, bundleInfo) in stateInfo {
if !bundleID.containsString("com.apple") { if !bundleID.contains("com.apple") {
guard let bundleInfo = bundleInfo as? [String : AnyObject] else { continue } guard let bundleInfo = bundleInfo as? [String : AnyObject] else { continue }
let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) }) let simApp = self.apps.match({ $0.bundleID == bundleID }, orMake: { SimApp(bundleID: bundleID) })
simApp.updateFromAppStateInfo(bundleInfo) simApp.updateFrom(appStateInfo: bundleInfo)
} }
} }
} }
@ -84,26 +84,26 @@ class SimDevice: OutlineProvider, PropertyProvider {
// mobile_installation.log.0 is my least favorite, most fragile way to scan for app installations // mobile_installation.log.0 is my least favorite, most fragile way to scan for app installations
// try this after everything else // try this after everything else
func gatherAppInfoFromInstallLogs() { func gatherAppInfoFromInstallLogs() {
let installLogURL = self.baseURL.URLByAppendingPathComponent("data/Library/Logs/MobileInstallation/mobile_installation.log.0") let installLogURL = self.baseURL.appendingPathComponent("data/Library/Logs/MobileInstallation/mobile_installation.log.0")
if let installLog = try? String(contentsOfURL: installLogURL) { if let installLog = try? String(contentsOf: installLogURL) {
let lines = installLog.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) let lines = installLog.components(separatedBy: .newlines)
for line in lines.reverse() { for line in lines.reversed() {
if !line.containsString("com.apple") { if !line.contains("com.apple") {
if line.containsString("makeContainerLiveReplacingContainer") { if line.contains("makeContainerLiveReplacingContainer") {
self.extractBundleLocationFromLogEntry(line) self.extractBundleLocationFrom(logEntry: line)
} }
if line.containsString("_refreshUUIDForContainer") { if line.contains("_refreshUUIDForContainer") {
self.extractSandboxLocationFromLogEntry(line) self.extractSandboxLocationFrom(logEntry: line)
} }
} }
} }
} }
} }
func extractBundleLocationFromLogEntry(line: String) { func extractBundleLocationFrom(logEntry: String) {
let logComponents = line.componentsSeparatedByString(" ") let logComponents = logEntry.split(separator: (" ")).map({ String($0) })
if let bundlePath = logComponents.last { if let bundlePath = logComponents.last {
if let bundleID = logComponents[safe: logComponents.count - 3] { if let bundleID = logComponents[safe: logComponents.count - 3] {
@ -114,8 +114,8 @@ class SimDevice: OutlineProvider, PropertyProvider {
} }
} }
func extractSandboxLocationFromLogEntry(line: String) { func extractSandboxLocationFrom(logEntry: String) {
let logComponents = line.componentsSeparatedByString(" ") let logComponents = logEntry.split(separator: (" ")).map({ String($0) })
if let sandboxPath = logComponents.last { if let sandboxPath = logComponents.last {
if let bundleID = logComponents[safe: logComponents.count - 5] { if let bundleID = logComponents[safe: logComponents.count - 5] {
@ -132,7 +132,7 @@ class SimDevice: OutlineProvider, PropertyProvider {
var outlineImage : NSImage? { return nil } var outlineImage : NSImage? { return nil }
var childCount : Int { return self.apps.count } var childCount : Int { return self.apps.count }
func childAtIndex(index: Int) -> OutlineProvider? { func childAt(index: Int) -> OutlineProvider? {
return self.apps[index] return self.apps[index]
} }

View file

@ -18,18 +18,18 @@ class SimOSVersion: OutlineProvider {
func completeScan(platformName: String) { func completeScan(platformName: String) {
for device in self.devices { for device in self.devices {
device.completeScan(platformName) device.completeScan(platformName: platformName)
} }
self.devices.sortInPlace { $0.name < $1.name } self.devices.sort(by: { $0.name < $1.name })
} }
func updateWithDeviceInfo(deviceInfo: [String : AnyObject], baseURL: NSURL) { func updateWith(deviceInfo: [String : AnyObject], baseURL: URL) {
guard let deviceName = deviceInfo["name"] as? String else { return } guard let deviceName = deviceInfo["name"] as? String else { return }
guard let deviceUDID = deviceInfo["UDID"] as? String else { return } guard let deviceUDID = deviceInfo["UDID"] as? String else { return }
guard var deviceType = deviceInfo["deviceType"] as? String else { return } guard var deviceType = deviceInfo["deviceType"] as? String else { return }
deviceType = deviceType.stringByReplacingOccurrencesOfString("com.apple.CoreSimulator.SimDeviceType.", withString: "") deviceType = deviceType.replacingOccurrences(of: "com.apple.CoreSimulator.SimDeviceType.", with: "")
deviceType = deviceType.stringByReplacingOccurrencesOfString("-", withString: " ") deviceType = deviceType.replacingOccurrences(of: "-", with: " ")
self.devices.append(SimDevice(name: deviceName, type: deviceType, udid: deviceUDID, baseURL: baseURL)) self.devices.append(SimDevice(name: deviceName, type: deviceType, udid: deviceUDID, baseURL: baseURL))
} }
@ -40,7 +40,7 @@ class SimOSVersion: OutlineProvider {
var outlineImage : NSImage? { return nil } var outlineImage : NSImage? { return nil }
var childCount : Int { return self.devices.count } var childCount : Int { return self.devices.count }
func childAtIndex(index: Int) -> OutlineProvider? { func childAt(index: Int) -> OutlineProvider? {
return self.devices[index] return self.devices[index]
} }
} }

View file

@ -13,23 +13,21 @@ class SimPlatform: OutlineProvider {
var osVersions = [SimOSVersion]() var osVersions = [SimOSVersion]()
class func scan() -> [SimPlatform] { class func scan() -> [SimPlatform] {
let fileMgr = NSFileManager.defaultManager() let fileMgr = FileManager.default
var platforms = [SimPlatform]() var platforms = [SimPlatform]()
if let libraryURL = fileMgr.URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask).first { if let libraryURL = fileMgr.urls(for: .libraryDirectory, in: .userDomainMask).first {
let deviceURL = libraryURL.URLByAppendingPathComponent("Developer/CoreSimulator/Devices") let deviceURL = libraryURL.appendingPathComponent("Developer/CoreSimulator/Devices")
if let dirEnumerator = fileMgr.enumeratorAtURL(deviceURL, includingPropertiesForKeys: nil, options: [ .SkipsSubdirectoryDescendants, .SkipsHiddenFiles ], errorHandler: nil) { if let dirEnumerator = fileMgr.enumerator(at: deviceURL, includingPropertiesForKeys: nil, options: [ .skipsSubdirectoryDescendants, .skipsHiddenFiles ], errorHandler: nil) {
let dirURLs = dirEnumerator.allObjects.flatMap { $0 as? NSURL } for baseURL in dirEnumerator.allObjects.compactMap({ $0 as? URL }) {
let deviceURL = baseURL.appendingPathComponent("device.plist")
for baseURL in dirURLs { guard let deviceInfo = PropertyListSerialization.propertyListWithURL(deviceURL) else { continue }
let deviceURL = baseURL.URLByAppendingPathComponent("device.plist")
guard let deviceInfo = NSPropertyListSerialization.propertyListWithURL(deviceURL) else { continue }
guard let runtime = deviceInfo["runtime"] as? String else { continue } guard let runtime = deviceInfo["runtime"] as? String else { continue }
let runtimeComponents = runtime.stringByReplacingOccurrencesOfString("com.apple.CoreSimulator.SimRuntime.", withString: "").componentsSeparatedByString("-") let runtimeComponents = runtime.replacingOccurrences(of: "com.apple.CoreSimulator.SimRuntime.", with: "").split(separator: "-").map({ String($0) })
if let platformName = runtimeComponents.first { if let platformName = runtimeComponents.first {
let platform = platforms.match({ $0.name == platformName }, orMake: { SimPlatform(runtimeComponents: runtimeComponents, deviceInfo: deviceInfo) }) let platform = platforms.match({ $0.name == platformName }, orMake: { SimPlatform(runtimeComponents: runtimeComponents, deviceInfo: deviceInfo) })
platform.updateWith(runtimeComponents, deviceInfo: deviceInfo, baseURL: baseURL) platform.updateWith(runtimeComponents, deviceInfo: deviceInfo, baseURL: baseURL)
} }
@ -41,7 +39,7 @@ class SimPlatform: OutlineProvider {
platform.completeScan() platform.completeScan()
} }
return platforms.sort { $0.name < $1.name } return platforms.sorted { $0.name < $1.name }
} }
init(runtimeComponents: [String], deviceInfo: [String : AnyObject]) { init(runtimeComponents: [String], deviceInfo: [String : AnyObject]) {
@ -50,16 +48,16 @@ class SimPlatform: OutlineProvider {
func completeScan() { func completeScan() {
for osVersion in self.osVersions { for osVersion in self.osVersions {
osVersion.completeScan(self.name) osVersion.completeScan(platformName: self.name)
} }
self.osVersions.sortInPlace { $0.name > $1.name } self.osVersions.sort(by: { $0.name > $1.name })
} }
func updateWith(runtimeComponents: [String], deviceInfo: [String : AnyObject], baseURL: NSURL) { func updateWith(_ runtimeComponents: [String], deviceInfo: [String : AnyObject], baseURL: URL) {
let versionID = "\(runtimeComponents[safe: 1] ?? "0").\(runtimeComponents[safe: 2] ?? "0")" let versionID = "\(runtimeComponents[safe: 1] ?? "0").\(runtimeComponents[safe: 2] ?? "0")"
let osVersion = self.osVersions.match({ $0.name == versionID }, orMake: { SimOSVersion(name: versionID, deviceInfo: deviceInfo) }) let osVersion = self.osVersions.match({ $0.name == versionID }, orMake: { SimOSVersion(name: versionID, deviceInfo: deviceInfo) })
osVersion.updateWithDeviceInfo(deviceInfo, baseURL: baseURL) osVersion.updateWith(deviceInfo: deviceInfo, baseURL: baseURL)
} }
// MARK: - OutlineProvider - // MARK: - OutlineProvider -
@ -68,7 +66,7 @@ class SimPlatform: OutlineProvider {
var outlineImage : NSImage? { return nil } var outlineImage : NSImage? { return nil }
var childCount : Int { return self.osVersions.count } var childCount : Int { return self.osVersions.count }
func childAtIndex(index: Int) -> OutlineProvider? { func childAt(index: Int) -> OutlineProvider? {
return self.osVersions[index] return self.osVersions[index]
} }
} }

View file

@ -10,11 +10,11 @@
import Foundation import Foundation
extension Array { extension Array {
mutating func match(predicate: (Element) -> Bool, orMake: () -> Element) -> Element { mutating func match(_ predicate: (Element) -> Bool, orMake: () -> Element) -> Element {
let element : Element let element : Element
if let index = self.indexOf(predicate) { if let match = self.first(where: predicate) {
element = self[index] element = match
} }
else { else {
element = orMake() element = orMake()
@ -25,27 +25,27 @@ extension Array {
} }
} }
extension CollectionType { extension Collection {
subscript (safe index: Index) -> Generator.Element? { subscript (safe index: Index) -> Iterator.Element? {
return indices.contains(index) ? self[index] : nil return indices.contains(index) ? self[index] : nil
} }
} }
extension String { extension String {
var validPath : Bool { return NSFileManager.defaultManager().fileExistsAtPath(self) } var validPath : Bool { return FileManager.default.fileExists(atPath: self) }
} }
extension NSURL { extension NSURL {
var validPath : Bool { return self.path.map { NSFileManager.defaultManager().fileExistsAtPath($0) } ?? false } var validPath : Bool { return self.path.map { FileManager.default.fileExists(atPath: $0) } ?? false }
} }
extension NSPropertyListSerialization { extension PropertyListSerialization {
class func propertyListWithURL(url: NSURL) -> [String : AnyObject]? { class func propertyListWithURL(_ url: URL) -> [String : AnyObject]? {
guard let plistData = NSData(contentsOfURL: url) else { return nil } guard let plistData = try? Data(contentsOf: url) else { return nil }
let plist : [String : AnyObject]? let plist : [String : AnyObject]?
do { do {
plist = try NSPropertyListSerialization.propertyListWithData(plistData, options: .Immutable, format: nil) as? [String : AnyObject] plist = try PropertyListSerialization.propertyList(from: plistData, options: [], format: nil) as? [String : AnyObject]
} catch { } catch {
plist = nil plist = nil
} }

View file

@ -11,7 +11,7 @@ import Cocoa
struct SimProperty { struct SimProperty {
enum Value { enum Value {
case Text(text: String) case Text(text: String)
case Location(url: NSURL) case Location(url: URL)
} }
let title : String let title : String
@ -40,7 +40,7 @@ class DetailController: NSViewController, NSTableViewDataSource, NSTableViewDele
@IBOutlet weak var imageView : NSImageView! @IBOutlet weak var imageView : NSImageView!
@IBOutlet weak var propertyTable : NSTableView! @IBOutlet weak var propertyTable : NSTableView!
let emptyProvider = EmptyProvider() let emptyProvider = EmptyProvider()
var selectedItem : AnyObject? { didSet { self.reload() } } var selectedItem : Any? { didSet { self.reload() } }
var selectedProvider : PropertyProvider { return (self.selectedItem as? PropertyProvider) ?? self.emptyProvider } var selectedProvider : PropertyProvider { return (self.selectedItem as? PropertyProvider) ?? self.emptyProvider }
override func viewDidLoad() { override func viewDidLoad() {
@ -57,33 +57,33 @@ class DetailController: NSViewController, NSTableViewDataSource, NSTableViewDele
// MARK: - NSTableViewDataSource - // MARK: - NSTableViewDataSource -
func numberOfRowsInTableView(tableView: NSTableView) -> Int { func numberOfRows(in tableView: NSTableView) -> Int {
return self.selectedProvider.properties.count ?? 0 return self.selectedProvider.properties.count
} }
// MARK: - NSTableViewDelegate - // MARK: - NSTableViewDelegate -
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? { func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let selectedProperty = self.selectedProvider.properties[row] let selectedProperty = self.selectedProvider.properties[row]
let columnIdentifier = tableColumn?.identifier ?? "" let columnIdentifier = tableColumn?.identifier ?? NSUserInterfaceItemIdentifier("")
let view : NSView? let view : NSView?
switch columnIdentifier { switch columnIdentifier.rawValue {
case "value": case "value":
switch selectedProperty.value { switch selectedProperty.value {
case .Text(let text): case .Text(let text):
view = tableView.makeViewWithIdentifier("PropertyValueCell", owner: self) view = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("PropertyValueCell"), owner: self)
(view as? NSTableCellView)?.textField?.stringValue = text (view as? NSTableCellView)?.textField?.stringValue = text
case .Location(let url): case .Location(let url):
view = tableView.makeViewWithIdentifier("PropertyActionCell", owner: self) view = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("PropertyActionCell"), owner: self)
if let actionCell = view as? ActionCell { if let actionCell = view as? ActionCell {
actionCell.action = { NSWorkspace.sharedWorkspace().activateFileViewerSelectingURLs([url]) } actionCell.action = { NSWorkspace.shared.activateFileViewerSelecting([url]) }
} }
} }
default: default:
view = tableView.makeViewWithIdentifier("PropertyTitleCell", owner: self) view = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("PropertyTitleCell"), owner: self)
(view as? NSTableCellView)?.textField?.stringValue = selectedProperty.title (view as? NSTableCellView)?.textField?.stringValue = selectedProperty.title
} }

View file

@ -9,10 +9,10 @@
import Cocoa import Cocoa
class DetailTableView: NSTableView { class DetailTableView: NSTableView {
override func drawGridInClipRect(clipRect: NSRect) { override func drawGrid(inClipRect: NSRect) {
let lastRowRect = self.rectOfRow(self.numberOfRows - 1) let lastRowRect = self.rect(ofRow: self.numberOfRows - 1)
let adjClipRect = NSRect(x: 0.0, y: 0.0, width: lastRowRect.width, height: lastRowRect.maxY) let adjClipRect = NSRect(x: 0.0, y: 0.0, width: lastRowRect.width, height: lastRowRect.maxY)
super.drawGridInClipRect(NSIntersectionRect(clipRect, adjClipRect)) super.drawGrid(inClipRect: NSIntersectionRect(inClipRect, adjClipRect))
} }
} }

View file

@ -13,7 +13,7 @@ protocol OutlineProvider: AnyObject {
var outlineImage : NSImage? { get } var outlineImage : NSImage? { get }
var childCount : Int { get } var childCount : Int { get }
func childAtIndex(index: Int) -> OutlineProvider? func childAt(index: Int) -> OutlineProvider?
} }
extension OutlineProvider { extension OutlineProvider {
@ -32,21 +32,21 @@ class SourceController: NSViewController, NSOutlineViewDataSource, NSOutlineView
// MARK: - NSOutlineViewDataSource - // MARK: - NSOutlineViewDataSource -
func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int { func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
return (item as? OutlineProvider)?.childCount ?? self.platforms.count return (item as? OutlineProvider)?.childCount ?? self.platforms.count
} }
func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject { func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
return (item as? OutlineProvider)?.childAtIndex(index) ?? self.platforms[index] return (item as? OutlineProvider)?.childAt(index: index) ?? self.platforms[index]
} }
func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool { func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
return (item as? OutlineProvider)?.expandable ?? (self.platforms.count > 0) return (item as? OutlineProvider)?.expandable ?? (self.platforms.count > 0)
} }
// MARK: - NSOutlineViewDelegate - // MARK: - NSOutlineViewDelegate -
func outlineView(outlineView: NSOutlineView, viewForTableColumn tableColumn: NSTableColumn?, item: AnyObject) -> NSView? { func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
var view : NSTableCellView? = nil var view : NSTableCellView? = nil
var title = "" var title = ""
var image : NSImage? = nil var image : NSImage? = nil
@ -56,7 +56,7 @@ class SourceController: NSViewController, NSOutlineViewDataSource, NSOutlineView
image = outlineProvider.outlineImage image = outlineProvider.outlineImage
} }
if let outlineCell = outlineView.makeViewWithIdentifier(image != nil ? "ImageCell" : "TextCell", owner: self) as? NSTableCellView { if let outlineCell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(image != nil ? "ImageCell" : "TextCell"), owner: self) as? NSTableCellView {
outlineCell.textField?.stringValue = title outlineCell.textField?.stringValue = title
outlineCell.imageView?.image = image outlineCell.imageView?.image = image
view = outlineCell view = outlineCell
@ -65,17 +65,17 @@ class SourceController: NSViewController, NSOutlineViewDataSource, NSOutlineView
return view return view
} }
func outlineView(outlineView: NSOutlineView, heightOfRowByItem item: AnyObject) -> CGFloat { func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {
return (item as? OutlineProvider)?.outlineImage != nil ? 24.0 : 20.0 return (item as? OutlineProvider)?.outlineImage != nil ? 24.0 : 20.0
} }
func outlineViewSelectionDidChange(notification: NSNotification) { func outlineViewSelectionDidChange(_ notification: Notification) {
if let thing = (self.parentViewController as? NSSplitViewController)?.splitViewItems[safe: 1]?.viewController as? DetailController { if let thing = (self.parent as? NSSplitViewController)?.splitViewItems[safe: 1]?.viewController as? DetailController {
var selectedItem : AnyObject? = nil var selectedItem : Any? = nil
let row = self.outlineView.selectedRow let row = self.outlineView.selectedRow
if row != NSNotFound { if row != NSNotFound {
selectedItem = self.outlineView.itemAtRow(row) selectedItem = self.outlineView.item(atRow: row)
} }
thing.selectedItem = selectedItem thing.selectedItem = selectedItem
@ -84,7 +84,7 @@ class SourceController: NSViewController, NSOutlineViewDataSource, NSOutlineView
// MARK: - Interaction - // MARK: - Interaction -
@IBAction func rescan(sender: AnyObject?) { @IBAction func rescan(_ sender: AnyObject?) {
self.platforms = SimPlatform.scan() self.platforms = SimPlatform.scan()
self.outlineView.reloadData() self.outlineView.reloadData()
} }