From 6a34aaae16be06cd5bc71bd53c7ff9d876b2b997 Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Fri, 29 Dec 2017 21:44:38 +0200 Subject: [PATCH 1/7] Turning off bitcode not supported by macos --- Motivation.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Motivation.xcodeproj/project.pbxproj b/Motivation.xcodeproj/project.pbxproj index f9c8436..0168fe8 100644 --- a/Motivation.xcodeproj/project.pbxproj +++ b/Motivation.xcodeproj/project.pbxproj @@ -280,7 +280,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -324,7 +324,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_BITCODE = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; From ce976df46fe4c0032f23c58c424c1e74446711d3 Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Fri, 29 Dec 2017 21:45:42 +0200 Subject: [PATCH 2/7] Fixing selectors --- Motivation/AgeView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Motivation/AgeView.swift b/Motivation/AgeView.swift index e983ab3..9db8961 100644 --- a/Motivation/AgeView.swift +++ b/Motivation/AgeView.swift @@ -116,8 +116,8 @@ class AgeView: ScreenSaverView { ]) // Listen for configuration changes - NSNotificationCenter.defaultCenter().addObserver(self, selector: "motivationLevelDidChange:", name: Preferences.motivationLevelDidChangeNotificationName, object: nil) - NSNotificationCenter.defaultCenter().addObserver(self, selector: "birthdayDidChange:", name: Preferences.birthdayDidChangeNotificationName, object: nil) + NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(AgeView.motivationLevelDidChange(_:)), name: Preferences.motivationLevelDidChangeNotificationName, object: nil) + NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(AgeView.birthdayDidChange(_:)), name: Preferences.birthdayDidChangeNotificationName, object: nil) } /// Age calculation From cb261345239f0a4bfe5a79a6bcf3420cbe1f2822 Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Fri, 29 Dec 2017 21:49:41 +0200 Subject: [PATCH 3/7] Converting to swift 3 --- Motivation.xcodeproj/project.pbxproj | 3 + Motivation/AgeView.swift | 78 +++++++++---------- .../ConfigurationWindowController.swift | 12 +-- Motivation/NSCalendar+Motivation.swift | 28 +++---- Motivation/Preferences.swift | 32 ++++---- 5 files changed, 78 insertions(+), 75 deletions(-) diff --git a/Motivation.xcodeproj/project.pbxproj b/Motivation.xcodeproj/project.pbxproj index 0168fe8..4549342 100644 --- a/Motivation.xcodeproj/project.pbxproj +++ b/Motivation.xcodeproj/project.pbxproj @@ -176,6 +176,7 @@ TargetAttributes = { 21F222251B73B5AC00B9A11A = { CreatedOnToolsVersion = 6.4; + LastSwiftMigration = 0830; }; 21F222391B73B60100B9A11A = { CreatedOnToolsVersion = 6.4; @@ -354,6 +355,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.motiviation; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; WRAPPER_EXTENSION = saver; }; name = Debug; @@ -370,6 +372,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.motiviation; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; WRAPPER_EXTENSION = saver; }; name = Release; diff --git a/Motivation/AgeView.swift b/Motivation/AgeView.swift index 9db8961..e5bdd1f 100644 --- a/Motivation/AgeView.swift +++ b/Motivation/AgeView.swift @@ -13,25 +13,25 @@ class AgeView: ScreenSaverView { // MARK: - Properties - private let textLabel: NSTextField = { + fileprivate let textLabel: NSTextField = { let label = NSTextField() label.translatesAutoresizingMaskIntoConstraints = false - label.editable = false + label.isEditable = false label.drawsBackground = false - label.bordered = false - label.bezeled = false - label.selectable = false - label.textColor = .whiteColor() + label.isBordered = false + label.isBezeled = false + label.isSelectable = false + label.textColor = .white return label }() - private lazy var configurationWindowController: NSWindowController = { + fileprivate lazy var configurationWindowController: NSWindowController = { return ConfigurationWindowController() }() - private var motivationLevel: MotivationLevel + fileprivate var motivationLevel: MotivationLevel - private var birthday: NSDate? { + fileprivate var birthday: Date? { didSet { updateFont() } @@ -41,7 +41,7 @@ class AgeView: ScreenSaverView { // MARK: - Initializers convenience init() { - self.init(frame: CGRectZero, isPreview: false) + self.init(frame: CGRect.zero, isPreview: false) } override init!(frame: NSRect, isPreview: Bool) { @@ -57,22 +57,22 @@ class AgeView: ScreenSaverView { } deinit { - NSNotificationCenter.defaultCenter().removeObserver(self) + NotificationCenter.default.removeObserver(self) } // MARK: - NSView - override func drawRect(rect: NSRect) { - let backgroundColor: NSColor = .blackColor() + override func draw(_ rect: NSRect) { + let backgroundColor: NSColor = .black backgroundColor.setFill() - NSBezierPath.fillRect(bounds) + NSBezierPath.fill(bounds) } // If the screen saver changes size, update the font - override func resizeWithOldSuperviewSize(oldSize: NSSize) { - super.resizeWithOldSuperviewSize(oldSize) + override func resize(withOldSuperviewSize oldSize: NSSize) { + super.resize(withOldSuperviewSize: oldSize) updateFont() } @@ -101,66 +101,66 @@ class AgeView: ScreenSaverView { // MARK: - Private /// Shared initializer - private func initialize() { + fileprivate func initialize() { // Set animation time interval animationTimeInterval = 1 / 30 // Recall preferences - birthday = Preferences().birthday + birthday = Preferences().birthday as! Date // Setup the label addSubview(textLabel) addConstraints([ - NSLayoutConstraint(item: textLabel, attribute: .CenterX, relatedBy: .Equal, toItem: self, attribute: .CenterX, multiplier: 1, constant: 0), - NSLayoutConstraint(item: textLabel, attribute: .CenterY, relatedBy: .Equal, toItem: self, attribute: .CenterY, multiplier: 1, constant: 0) + NSLayoutConstraint(item: textLabel, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0), + NSLayoutConstraint(item: textLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0) ]) // Listen for configuration changes - NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(AgeView.motivationLevelDidChange(_:)), name: Preferences.motivationLevelDidChangeNotificationName, object: nil) - NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(AgeView.birthdayDidChange(_:)), name: Preferences.birthdayDidChangeNotificationName, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(AgeView.motivationLevelDidChange(_:)), name: NSNotification.Name(rawValue: Preferences.motivationLevelDidChangeNotificationName), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(AgeView.birthdayDidChange(_:)), name: NSNotification.Name(rawValue: Preferences.birthdayDidChangeNotificationName), object: nil) } /// Age calculation - private func ageForBirthday(birthday: NSDate) -> Double { - let calendar = NSCalendar.currentCalendar() - let now = NSDate() + fileprivate func ageForBirthday(_ birthday: Date) -> Double { + let calendar = Calendar.current + let now = Date() // An age is defined as the number of years you've been alive plus the number of days, seconds, and nanoseconds // you've been alive out of that many units in the current year. - let components = calendar.components([NSCalendarUnit.Year, NSCalendarUnit.Day, NSCalendarUnit.Second, NSCalendarUnit.Nanosecond], fromDate: birthday, toDate: now, options: []) + let components = (calendar as NSCalendar).components([NSCalendar.Unit.year, NSCalendar.Unit.day, NSCalendar.Unit.second, NSCalendar.Unit.nanosecond], from: birthday, to: now, options: []) // We calculate these every time since the values can change when you cross a boundary. Things are too // complicated to try to figure out when that is and cache them. NSCalendar is made for this. let daysInYear = Double(calendar.daysInYear(now) ?? 365) - let hoursInDay = Double(calendar.rangeOfUnit(NSCalendarUnit.Hour, inUnit: NSCalendarUnit.Day, forDate: now).length) - let minutesInHour = Double(calendar.rangeOfUnit(NSCalendarUnit.Minute, inUnit: NSCalendarUnit.Hour, forDate: now).length) - let secondsInMinute = Double(calendar.rangeOfUnit(NSCalendarUnit.Second, inUnit: NSCalendarUnit.Minute, forDate: now).length) - let nanosecondsInSecond = Double(calendar.rangeOfUnit(NSCalendarUnit.Nanosecond, inUnit: NSCalendarUnit.Second, forDate: now).length) + let hoursInDay = Double((calendar as NSCalendar).range(of: NSCalendar.Unit.hour, in: NSCalendar.Unit.day, for: now).length) + let minutesInHour = Double((calendar as NSCalendar).range(of: NSCalendar.Unit.minute, in: NSCalendar.Unit.hour, for: now).length) + let secondsInMinute = Double((calendar as NSCalendar).range(of: NSCalendar.Unit.second, in: NSCalendar.Unit.minute, for: now).length) + let nanosecondsInSecond = Double((calendar as NSCalendar).range(of: NSCalendar.Unit.nanosecond, in: NSCalendar.Unit.second, for: now).length) // Now that we have all of the values, assembling them is easy. We don't get minutes and hours from the calendar // since it will overflow nicely to seconds. We need days and years since the number of days in a year changes // more frequently. This will handle leap seconds, days, and years. - let seconds = Double(components.second) + (Double(components.nanosecond) / nanosecondsInSecond) + let seconds = Double(components.second!) + (Double(components.nanosecond!) / nanosecondsInSecond) let minutes = seconds / secondsInMinute let hours = minutes / minutesInHour - let days = Double(components.day) + (hours / hoursInDay) + let days = Double(components.day!) + (hours / hoursInDay) let years = Double(components.year) + (days / daysInYear) return years } /// Motiviation level changed - @objc private func motivationLevelDidChange(notification: NSNotification?) { + @objc fileprivate func motivationLevelDidChange(_ notification: Notification?) { motivationLevel = Preferences().motivationLevel } /// Birthday changed - @objc private func birthdayDidChange(notification: NSNotification?) { - birthday = Preferences().birthday + @objc fileprivate func birthdayDidChange(_ notification: Notification?) { + birthday = Preferences().birthday as! Date } /// Update the font for the current size - private func updateFont() { + fileprivate func updateFont() { if birthday != nil { textLabel.font = fontWithSize(bounds.width / 10) } else { @@ -169,17 +169,17 @@ class AgeView: ScreenSaverView { } /// Get a font - private func fontWithSize(fontSize: CGFloat, monospace: Bool = true) -> NSFont { + fileprivate func fontWithSize(_ fontSize: CGFloat, monospace: Bool = true) -> NSFont { let font: NSFont if #available(OSX 10.11, *) { - font = .systemFontOfSize(fontSize, weight: NSFontWeightThin) + font = .systemFont(ofSize: fontSize, weight: NSFontWeightThin) } else { font = NSFont(name: "HelveticaNeue-Thin", size: fontSize)! } let fontDescriptor: NSFontDescriptor if monospace { - fontDescriptor = font.fontDescriptor.fontDescriptorByAddingAttributes([ + fontDescriptor = font.fontDescriptor.addingAttributes([ NSFontFeatureSettingsAttribute: [ [ NSFontFeatureTypeIdentifierKey: kNumberSpacingType, diff --git a/Motivation/ConfigurationWindowController.swift b/Motivation/ConfigurationWindowController.swift index 06bd6a7..cf12b14 100644 --- a/Motivation/ConfigurationWindowController.swift +++ b/Motivation/ConfigurationWindowController.swift @@ -27,23 +27,23 @@ class ConfigurationWindowController: NSWindowController { super.windowDidLoad() switch Preferences().motivationLevel { - case .Light: lightRadio.state = NSOnState - case .Moderate: moderateRadio.state = NSOnState - case .Terrifying: terrifyingRadio.state = NSOnState + case .light: lightRadio.state = NSOnState + case .moderate: moderateRadio.state = NSOnState + case .terrifying: terrifyingRadio.state = NSOnState } } // MARK: - Action - @IBAction func close(sender: AnyObject?) { + @IBAction func close(_ sender: AnyObject?) { if let window = window { window.sheetParent?.endSheet(window) } } - @IBAction func levelDidChange(sender: AnyObject?) { - guard let button = sender as? NSButton, level = MotivationLevel(rawValue: UInt(button.tag)) else { return } + @IBAction func levelDidChange(_ sender: AnyObject?) { + guard let button = sender as? NSButton, let level = MotivationLevel(rawValue: UInt(button.tag)) else { return } Preferences().motivationLevel = level } } diff --git a/Motivation/NSCalendar+Motivation.swift b/Motivation/NSCalendar+Motivation.swift index 1cbe0b1..ae91fe0 100644 --- a/Motivation/NSCalendar+Motivation.swift +++ b/Motivation/NSCalendar+Motivation.swift @@ -8,27 +8,27 @@ import Foundation -extension NSCalendar { - func daysInYear(date: NSDate = NSDate()) -> Int? { - let year = components([NSCalendarUnit.Year], fromDate: date).year - return daysInYear(year) +extension Calendar { + func daysInYear(_ date: Date = Date()) -> Int? { + let year = dateComponents([NSCalendar.Unit.year], from: date).year + return daysInYear(year!) } - func daysInYear(year: Int) -> Int? { - guard let begin = lastDayOfYear(year - 1), end = lastDayOfYear(year) else { return nil } - return components([NSCalendarUnit.Day], fromDate: begin, toDate: end, options: []).day + func daysInYear(_ year: Int) -> Int? { + guard let begin = lastDayOfYear(year - 1), let end = lastDayOfYear(year) else { return nil } + return dateComponents([NSCalendar.Unit.day], from: begin, to: end, options: []).day } - func lastDayOfYear(year: Int) -> NSDate? { - let components = NSDateComponents() + func lastDayOfYear(_ year: Int) -> Date? { + var components = DateComponents() components.year = year - guard let years = dateFromComponents(components) else { return nil } + guard let years = date(from: components) else { return nil } - components.month = rangeOfUnit(NSCalendarUnit.Month, inUnit: NSCalendarUnit.Year, forDate: years).length - guard let months = dateFromComponents(components) else { return nil } + components.month = range(of: NSCalendar.Unit.month, in: NSCalendar.Unit.year, for: years).length + guard let months = date(from: components) else { return nil } - components.day = rangeOfUnit(NSCalendarUnit.Day, inUnit: NSCalendarUnit.Month, forDate: months).length + components.day = range(of: NSCalendar.Unit.day, in: NSCalendar.Unit.month, for: months).length - return dateFromComponents(components) + return date(from: components) } } diff --git a/Motivation/Preferences.swift b/Motivation/Preferences.swift index 9f5b899..e4947e4 100644 --- a/Motivation/Preferences.swift +++ b/Motivation/Preferences.swift @@ -10,13 +10,13 @@ import Foundation import ScreenSaver enum MotivationLevel: UInt { - case Light, Moderate, Terrifying + case light, moderate, terrifying var decimalPlaces: UInt { switch self { - case Light: return 7 - case Moderate: return 8 - case Terrifying: return 9 + case .light: return 7 + case .moderate: return 8 + case .terrifying: return 9 } } } @@ -28,40 +28,40 @@ class Preferences: NSObject { static var birthdayDidChangeNotificationName = "Preferences.birthdayDidChangeNotification" static var motivationLevelDidChangeNotificationName = "Preferences.motivationLevelDidChangeNotification" - var birthday: NSDate? { + var birthday: Date? { get { - let timestamp = defaults?.objectForKey("Birthday") as? NSTimeInterval - return timestamp.map { NSDate(timeIntervalSince1970: $0) } + let timestamp = defaults?.object(forKey: "Birthday") as? TimeInterval + return timestamp.map { Date(timeIntervalSince1970: $0) } } set { if let date = newValue { - defaults?.setObject(date.timeIntervalSince1970, forKey: "Birthday") + defaults?.set(date.timeIntervalSince1970, forKey: "Birthday") } else { - defaults?.removeObjectForKey("Birthday") + defaults?.removeObject(forKey: "Birthday") } defaults?.synchronize() - NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.birthdayDidChangeNotificationName, object: newValue) + NotificationCenter.default.post(name: Notification.Name(rawValue: type(of: self).birthdayDidChangeNotificationName), object: newValue) } } var motivationLevel: MotivationLevel { get { - let uint = defaults?.objectForKey("MotivationLevel") as? UInt - return uint.flatMap { MotivationLevel(rawValue: $0) } ?? .Terrifying + let uint = defaults?.object(forKey: "MotivationLevel") as? UInt + return uint.flatMap { MotivationLevel(rawValue: $0) } ?? .terrifying } set { - defaults?.setObject(newValue.rawValue, forKey: "MotivationLevel") + defaults?.set(newValue.rawValue, forKey: "MotivationLevel") defaults?.synchronize() - NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.motivationLevelDidChangeNotificationName, object: newValue.rawValue) + NotificationCenter.default.post(name: Notification.Name(rawValue: type(of: self).motivationLevelDidChangeNotificationName), object: newValue.rawValue) } } - private let defaults: ScreenSaverDefaults? = { - let bundleIdentifier = NSBundle(forClass: Preferences.self).bundleIdentifier + fileprivate let defaults: ScreenSaverDefaults? = { + let bundleIdentifier = Bundle(for: Preferences.self).bundleIdentifier return bundleIdentifier.flatMap { ScreenSaverDefaults(forModuleWithName: $0) } }() } From 39ca15456836447b12aebe902e5fbb03c9ec1246 Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Fri, 29 Dec 2017 21:50:48 +0200 Subject: [PATCH 4/7] Updating project settings to recommended by Xcode 8.3.3 --- Motivation.xcodeproj/project.pbxproj | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Motivation.xcodeproj/project.pbxproj b/Motivation.xcodeproj/project.pbxproj index 4549342..69b9b85 100644 --- a/Motivation.xcodeproj/project.pbxproj +++ b/Motivation.xcodeproj/project.pbxproj @@ -171,7 +171,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0830; ORGANIZATIONNAME = "Sam Soffes"; TargetAttributes = { 21F222251B73B5AC00B9A11A = { @@ -275,8 +275,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; @@ -319,8 +321,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; @@ -339,16 +343,17 @@ MACOSX_DEPLOYMENT_TARGET = 10.9; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; }; name = Release; }; 21F222321B73B5AC00B9A11A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "Developer ID Application"; COMBINE_HIDPI_IMAGES = YES; - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; INFOPLIST_FILE = Motivation/Info.plist; INSTALL_PATH = "$(HOME)/Library/Screen Savers"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; @@ -363,10 +368,10 @@ 21F222331B73B5AC00B9A11A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "Developer ID Application"; COMBINE_HIDPI_IMAGES = YES; - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; INFOPLIST_FILE = Motivation/Info.plist; INSTALL_PATH = "$(HOME)/Library/Screen Savers"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; From 26766e4f8e6569345ed8e984e0ae67adff72e0ca Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Fri, 29 Dec 2017 22:44:53 +0200 Subject: [PATCH 5/7] Converting to Swift 3 --- Motivation/AgeView.swift | 6 +++--- Motivation/NSCalendar+Motivation.swift | 11 +++++------ Preview/PreviewWindowController.swift | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Motivation/AgeView.swift b/Motivation/AgeView.swift index e5bdd1f..9169d90 100644 --- a/Motivation/AgeView.swift +++ b/Motivation/AgeView.swift @@ -106,7 +106,7 @@ class AgeView: ScreenSaverView { animationTimeInterval = 1 / 30 // Recall preferences - birthday = Preferences().birthday as! Date + birthday = Preferences().birthday // Setup the label addSubview(textLabel) @@ -144,7 +144,7 @@ class AgeView: ScreenSaverView { let minutes = seconds / secondsInMinute let hours = minutes / minutesInHour let days = Double(components.day!) + (hours / hoursInDay) - let years = Double(components.year) + (days / daysInYear) + let years = Double(components.year!) + (days / daysInYear) return years } @@ -156,7 +156,7 @@ class AgeView: ScreenSaverView { /// Birthday changed @objc fileprivate func birthdayDidChange(_ notification: Notification?) { - birthday = Preferences().birthday as! Date + birthday = Preferences().birthday } /// Update the font for the current size diff --git a/Motivation/NSCalendar+Motivation.swift b/Motivation/NSCalendar+Motivation.swift index ae91fe0..5dec3fb 100644 --- a/Motivation/NSCalendar+Motivation.swift +++ b/Motivation/NSCalendar+Motivation.swift @@ -10,13 +10,13 @@ import Foundation extension Calendar { func daysInYear(_ date: Date = Date()) -> Int? { - let year = dateComponents([NSCalendar.Unit.year], from: date).year + let year = dateComponents([.year], from: date).year return daysInYear(year!) } func daysInYear(_ year: Int) -> Int? { guard let begin = lastDayOfYear(year - 1), let end = lastDayOfYear(year) else { return nil } - return dateComponents([NSCalendar.Unit.day], from: begin, to: end, options: []).day + return dateComponents([.day], from: begin, to: end).day } func lastDayOfYear(_ year: Int) -> Date? { @@ -24,11 +24,10 @@ extension Calendar { components.year = year guard let years = date(from: components) else { return nil } - components.month = range(of: NSCalendar.Unit.month, in: NSCalendar.Unit.year, for: years).length - guard let months = date(from: components) else { return nil } - - components.day = range(of: NSCalendar.Unit.day, in: NSCalendar.Unit.month, for: months).length + components.month = range(of: Calendar.Component.month, in: Calendar.Component.year, for: years)?.count + guard let months = date(from: components) else { return nil } + components.day = range(of: Calendar.Component.day, in: Calendar.Component.month, for: months)?.count return date(from: components) } } diff --git a/Preview/PreviewWindowController.swift b/Preview/PreviewWindowController.swift index 2c086f5..083a1ff 100644 --- a/Preview/PreviewWindowController.swift +++ b/Preview/PreviewWindowController.swift @@ -22,7 +22,7 @@ class PreviewWindowController: NSWindowController { window?.contentView = screenSaver - NSTimer.scheduledTimerWithTimeInterval(screenSaver.animationTimeInterval, target: screenSaver, selector: "animateOneFrame", userInfo: nil, repeats: true) + _ = Timer.scheduledTimer(timeInterval: screenSaver.animationTimeInterval, target: screenSaver, selector: #selector(AgeView.animateOneFrame), userInfo: nil, repeats: true) } From 5a3e22e8a0f80a9d814addb0f3bd36521707b74c Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Fri, 29 Dec 2017 22:46:45 +0200 Subject: [PATCH 6/7] Change project for Xcode 8.3.3 --- Motivation.xcodeproj/project.pbxproj | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Motivation.xcodeproj/project.pbxproj b/Motivation.xcodeproj/project.pbxproj index 69b9b85..476281f 100644 --- a/Motivation.xcodeproj/project.pbxproj +++ b/Motivation.xcodeproj/project.pbxproj @@ -177,6 +177,7 @@ 21F222251B73B5AC00B9A11A = { CreatedOnToolsVersion = 6.4; LastSwiftMigration = 0830; + ProvisioningStyle = Automatic; }; 21F222391B73B60100B9A11A = { CreatedOnToolsVersion = 6.4; @@ -305,6 +306,7 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -344,6 +346,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -352,13 +355,14 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = Motivation/Info.plist; INSTALL_PATH = "$(HOME)/Library/Screen Savers"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.motiviation; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 3.0; WRAPPER_EXTENSION = saver; @@ -370,13 +374,14 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = Motivation/Info.plist; INSTALL_PATH = "$(HOME)/Library/Screen Savers"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.motiviation; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 3.0; WRAPPER_EXTENSION = saver; }; From 5c27f4a529e1fce5aa66ca19a428b62b2b67edd6 Mon Sep 17 00:00:00 2001 From: Valeriy Van Date: Fri, 29 Dec 2017 22:48:35 +0200 Subject: [PATCH 7/7] Update project to settings recommended by Xcode 9.2 --- Motivation.xcodeproj/project.pbxproj | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Motivation.xcodeproj/project.pbxproj b/Motivation.xcodeproj/project.pbxproj index 476281f..dc7ca6c 100644 --- a/Motivation.xcodeproj/project.pbxproj +++ b/Motivation.xcodeproj/project.pbxproj @@ -171,7 +171,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 0830; + LastUpgradeCheck = 0920; ORGANIZATIONNAME = "Sam Soffes"; TargetAttributes = { 21F222251B73B5AC00B9A11A = { @@ -271,14 +271,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -318,14 +324,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;