Skip to content

Commit

Permalink
Replacing NSTimers with dispatch timers
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Tsochantaris authored and Paul Tsochantaris committed Jan 31, 2017
1 parent bef5bdb commit 890fcc1
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 36 deletions.
2 changes: 1 addition & 1 deletion PocketTrailer Today Extension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1405</string>
<string>1406</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionMainStoryboard</key>
Expand Down
2 changes: 1 addition & 1 deletion PocketTrailer WatchKit App/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1405</string>
<string>1406</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
Expand Down
2 changes: 1 addition & 1 deletion PocketTrailer WatchKit Extension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1405</string>
<string>1406</string>
<key>CLKComplicationPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).ComplicationDataSource</string>
<key>CLKComplicationSupportedFamilies</key>
Expand Down
2 changes: 1 addition & 1 deletion PocketTrailer/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1405</string>
<string>1406</string>
<key>CoreSpotlightContinuation</key>
<true/>
<key>ITSAppUsesNonExemptEncryption</key>
Expand Down
10 changes: 6 additions & 4 deletions PocketTrailer/QuickStartViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,22 @@ final class QuickStartViewController: UIViewController, UITextFieldDelegate {
s.feedback.text = "Syncing GitHub data for the first time.\n\nThis could take a little while, please wait..."
Settings.lastSuccessfulRefresh = nil
app.startRefreshIfItIsDue()
s.checkTimer = Timer.scheduledTimer(timeInterval: 1.0, target: s, selector: #selector(s.checkRefreshDone), userInfo: nil, repeats: true)
s.checkTimer = Timer(repeats: true, interval: 1) {
s.checkRefreshDone()
}
}
}
}

func checkRefreshDone(t: Timer) {
private func checkRefreshDone() {
if !appIsRefreshing {
checkTimer?.invalidate()
checkTimer = nil
if newServer.lastSyncSucceeded {
dismiss(animated: true, completion: {
dismiss(animated: true) {
popupManager.masterController.resetView()
showMessage("Setup complete!", "You can tweak options & behaviour from the settings.\n\nTrailer has read-only access to your GitHub data, so feel free to experiment, you can't damage your data or settings on GitHub.")
})
}
} else {
showMessage("Syncing with this server failed - please check that your network connection is working and that you have pasted your token correctly", nil)
normalMode()
Expand Down
11 changes: 8 additions & 3 deletions PocketTrailer/iOS_AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ final class iOS_AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat
} else {
let howLongUntilNextSync = TimeInterval(Settings.refreshPeriod) - howLongAgo
DLog("No need to refresh yet, will refresh in %@", howLongUntilNextSync)
refreshTimer = Timer.scheduledTimer(timeInterval: howLongUntilNextSync, target: self, selector: #selector(refreshTimerDone), userInfo: nil, repeats: false)
refreshTimer = Timer(repeats: false, interval: howLongUntilNextSync) { [weak self] in
self?.refreshTimerDone()
}
}
} else {
startRefresh()
Expand Down Expand Up @@ -212,7 +214,9 @@ final class iOS_AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat
showMessage("Refresh failed", "Loading the latest data from GitHub failed")
}

s.refreshTimer = Timer.scheduledTimer(timeInterval: TimeInterval(Settings.refreshPeriod), target: s, selector: #selector(s.refreshTimerDone), userInfo: nil, repeats: false)
s.refreshTimer = Timer(repeats: false, interval: TimeInterval(Settings.refreshPeriod)) {
s.refreshTimerDone()
}
DLog("Refresh done")

s.updateBadge()
Expand Down Expand Up @@ -243,7 +247,8 @@ final class iOS_AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat
}
}

func refreshTimerDone() {
private func refreshTimerDone() {
refreshTimer = nil
if DataManager.appIsConfigured {
startRefresh()
}
Expand Down
31 changes: 13 additions & 18 deletions Shared/PopTimer.swift
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@

#if os(iOS)
import UIKit
#endif
import Foundation

final class PopTimer {

private var _popTimer: Timer?
private let _timeInterval: TimeInterval
private let _callback: () -> Void
private var popTimer: Timer?
private let timeInterval: TimeInterval
private let callback: Completion

func push() {
_popTimer?.invalidate()
_popTimer = Timer.scheduledTimer(timeInterval: _timeInterval, target: self, selector: #selector(popped), userInfo: nil, repeats: false)
}

@objc
func popped() {
invalidate()
_callback()
popTimer?.invalidate()
popTimer = Timer(repeats: false, interval: timeInterval) { [weak self] in
self?.invalidate()
self?.callback()
}
}

func invalidate() {
_popTimer?.invalidate()
_popTimer = nil
popTimer?.invalidate()
popTimer = nil
}

init(timeInterval: TimeInterval, callback: @escaping Completion) {
_timeInterval = timeInterval
_callback = callback
self.timeInterval = timeInterval
self.callback = callback
}
}
24 changes: 24 additions & 0 deletions Shared/Timer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

import Foundation

final class Timer {

private let timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
private let completion: Completion

init(repeats: Bool, interval: TimeInterval, block: @escaping Completion) {
completion = block

if repeats {
timer.scheduleRepeating(deadline: .now() + interval, interval: interval)
} else {
timer.scheduleOneshot(deadline: .now() + interval)
}
timer.setEventHandler(handler: completion)
timer.resume()
}

func invalidate() {
timer.cancel()
}
}
6 changes: 6 additions & 0 deletions Trailer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
1633C1A21ABD84370086C692 /* PullRequestCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1633C1A11ABD84370086C692 /* PullRequestCell.swift */; };
16358F3B1CF138190055F849 /* ItemDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16358F3A1CF138190055F849 /* ItemDelegate.swift */; };
16358F3D1CF206CE0055F849 /* MenuBarSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16358F3C1CF206CE0055F849 /* MenuBarSet.swift */; };
1639E2C11E4007B900C561E1 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1639E2C01E4007B900C561E1 /* Timer.swift */; };
1639E2C21E4007B900C561E1 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1639E2C01E4007B900C561E1 /* Timer.swift */; };
164785AA1A2CE7BD00297764 /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 164785A91A2CE7BD00297764 /* Globals.swift */; };
164785AB1A2CE7BD00297764 /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 164785A91A2CE7BD00297764 /* Globals.swift */; };
164840BF1ACFEA45009E6383 /* AboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 164840BE1ACFEA45009E6383 /* AboutWindow.xib */; };
Expand Down Expand Up @@ -268,6 +270,7 @@
1633C1A11ABD84370086C692 /* PullRequestCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = PullRequestCell.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
16358F3A1CF138190055F849 /* ItemDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ItemDelegate.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
16358F3C1CF206CE0055F849 /* MenuBarSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MenuBarSet.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
1639E2C01E4007B900C561E1 /* Timer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Timer.swift; path = Shared/Timer.swift; sourceTree = "<group>"; };
163D1F7F1AAFA54800E080D7 /* Trailer 20.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Trailer 20.xcdatamodel"; sourceTree = "<group>"; };
163E45881CD3EB6000B0E2BE /* Trailer 26.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Trailer 26.xcdatamodel"; sourceTree = "<group>"; };
164785A91A2CE7BD00297764 /* Globals.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = Globals.swift; path = Shared/Globals.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
Expand Down Expand Up @@ -513,6 +516,7 @@
1668CFE71D5E16B70021CDC5 /* Reachability.swift */,
16901A441D659E9500141595 /* NotificationQueue.swift */,
160E19E11D672BD1006C1A59 /* PopTimer.swift */,
1639E2C01E4007B900C561E1 /* Timer.swift */,
);
name = Logic;
sourceTree = "<group>";
Expand Down Expand Up @@ -1107,6 +1111,7 @@
160823F51A44997F006F91AD /* UINavigationControllerExtensions.swift in Sources */,
16275DF61CF8944100EEBF48 /* API.swift in Sources */,
16901A461D659E9500141595 /* NotificationQueue.swift in Sources */,
1639E2C21E4007B900C561E1 /* Timer.swift in Sources */,
16B3B3501A34E990000BE6CC /* Trailer.xcdatamodeld in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -1181,6 +1186,7 @@
162A29D91A4085FD008F41A9 /* GroupingCriterion.swift in Sources */,
16B3B34F1A34E990000BE6CC /* Trailer.xcdatamodeld in Sources */,
1633C1921ABCEC4A0086C692 /* Issue.swift in Sources */,
1639E2C11E4007B900C561E1 /* Timer.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion Trailer/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1405</string>
<string>1406</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>
Expand Down
13 changes: 9 additions & 4 deletions Trailer/OSX_AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
final class OSX_AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate, NSUserNotificationCenterDelegate, NSOpenSavePanelDelegate {

// Globals
weak var refreshTimer: Timer?
var refreshTimer: Timer?
var openingWindow = false
var isManuallyScrolling = false
var ignoreNextFocusLoss = false
Expand Down Expand Up @@ -582,7 +582,9 @@ final class OSX_AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate,
} else {
let howLongUntilNextSync = TimeInterval(Settings.refreshPeriod) - howLongAgo
DLog("No need to refresh yet, will refresh in %@", howLongUntilNextSync)
refreshTimer = Timer.scheduledTimer(timeInterval: howLongUntilNextSync, target: self, selector: #selector(refreshTimerDone), userInfo: nil, repeats: false)
refreshTimer = Timer(repeats: false, interval: howLongUntilNextSync) { [weak self] in
self?.refreshTimerDone()
}
}
}
else
Expand Down Expand Up @@ -718,11 +720,14 @@ final class OSX_AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate,
Settings.lastSuccessfulRefresh = Date()
}
s.completeRefresh()
s.refreshTimer = Timer.scheduledTimer(timeInterval: TimeInterval(Settings.refreshPeriod), target: s, selector: #selector(s.refreshTimerDone), userInfo: nil, repeats: false)
s.refreshTimer = Timer(repeats: false, interval: TimeInterval(Settings.refreshPeriod)) {
s.refreshTimerDone()
}
}
}

func refreshTimerDone() {
private func refreshTimerDone() {
refreshTimer = nil
if DataManager.appIsConfigured {
if preferencesWindow != nil {
preferencesDirty = true
Expand Down
6 changes: 4 additions & 2 deletions Trailer/SetupAssistant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,15 @@ final class SetupAssistant: NSWindow, NSWindowDelegate {
s.quickstart.stringValue = "\nSyncing GitHub data for the first time.\n\nThis could take a little while, please wait..."
Settings.lastSuccessfulRefresh = nil
app.startRefreshIfItIsDue()
s.checkTimer = Timer.scheduledTimer(timeInterval: 0.5, target: s, selector: #selector(s.checkRefreshDone), userInfo: nil, repeats: true)
s.checkTimer = Timer(repeats: true, interval: 0.5) {
s.checkRefreshDone()
}
}
}
}
}

func checkRefreshDone(_ t: Timer) {
private func checkRefreshDone() {
if !appIsRefreshing {

checkTimer?.invalidate()
Expand Down

0 comments on commit 890fcc1

Please sign in to comment.