Skip to content

Commit

Permalink
Add timezone retrieval on iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
Pante committed Jun 24, 2023
1 parent 064e070 commit 714d5f3
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 154 deletions.
8 changes: 4 additions & 4 deletions stevia/example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@

/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
5F85B0167B5FA5A406511FC6 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D910E1AFE057DA5AD107ECD /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
DD992446B6C14ABE6DCE8D55 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DCC8C92E591DFE8398C6AF0 /* Pods_RunnerTests.framework */; };
E3D4BF3F2A46E36500A95BAC /* HapticChannelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3D4BF3E2A46E36500A95BAC /* HapticChannelTests.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -45,7 +45,6 @@
0D910E1AFE057DA5AD107ECD /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3DCC8C92E591DFE8398C6AF0 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand All @@ -64,6 +63,7 @@
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AD8E642659CB1758D814C5C6 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
D0502FE43E836EFA6B94CB19 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
E3D4BF3E2A46E36500A95BAC /* HapticChannelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticChannelTests.swift; sourceTree = "<group>"; };
FC0AC7065165FFF8E62BA847 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -103,7 +103,7 @@
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
E3D4BF3E2A46E36500A95BAC /* HapticChannelTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -368,7 +368,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
E3D4BF3F2A46E36500A95BAC /* HapticChannelTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
103 changes: 103 additions & 0 deletions stevia/example/ios/RunnerTests/HapticChannelTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// This demonstrates a simple unit test of the Swift portion of this plugin's implementation.
//
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.

import Flutter
import UIKit
import XCTest

@testable import stevia

class HapticPluginTests: XCTestCase {

let plugin = SteviaPlugin()

func testHandleSuccessful() {
let call = FlutterMethodCall(methodName: "hapticFeedback", arguments: "success")
let expectation = expectation(description: "result block must be called.")

plugin.handle(call) { result in
XCTAssertNil(result)
expectation.fulfill()
}
waitForExpectations(timeout: 1)
}

func testHandleInvalidArgument() {
let call = FlutterMethodCall(methodName: "hapticFeedback", arguments: nil)
let expectation = expectation(description: "result block must be called.")

plugin.handle(call) { result in
XCTAssertEqual(
result as! FlutterError,
FlutterError(code: HapticPlugin.errorCode, message: "No pattern was specified", details: nil)
)
expectation.fulfill()
}
waitForExpectations(timeout: 1)
}

func testHandleUnsupportedMethod() {
let call = FlutterMethodCall(methodName: "invalid", arguments: "success")
let expectation = expectation(description: "result block must be called.")

plugin.handle(call) { result in
XCTAssertEqual(
result as! NSObject,
FlutterMethodNotImplemented
)
expectation.fulfill()
}
waitForExpectations(timeout: 1)
}

}

class HapticFeedbackTests: XCTestCase {

let feedback = HapticFeedback()

func testHapticFeedbackPerformSuccess() {
XCTAssertNil(feedback.perform("success"))
}

func testHapticFeedbackPerformWarning() {
XCTAssertNil(feedback.perform("warning"))
}

func testHapticFeedbackPerformError() {
XCTAssertNil(feedback.perform("error"))
}

func testHapticFeedbackPerformSelection() {
XCTAssertNil(feedback.perform("selection"))
}

func testHapticFeedbackPerformHeavy() {
XCTAssertNil(feedback.perform("heavy"))
}

func testHapticFeedbackPerformMedium() {
XCTAssertNil(feedback.perform("medium"))
}

func testHapticFeedbackPerformLight() {
XCTAssertNil(feedback.perform("light"))
}

func testHapticFeedbackPerformRigid() {
XCTAssertNil(feedback.perform("rigid"))
}

func testHapticFeedbackPerformSoft() {
XCTAssertNil(feedback.perform("soft"))
}

func testHapticFeedbackUnspportedPattern() {
XCTAssertEqual(
feedback.perform("invalid") as! FlutterError,
FlutterError(code: HapticPlugin.errorCode, message: "Unsupported pattern: invalid", details: nil)
)
}

}
101 changes: 0 additions & 101 deletions stevia/example/ios/RunnerTests/RunnerTests.swift
Original file line number Diff line number Diff line change
@@ -1,105 +1,4 @@
import Flutter
import UIKit
import XCTest

@testable import stevia



// This demonstrates a simple unit test of the Swift portion of this plugin's implementation.
//
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.

class HapticPluginTests: XCTestCase {

let plugin = HapticPlugin()

func testHandleSuccessful() {
let call = FlutterMethodCall(methodName: "hapticFeedback", arguments: "success")
let expectation = expectation(description: "result block must be called.")

plugin.handle(call) { result in
XCTAssertNil(result)
expectation.fulfill()
}
waitForExpectations(timeout: 1)
}

func testHandleInvalidArgument() {
let call = FlutterMethodCall(methodName: "hapticFeedback", arguments: nil)
let expectation = expectation(description: "result block must be called.")

plugin.handle(call) { result in
XCTAssertEqual(
result as! FlutterError,
FlutterError(code: HapticPlugin.errorCode, message: "No pattern was specified", details: nil)
)
expectation.fulfill()
}
waitForExpectations(timeout: 1)
}

func testHandleUnsupportedMethod() {
let call = FlutterMethodCall(methodName: "invalid", arguments: "success")
let expectation = expectation(description: "result block must be called.")

plugin.handle(call) { result in
XCTAssertEqual(
result as! NSObject,
FlutterMethodNotImplemented
)
expectation.fulfill()
}
waitForExpectations(timeout: 1)
}

}

class HapticFeedbackTests: XCTestCase {

let feedback = HapticFeedback()

func testHapticFeedbackPerformSuccess() {
XCTAssertNil(feedback.perform("success"))
}

func testHapticFeedbackPerformWarning() {
XCTAssertNil(feedback.perform("warning"))
}

func testHapticFeedbackPerformError() {
XCTAssertNil(feedback.perform("error"))
}

func testHapticFeedbackPerformSelection() {
XCTAssertNil(feedback.perform("selection"))
}

func testHapticFeedbackPerformHeavy() {
XCTAssertNil(feedback.perform("heavy"))
}

func testHapticFeedbackPerformMedium() {
XCTAssertNil(feedback.perform("medium"))
}

func testHapticFeedbackPerformLight() {
XCTAssertNil(feedback.perform("light"))
}

func testHapticFeedbackPerformRigid() {
XCTAssertNil(feedback.perform("rigid"))
}

func testHapticFeedbackPerformSoft() {
XCTAssertNil(feedback.perform("soft"))
}

func testHapticFeedbackUnspportedPattern() {
XCTAssertEqual(
feedback.perform("invalid") as! FlutterError,
FlutterError(code: HapticPlugin.errorCode, message: "Unsupported pattern: invalid", details: nil)
)
}

}
69 changes: 69 additions & 0 deletions stevia/ios/Classes/HapticChannel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import Flutter
import UIKit

class HapticChannel {

private let methodHander = HapticMethodHandler()
private let methodChannel: FlutterMethodChannel

init(with registrar: FlutterPluginRegistrar) {
methodChannel = FlutterMethodChannel(name: "com.foruslabs.stevia.haptic", binaryMessenger: registrar.messenger())
methodChannel.setMethodCallHandler(methodHander.handle)
}

}

class HapticMethodHandler {

private let feedback = HapticFeedback()

func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch (call.method, call.arguments) {
case ("hapticFeedback", let pattern as String):
result(feedback.perform(pattern))
case ("hapticFeedback", _):
result(FlutterError(code: HapticFeedback.code, message: "No pattern was specified", details: nil));

default:
result(FlutterMethodNotImplemented)
}
}

}

class HapticFeedback {
static let code = "invalid-haptic-pattern"

private let notificationFeedback = UINotificationFeedbackGenerator()
private let selectionFeedback = UISelectionFeedbackGenerator()
private let heavyImpactFeedback = UIImpactFeedbackGenerator(style: .heavy)
private let mediumImpactFeedback = UIImpactFeedbackGenerator(style: .medium)
private let lightImpactFeedback = UIImpactFeedbackGenerator(style: .light)
private var rigitImpactFeedback: UIImpactFeedbackGenerator?
private var softImpactFeedback: UIImpactFeedbackGenerator?

init() {
if #available(iOS 13, *) {
rigitImpactFeedback = UIImpactFeedbackGenerator(style: .rigid)
softImpactFeedback = UIImpactFeedbackGenerator(style: .soft)
}
}

func perform(_ pattern: String) -> Any? {
switch pattern {
case "success": notificationFeedback.notificationOccurred(.success)
case "warning": notificationFeedback.notificationOccurred(.warning)
case "error": notificationFeedback.notificationOccurred(.error)
case "selection": selectionFeedback.selectionChanged()
case "heavy": heavyImpactFeedback.impactOccurred()
case "medium": mediumImpactFeedback.impactOccurred()
case "light": lightImpactFeedback.impactOccurred()
case "rigid": rigitImpactFeedback?.impactOccurred()
case "soft": softImpactFeedback?.impactOccurred()
default:
return FlutterError(code: HapticFeedback.code, message: "Unsupported pattern: \(pattern)", details: nil)
}

return nil
}
}
56 changes: 7 additions & 49 deletions stevia/ios/Classes/SteviaPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,19 @@ import Flutter
import UIKit

public class SteviaPlugin: NSObject, FlutterPlugin {
static let hapticErrorCode = "invalid-haptic-pattern"

public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "com.foruslabs.stevia.haptic", binaryMessenger: registrar.messenger())
let instance = SteviaPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
registrar.addApplicationDelegate(SteviaPlugin(with: registrar))
}


private let feedback = HapticFeedback()

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch (call.method, call.arguments) {
case ("hapticFeedback", let pattern as String):
result(feedback.perform(pattern))
case ("hapticFeedback", _):
result(FlutterError(code: SteviaPlugin.hapticErrorCode, message: "No pattern was specified", details: nil));
default:
result(FlutterMethodNotImplemented)
}
private let hapticChannel: HapticChannel
private let timezoneChannel: TimezoneChannel

init(with registrar: FlutterPluginRegistrar) {
hapticChannel = HapticChannel(with: registrar)
timezoneChannel = TimezoneChannel(with: registrar)
}

}

class HapticFeedback {
private let notificationFeedback = UINotificationFeedbackGenerator()
private let selectionFeedback = UISelectionFeedbackGenerator()
private let heavyImpactFeedback = UIImpactFeedbackGenerator(style: .heavy)
private let mediumImpactFeedback = UIImpactFeedbackGenerator(style: .medium)
private let lightImpactFeedback = UIImpactFeedbackGenerator(style: .light)
private var rigitImpactFeedback: UIImpactFeedbackGenerator?
private var softImpactFeedback: UIImpactFeedbackGenerator?

init() {
if #available(iOS 13, *) {
rigitImpactFeedback = UIImpactFeedbackGenerator(style: .rigid)
softImpactFeedback = UIImpactFeedbackGenerator(style: .soft)
}
}

func perform(_ pattern: String) -> Any? {
switch pattern {
case "success": notificationFeedback.notificationOccurred(.success)
case "warning": notificationFeedback.notificationOccurred(.warning)
case "error": notificationFeedback.notificationOccurred(.error)
case "selection": selectionFeedback.selectionChanged()
case "heavy": heavyImpactFeedback.impactOccurred()
case "medium": mediumImpactFeedback.impactOccurred()
case "light": lightImpactFeedback.impactOccurred()
case "rigid": rigitImpactFeedback?.impactOccurred()
case "soft": softImpactFeedback?.impactOccurred()
default:
return FlutterError(code: SteviaPlugin.hapticErrorCode, message: "Unsupported pattern: \(pattern)", details: nil)
}

return nil
}
}
Loading

0 comments on commit 714d5f3

Please sign in to comment.