From b8a3efb6602704f49b346f21ea66eca4ad913ef7 Mon Sep 17 00:00:00 2001 From: Oktawian Chojnacki Date: Mon, 5 Dec 2016 09:20:41 +0100 Subject: [PATCH] Initial commit. --- .gitignore | 1 + Insomnia.podspec | 12 +++ Insomnia/Insomnia.swift | 101 +++++++++++++++++++++++++ LICENSE | 22 ++++++ Tests/InsomniaTests.swift | 150 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 286 insertions(+) create mode 100644 .gitignore create mode 100644 Insomnia.podspec create mode 100644 Insomnia/Insomnia.swift create mode 100644 LICENSE create mode 100644 Tests/InsomniaTests.swift diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/Insomnia.podspec b/Insomnia.podspec new file mode 100644 index 0000000..e308a14 --- /dev/null +++ b/Insomnia.podspec @@ -0,0 +1,12 @@ +Pod::Spec.new do |s| + s.name = "Insomnia" + s.version = "0.9.0" + s.summary = "Small class to disable sleep timeout in iOS." + s.description = "Sometimes you want your iPhone to stay awake a little bit longer." + s.homepage = "https://github.com/ochococo/insomnia/" + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = "Oktawian Chojnacki" + s.platform = :ios, "9.0" + s.source = { :git => "https://github.com/ochococo/insomnia.git", :tag => "#{s.version}" } + s.source_files = "Insomnia/**/*.{swift}" +end diff --git a/Insomnia/Insomnia.swift b/Insomnia/Insomnia.swift new file mode 100644 index 0000000..25c312b --- /dev/null +++ b/Insomnia/Insomnia.swift @@ -0,0 +1,101 @@ +// +// The MIT License (MIT) +// +// Copyright (c) 2016 Oktawian Chojnacki +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import UIKit + +public enum InsomniaMode { + case disabled + case always + case whenCharging +} + +public protocol BatteryStateReporting : class { + var batteryStateHandler: ((_ isPlugged: Bool) -> Void)? { get set } +} + +public final class Insomnia : BatteryStateReporting { + + public var mode: InsomniaMode { + didSet { + updateInsomniaMode() + } + } + + private unowned let device: UIDevice + private unowned let notificationCenter: NotificationCenter + private unowned let application: UIApplication + + public var batteryStateHandler: ((_ isPlugged: Bool) -> Void)? { + didSet { + notifyAboutCurrentBatteryState() + } + } + + public init(mode: InsomniaMode, + device: UIDevice = UIDevice.current, + notificationCenter: NotificationCenter = NotificationCenter.default, + application: UIApplication = UIApplication.shared) { + self.device = device + self.mode = mode + self.notificationCenter = notificationCenter + self.application = application + startMonitoring() + } + + private func startMonitoring() { + device.isBatteryMonitoringEnabled = true + notificationCenter.addObserver(self, + selector: #selector(batteryStateDidChange), + name: NSNotification.Name.UIDeviceBatteryStateDidChange, object: nil) + updateInsomniaMode() + } + + @objc private func batteryStateDidChange(notification: NSNotification){ + updateInsomniaMode() + } + + private func updateInsomniaMode() { + notifyAboutCurrentBatteryState() + application.isIdleTimerDisabled = mode == .whenCharging ? isPlugged : (mode != .disabled) + } + + private func notifyAboutCurrentBatteryState() { + batteryStateHandler?(isPlugged) + } + + private var isPlugged: Bool { + switch device.batteryState { + case .unknown, .unplugged: + return false + default: + return true + } + } + + deinit { + notificationCenter.removeObserver(self) + device.isBatteryMonitoringEnabled = false + application.isIdleTimerDisabled = false + } +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..01ace4b --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Yalantis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Tests/InsomniaTests.swift b/Tests/InsomniaTests.swift new file mode 100644 index 0000000..9a84302 --- /dev/null +++ b/Tests/InsomniaTests.swift @@ -0,0 +1,150 @@ +// +// The MIT License (MIT) +// +// Copyright (c) 2016 Oktawian Chojnacki +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + + +import Foundation + + +import XCTest +@testable import Stamp + +final class DeviceMock : UIDevice { + + var mock_batteryState: UIDeviceBatteryState = .Unknown + + override var batteryState: UIDeviceBatteryState { + get { return mock_batteryState } + set {} + } +} + +final class InsomniaTests: XCTestCase { + + let device = DeviceMock() + var insomnia: Insomnia! + + override func setUp() { + super.setUp() + + insomnia = Insomnia(mode: .WhenCharging, device: device) + } + + func testNotifiedAboutBatteryStateChangeCharging() { + + device.mock_batteryState = .Charging + + insomnia.batteryStateHandler = { isPlugged in + XCTAssertTrue(isPlugged) + } + } + + func testNotifiedAboutBatteryStateChangeFull() { + + device.mock_batteryState = .Full + + insomnia.batteryStateHandler = { isPlugged in + XCTAssertTrue(isPlugged) + } + } + + func testNotifiedAboutBatteryStateChangeUnknown() { + + device.mock_batteryState = .Unknown + + insomnia.batteryStateHandler = { isPlugged in + XCTAssertFalse(isPlugged) + } + } + + func testNotifiedAboutBatteryStateChangeUnplugged() { + + device.mock_batteryState = .Unplugged + + insomnia.batteryStateHandler = { isPlugged in + XCTAssertFalse(isPlugged) + } + } + + func testNotifiedAboutBatteryStateChangeAfterNotification() { + + device.mock_batteryState = .Charging + + var batteryIsPlugged = true + + insomnia.batteryStateHandler = { isPlugged in + batteryIsPlugged = isPlugged + } + + device.mock_batteryState = .Unplugged + + let notification = NSNotification(name: UIDeviceBatteryStateDidChangeNotification, object: nil) + NSNotificationCenter.defaultCenter().postNotification(notification) + + XCTAssertFalse(batteryIsPlugged) + } + + func testDidSetInsomniaModeToDisabledAfterNotificationAboutUnplugged() { + + device.mock_batteryState = .Unplugged + + let notification = NSNotification(name: UIDeviceBatteryStateDidChangeNotification, object: nil) + NSNotificationCenter.defaultCenter().postNotification(notification) + + XCTAssertFalse(UIApplication.sharedApplication().idleTimerDisabled) + } + + func testDidSetInsomniaModeToEnabledAfterNotificationAboutCharging() { + + device.mock_batteryState = .Charging + + let notification = NSNotification(name: UIDeviceBatteryStateDidChangeNotification, object: nil) + NSNotificationCenter.defaultCenter().postNotification(notification) + + XCTAssertTrue(UIApplication.sharedApplication().idleTimerDisabled) + } + + func testDidSetInsomniaModeToEnabledInAlwaysModeAfterNotificationAboutUnplugged() { + + insomnia.mode = .Always + + device.mock_batteryState = .Unplugged + + let notification = NSNotification(name: UIDeviceBatteryStateDidChangeNotification, object: nil) + NSNotificationCenter.defaultCenter().postNotification(notification) + + XCTAssertTrue(UIApplication.sharedApplication().idleTimerDisabled) + } + + func testDidSetInsomniaModeToDisabledInDisabledModeAfterNotificationAboutCharging() { + + insomnia.mode = .Disabled + + device.mock_batteryState = .Charging + + let notification = NSNotification(name: UIDeviceBatteryStateDidChangeNotification, object: nil) + NSNotificationCenter.defaultCenter().postNotification(notification) + + XCTAssertFalse(UIApplication.sharedApplication().idleTimerDisabled) + } +}