Skip to content

Commit fbcf29c

Browse files
authored
Merge pull request #42 from jevonmao/develop
2 parents 81da16d + 7bb82a2 commit fbcf29c

File tree

64 files changed

+715
-105
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+715
-105
lines changed

.github/workflows/swift.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ jobs:
2727
uses: maxim-lobanov/setup-xcode@v1
2828
with:
2929
xcode-version: latest-stable
30-
- name: Test
31-
run: xcodebuild -scheme PermissionsSwiftUI -destination 'platform=iOS Simulator,name=iPhone 12 Pro Max' test
30+
- name: Test large screen device
31+
run: xcodebuild -scheme PermissionsSwiftUI -destination 'platform=iOS Simulator,name=iPhone 12 Pro Max' -only-testing:PermissionsSwiftUITests test
32+
- name: Test small screen device
33+
run: xcodebuild -scheme PermissionsSwiftUI -destination 'platform=iOS Simulator,name=iPod touch (7th generation)' -only-testing:PermissionsSwiftUISmallScreenTests test
3234
Swiftformat:
3335
name: Check swiftformat
3436
runs-on: macos-latest

Package.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,9 @@ let package = Package(
2929
name: "PermissionsSwiftUITests",
3030
dependencies: ["PermissionsSwiftUI","SnapshotTesting"]
3131
),
32+
.testTarget(
33+
name: "PermissionsSwiftUISmallScreenTests",
34+
dependencies: ["PermissionsSwiftUI","SnapshotTesting"]
35+
),
3236
]
3337
)

Sources/PermissionsSwiftUI/Components/Modal-style/MainView.swift

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,36 @@
88
import SwiftUI
99

1010
struct MainView: View {
11-
private var showModal: Binding<Bool>
12-
private var bodyView: AnyView
13-
var shouldShowPermission:Binding<Bool> = Binding(get: {
14-
let store = PermissionStore.shared
15-
if store.autoCheckModalAuth{
16-
return !PermissionStore.shared.permissionsToAsk.isEmpty
17-
}
18-
return true
19-
}, set: {_ in})
20-
init(for bodyView: AnyView, show showModal: Binding<Bool>) {
11+
var showModal: Binding<Bool>
12+
var bodyView: AnyView
13+
var permissionsToAsk: [PermissionType]
14+
var shouldShowPermission:Binding<Bool>{
15+
Binding(get: {
16+
let store = PermissionStore.shared
17+
if store.autoCheckModalAuth{
18+
return !permissionsToAsk.isEmpty
19+
}
20+
return true
21+
}, set: {_ in})
22+
}
23+
init(for bodyView: AnyView,
24+
show showModal: Binding<Bool>,
25+
permissionsToAsk: [PermissionType]=PermissionStore.shared.permissionsToAsk) {
2126
self.bodyView = bodyView
2227
self.showModal = showModal
28+
self.permissionsToAsk = permissionsToAsk
2329
}
24-
30+
2531
var body: some View {
26-
bodyView
27-
.sheet(isPresented: showModal.combine(with: shouldShowPermission), content: {
28-
ModalView(showModal: showModal)
29-
.onAppear(perform: PermissionStore.shared.onAppear)
30-
.onDisappear(perform:PermissionStore.shared.onDisappear)
31-
.onDisappear{showModal.wrappedValue = false}
32-
33-
})
34-
32+
bodyView
33+
.sheet(isPresented: showModal.combine(with: shouldShowPermission), content: {
34+
ModalView(showModal: showModal)
35+
.onAppear(perform: PermissionStore.shared.onAppear)
36+
.onDisappear(perform:PermissionStore.shared.onDisappear)
37+
.onDisappear{showModal.wrappedValue = false}
38+
39+
})
40+
3541
}
3642
//if DEBUG to ensure these functions are never used in production. They are for unit testing only.
3743
#if DEBUG
@@ -44,7 +50,7 @@ struct MainView: View {
4450
onDisappear()
4551
}
4652
#endif
47-
53+
4854
}
4955
//Extension Binding wrapper for Binding booleans
5056
extension Binding where Value == Bool{

Sources/PermissionsSwiftUI/Model/Mocks/MockHealthManager.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class MockHealthManager: HealthManager {
2424
var requestSuccessOverride: Bool = true
2525
static var healthDataAvailableOverride: Bool = true
2626

27+
var requestedPermissions: HKAccess?
2728
var lastStatus: HKAuthorizationStatus = .notDetermined
2829
func authorizationStatus(for type: HKObjectType) -> HKAuthorizationStatus {
2930
switch authStatusOverride {
@@ -59,6 +60,17 @@ class MockHealthManager: HealthManager {
5960
let healthDataAvailable = MockHealthManager.healthDataAvailableOverride
6061
if requestSuccessOverride {
6162
completion(requestSuccessOverride, healthDataAvailable ? nil : fatalError("MockHealthManager - health data is not available"))
63+
guard typesToShare != nil || typesToRead != nil else {return}
64+
if let typesToShare = typesToShare, let typesToRead = typesToRead {
65+
requestedPermissions = .init(read: typesToRead as! Set<HKSampleType>, write: typesToShare)
66+
}
67+
else if let typesToShare = typesToShare {
68+
requestedPermissions = .init(write: typesToShare)
69+
}
70+
else if let typesToRead = typesToRead {
71+
requestedPermissions = .init(read: typesToRead as! Set<HKSampleType>)
72+
}
73+
6274
}
6375
else {
6476
completion(false, NSError(domain: "", code: 0, userInfo: nil))

Sources/PermissionsSwiftUI/Model/Mocks/MockNotificationManager.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ protocol NotificationManager {
1414
func getNotificationSettings(completionHandler: @escaping (UNNotificationSettings) -> Void)
1515
}
1616
extension UNUserNotificationCenter:NotificationManager{
17+
static var isTestingMode = false
1718
static func shared() -> NotificationManager {
18-
return UNUserNotificationCenter.current()
19+
return isTestingMode ? MockNotificationManager.shared() : UNUserNotificationCenter.current()
1920
}
2021
func requestPermission(options: UNAuthorizationOptions=[], completionHandler: @escaping (Bool, Error?) -> Void) {
2122
self.requestAuthorization(options: options) { granted, error in

Sources/PermissionsSwiftUI/Model/PermissionManagers/JMHealthPermissionManager.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ class JMHealthPermissionManager: PermissionManager{
9090
completion(false)
9191
return
9292
}
93-
healthStore.requestAuthorization(toShare: Set(healthPermission?.readPermissions ?? []),
94-
read: Set(healthPermission?.writePermissions ?? [])) { authorized, error in
93+
healthStore.requestAuthorization(toShare: Set(healthPermission?.writePermissions ?? []),
94+
read: Set(healthPermission?.readPermissions ?? [])) { authorized, error in
9595
guard error == nil else{
9696
print("PermissionSwiftUI - \(error!)")
9797
completion(false)

Sources/PermissionsSwiftUI/Model/PermissionManagers/JMLocationPermissionAlwaysManager.swift renamed to Sources/PermissionsSwiftUI/Model/PermissionManagers/JMLocationAlwaysPermissionManager.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
import Foundation
99
import MapKit
1010

11-
class JMLocationPermissionAlwaysManager: NSObject, CLLocationManagerDelegate, PermissionManager {
11+
class JMLocationAlwaysPermissionManager: NSObject, CLLocationManagerDelegate, PermissionManager {
1212

1313
typealias authorizationStatus = CLAuthorizationStatus
14-
typealias permissionManagerInstance = JMLocationPermissionAlwaysManager
14+
typealias permissionManagerInstance = JMLocationAlwaysPermissionManager
1515

16-
static var shared: PermissionManager = JMLocationPermissionAlwaysManager()
16+
static var shared: PermissionManager = JMLocationAlwaysPermissionManager()
1717
var authorizationStatus: AuthorizationStatus{
1818
switch CLLocationManager.authorizationStatus(){
1919
case .authorizedAlways:

Sources/PermissionsSwiftUI/Model/PermissionManagers/JMLocationInUsePermissionManager.swift renamed to Sources/PermissionsSwiftUI/Model/PermissionManagers/JMLocationPermissionManager.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
import Foundation
1010
import MapKit
1111

12-
class JMLocationInUsePermissionManager: NSObject, CLLocationManagerDelegate, PermissionManager {
12+
class JMLocationPermissionManager: NSObject, CLLocationManagerDelegate, PermissionManager {
1313
typealias authorizationStatus = CLAuthorizationStatus
14-
typealias permissionManagerInstance = JMLocationInUsePermissionManager
14+
typealias permissionManagerInstance = JMLocationPermissionManager
1515

16-
static var shared: PermissionManager = JMLocationInUsePermissionManager()
16+
static var shared: PermissionManager = JMLocationPermissionManager()
1717
var authorizationStatus: AuthorizationStatus{
1818
switch locationManager.authorizationStatus(){
1919
case .authorizedAlways:

Sources/PermissionsSwiftUI/Model/PermissionManagers/JMMicPermissionManager.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import AVFoundation
99
import Foundation
1010

11-
struct JMMicPermissionManager: PermissionManager {
11+
struct JMMicrophonePermissionManager: PermissionManager {
1212

13-
static var shared: PermissionManager = JMMicPermissionManager()
13+
static var shared: PermissionManager = JMMicrophonePermissionManager()
1414
var authorizationStatus: AuthorizationStatus{
1515
switch AVCaptureDevice.authorizationStatus(for: .audio){
1616
case .authorized:

Sources/PermissionsSwiftUI/Model/PermissionType/PermissionTypeGetSet.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ extension PermissionType:PermissionTypeProtocol{
100100
func getPermissionManager() -> PermissionManager?{
101101
switch self {
102102
case .location:
103-
return JMLocationPermissionAlwaysManager.shared
103+
return JMLocationPermissionManager.shared
104104
case .locationAlways:
105-
return JMLocationPermissionAlwaysManager.shared
105+
return JMLocationAlwaysPermissionManager.shared
106106
case .photo:
107107
return JMPhotoPermissionManager.shared
108108
case .microphone:
109-
return JMMicPermissionManager.shared
109+
return JMMicrophonePermissionManager.shared
110110
case .camera:
111111
return JMCameraPermissionManager.shared
112112
case .notification:
@@ -139,9 +139,15 @@ extension PermissionType:PermissionTypeProtocol{
139139
extension PermissionType:CaseIterable{
140140
public static var allCases: [PermissionType]{
141141
if #available(iOS 14.5, *) {
142-
return [.location,.locationAlways,.photo,microphone,.camera,.notification,.calendar,.bluetooth,.contacts,.motion,.reminders,.speech,.tracking]
142+
return [.location,.locationAlways,.photo,microphone,.camera,.notification,.calendar,.bluetooth,.contacts,.motion,.reminders,.speech,.tracking, .health(categories: nil)]
143143
} else {
144-
return [.location,.locationAlways,.photo,microphone,.camera,.notification,.calendar,.bluetooth,.contacts,.motion,.reminders,.speech]
144+
return [.location,.locationAlways,.photo,microphone,.camera,.notification,.calendar,.bluetooth,.contacts,.motion,.reminders,.speech, .health(categories: nil)]
145145
}
146146
}
147+
var rawValue: String {
148+
guard let label = Mirror(reflecting: self).children.first?.label else {
149+
return .init(describing: self)
150+
}
151+
return label
152+
}
147153
}

Sources/PermissionsSwiftUI/Model/Utility/FilterPermissions.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
//
22
// FilterPermissions.swift
3-
//
3+
//
44
//
55
// Created by Jevon Mao on 2/19/21.
66
//
77

88
import Foundation
99

10-
struct FilterPermissions{
11-
//Based on struct boolean property, dependent on memory
12-
static func filterForUnauthorized(for permissions:[PermissionType]) -> [PermissionType] {
13-
let filteredPermissions = permissions.filter{$0.currentPermission.authorized==false}
10+
struct FilterPermissions {
11+
// Based on struct boolean property, dependent on memory
12+
static func filterForUnauthorized(for permissions: [PermissionType]) -> [PermissionType] {
13+
let filteredPermissions = permissions.filter { $0.currentPermission.authorized == false }
1414
return filteredPermissions
1515
}
16-
//Based on system API query, independent from memory
17-
static func filterForShouldAskPermission(for permissions:[PermissionType]) -> [PermissionType] {
18-
var filteredPermissions:[PermissionType] = []
19-
for permission in permissions{
20-
if permission.getPermissionManager()?.authorizationStatus == .notDetermined{
16+
17+
// Based on system API query, independent from memory
18+
static func filterForShouldAskPermission(for permissions: [PermissionType]) -> [PermissionType] {
19+
var filteredPermissions: [PermissionType] = []
20+
for permission in permissions {
21+
if permission.getPermissionManager()?.authorizationStatus == .notDetermined {
2122
filteredPermissions.append(permission)
2223
}
2324
}

0 commit comments

Comments
 (0)