Skip to content

Commit

Permalink
Merge pull request #988 from hello/jimmy/animation-logging
Browse files Browse the repository at this point in the history
Fixes the animation issue.  2.1.0 RC 3
  • Loading branch information
jimmymlu authored Apr 7, 2017
2 parents 4e8aea2 + 27bdc80 commit 4320cc9
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 59 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## 2.1.0.26

Fixes:

* Another attempt to fix night mode transition by requesting more than 1 location objects, until 1 is valid

## 2.1.0.25

Fixes:

* Prevent multiple calls to update theme
* Update error message

## 2.1.0.24

* Adding additional logging for Night Mode to see why animation is disabled on schedule

## 2.1.0.23

Fixes:
Expand Down
2 changes: 1 addition & 1 deletion Extensions/RoomConditions/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>2.1.0.23</string>
<string>2.1.0.26</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionMainStoryboard</key>
Expand Down
4 changes: 2 additions & 2 deletions Sense.xcodeproj/xcshareddata/xcschemes/Sense.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@
<EnvironmentVariable
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
isEnabled = "NO">
</EnvironmentVariable>
<EnvironmentVariable
key = "OS_ACTIVITY_MODE"
value = "disable"
isEnabled = "YES">
isEnabled = "NO">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
Expand Down
1 change: 1 addition & 0 deletions SleepModel/Base.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@
"settings.night-mode.option.scheduled.description" = "Automatic from sunset to sunrise.";
"settings.night-mode.no-location.message.format" = "%@ must be enabled for Sense to know local sunset and sunrise times.";
"settings.night-mode.location.service" = "Location Services";
"settings.night-mode.error.no-location" = "Your location could not be determined. Make sure Location Service is enabled or try moving to a different location.";
"settings.units" = "Units and time";
"settings.support" = "Support";
"settings.tell-a-friend" = "Tell a friend about Sense";
Expand Down
3 changes: 2 additions & 1 deletion SleepModel/HEMLocationService.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ typedef void(^HEMLocationHandler)(HEMLocation* _Nullable mostRecentLocation, NSE
- (HEMLocationAuthStatus)authorizationStatus;
- (BOOL)requiresPermission;
- (BOOL)hasDeniedPermission;
- (NSError*)quickLocation:(HEMLocationHandler)completion;
- (BOOL)isEnabled;
- (nullable NSError*)quickLocation:(HEMLocationHandler)completion;
- (void)requestPermission:(HEMLocationAuthorizationHandler)authHandler;
- (nullable HEMLocationActivity*)startLocationActivity:(HEMLocationHandler)update
error:(NSError**)error;
Expand Down
4 changes: 4 additions & 0 deletions SleepModel/HEMLocationService.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ - (HEMLocationAuthStatus)authorizationStatus {
return HEMLocationAuthStatusAuthorized;
}
}

- (BOOL)isEnabled {
return [CLLocationManager locationServicesEnabled];
}

- (BOOL)hasDeniedPermission {
return [self authorizationStatus] == HEMLocationAuthStatusDenied;
Expand Down
2 changes: 1 addition & 1 deletion SleepModel/NightModeService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class NightModeService: SENService {
func scheduleForSunset(latitude: Double, longitude: Double) {
self.updateLocation(latitude: latitude, longitude: longitude)
self.save(option: .sunsetToSunrise)
}
}

@objc func updateLocation(latitude: Double, longitude: Double) {
let latKey = NightModeService.settingsLatKey
Expand Down
139 changes: 90 additions & 49 deletions SleepModel/NightModeSettingsPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class NightModeSettingsPresenter: HEMListPresenter {
fileprivate var footer: UIView?
fileprivate var waitingOnPermission: Bool
fileprivate weak var transitionView: UIView?
fileprivate var locationActivity: HEMLocationActivity?

init(nightModeService: NightModeService, locationService: HEMLocationService) {
let optionsTitle = NSLocalizedString("settings.night-mode.options.title", comment: "table options title")
Expand Down Expand Up @@ -74,9 +75,12 @@ class NightModeSettingsPresenter: HEMListPresenter {
textView.isScrollEnabled = false
textView.backgroundColor = self.tableView!.backgroundColor

let enabled = self.locationService.isEnabled()
let denied = self.locationService.hasDeniedPermission()

let footer = UIView()
footer.addSubview(textView)
footer.isHidden = self.locationService.hasDeniedPermission() == false
footer.isHidden = denied == false && enabled == true

return footer
}
Expand Down Expand Up @@ -134,7 +138,9 @@ class NightModeSettingsPresenter: HEMListPresenter {
cell.descriptionLabel?.text = self.detail(forItem: item)

if option == .sunsetToSunrise {
self.footer?.isHidden = self.locationService.hasDeniedPermission() == false
let enabled = self.locationService.isEnabled()
let denied = self.locationService.hasDeniedPermission()
self.footer?.isHidden = denied == false && enabled == true
cell.enable(self.footer?.isHidden == true)
} else {
cell.enable(true)
Expand All @@ -143,38 +149,27 @@ class NightModeSettingsPresenter: HEMListPresenter {

override func didNotifyDelegateOfSelection() {
super.didNotifyDelegateOfSelection()

let selectedName = self.selectedItemNames?.last as? String ?? ""
guard let option = NightModeService.Option.fromDescription(description: selectedName) else {
return
}

// snapshot the screen
if self.activityContainerView != nil {
if let snapshot = self.activityContainerView!.snapshotView(afterScreenUpdates: false) {
snapshot.frame = self.activityContainerView!.bounds
self.activityContainerView!.addSubview(snapshot)
self.transitionView = snapshot
// the transitionView will be removed when the theme is changed, in didChange:
}
}

let selectedName = self.selectedItemNames?.last as? String ?? ""
guard let option = NightModeService.Option.fromDescription(description: selectedName) else {
return
}

switch option {
case .sunsetToSunrise:
if self.locationService.requiresPermission() == true {
self.waitingOnPermission = true
self.locationService.requestPermission({ (status: HEMLocationAuthStatus) in
self.waitingOnPermission = false
switch status {
case .notEnabled:
fallthrough
case .denied:
let savedOption = self.nightModeService.savedOption()
self.selectedItemNames = [savedOption.localizedDescription()]
self.tableView?.reloadData() // to disable the schedule cell
self.removeTransitionView(animate: false)
default:
self.scheduleNightModeFromLocation()
}
})
self.requestLocationPermission()
} else {
self.scheduleNightModeFromLocation()
}
Expand All @@ -190,54 +185,100 @@ class NightModeSettingsPresenter: HEMListPresenter {

}

fileprivate func requestLocationPermission() {
self.locationService.requestPermission({ (status: HEMLocationAuthStatus) in
self.waitingOnPermission = false
switch status {
case .notEnabled:
fallthrough
case .denied:
self.revertSelection(withError: false)
default:
self.scheduleNightModeFromLocation()
}
})
}

fileprivate func revertSelection(withError: Bool) {
let savedOption = self.nightModeService.savedOption()
self.selectedItemNames = [savedOption.localizedDescription()]
self.tableView?.reloadData() // to disable the schedule cell

self.removeTransitionView(animate: true)

if withError == true {
// show error
let title = NSLocalizedString("settings.night-mode", comment: "title, same as screen title")
let message = NSLocalizedString("settings.night-mode.error.no-location", comment: "no location error")
self.presenterDelegate?.presentError(withTitle: title, message: message, from: self)
}
}

fileprivate func removeTransitionView(animate: Bool) {
guard let view = self.transitionView else {
SENAnalytics.trackWarning(withMessage: "snapshot already removed in night mode settings")
return
}

guard animate == true else {
SENAnalytics.trackWarning(withMessage: "animation disabled when removing snapshot in night mode settings")
view.removeFromSuperview()
return
}

UIView.animate(withDuration: 0.35, animations: {
UIView.animate(withDuration: 0.35, delay: 0.0, options: .beginFromCurrentState, animations: {
view.alpha = 0.0
}) { (finished: Bool) in
view.removeFromSuperview()
}
}

fileprivate func showLocationError() {
// TODO: throw an alert
fileprivate func scheduleNightModeFromLocation() {
guard let service = self.locationService else {
self.revertSelection(withError: false)
return
}

var done = false
do {
self.locationActivity = try service.startLocationActivity({ [weak self] (loc: HEMLocation?, err: Error?) in
// to ensure only 1 location is used and to not call it too many times
guard done == false else {
return
}

if loc != nil {
done = true
SENAnalytics.trackNightModeChange(withSetting: kHEMAnalyticsPropNightModeValueAuto)
self?.nightModeService.scheduleForSunset(latitude: Double(loc!.lat), longitude: Double(loc!.lon))
self?.removeTransitionView(animate: true)
} else if err != nil {
done = true
self?.revertSelection(withError: true)
}

if done == true {
if let activity = self?.locationActivity, let locService = self?.locationService {
locService.stop(activity)
}
}

})
} catch _ {
self.revertSelection(withError: true)
}
}

fileprivate func scheduleNightModeFromLocation() {
var scheduled = false
let service = self.locationService
let error = service?.quickLocation({[weak self] (loc: HEMLocation?, err: Error?) in
// to ensure only 1 location is used and to not call it too many times
guard scheduled == false else {
return
}

scheduled = true

if loc != nil {
SENAnalytics.trackNightModeChange(withSetting: kHEMAnalyticsPropNightModeValueAuto)
self?.nightModeService.scheduleForSunset(latitude: Double(loc!.lat),
longitude: Double(loc!.lon))
self?.removeTransitionView(animate: true)
} else {
self?.removeTransitionView(animate: false)
self?.showLocationError()
}

})
deinit {
guard let service = self.locationService else {
return
}

if error != nil {
self.removeTransitionView(animate: false)
self.showLocationError()
guard let activity = self.locationActivity else {
return
}

service.stop(activity)
}

}
2 changes: 1 addition & 1 deletion SleepModel/Sense-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>2.1.0.23</string>
<string>2.1.0.26</string>
<key>FacebookAppID</key>
<string>372438546161587</string>
<key>FacebookDisplayName</key>
Expand Down
13 changes: 9 additions & 4 deletions SleepModel/Theme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ import UIKit
let app = UIApplication.shared
let keyWindow = app.delegate?.window
let rootVC = keyWindow??.rootViewController
self.apply(viewController: rootVC, auto: auto)
self.applyApearances()
self.apply(viewController: rootVC, auto: auto)
}

fileprivate func applyApearances() {
Expand Down Expand Up @@ -298,14 +298,17 @@ import UIKit
return
}

var viewControllers: [UIViewController]?
if let navVC = controller as? UINavigationController {
navVC.viewControllers.forEach({ (controllerInStack: UIViewController) in
viewControllers = navVC.viewControllers
viewControllers?.forEach({ (controllerInStack: UIViewController) in
self.apply(viewController: controllerInStack, auto: auto)
})
}

if let tabVC = controller as? UITabBarController {
tabVC.viewControllers?.forEach({ (tabController: UIViewController) in
viewControllers = tabVC.viewControllers
viewControllers?.forEach({ (tabController: UIViewController) in
self.apply(viewController: tabController, auto: auto)
})
}
Expand All @@ -316,7 +319,9 @@ import UIKit

themedVC.didChange(theme: self, auto: auto)
controller.childViewControllers.forEach { (child: UIViewController) in
self.apply(viewController: child, auto: auto)
if viewControllers == nil || viewControllers!.contains(child) == false {
self.apply(viewController: child, auto: auto)
}
}
}

Expand Down

0 comments on commit 4320cc9

Please sign in to comment.