Skip to content

Commit 4dd436c

Browse files
feat(dev-menu): add the Developer Menu to Amplify (#844)
* feat(amplify-dev-menu): Initial code setup for Amplify Developer Menu (#594) * refactor: Updated protocols for initial setup and added documentation (#615) This PR added documentation to the Developer Menu codebase and added protocols to make it more testable. * feat(device-info-screen): Device Info Screen in Developer Menu (#624) * feat(environment-info-screen): Environment Info Screen in Developer Menu (#637) * feat(log-viewer): Log Viewer Screen in Developer Menu (#653) * feat(report-issue-screen): Report Issue Screen in Developer Menu (#668) * test(dev-menu): Unit tests for Amplify+DevMenu extension (#682) * feat(report-issue-screen): Minimum character limit added for issue de… (#692) * test(dev-menu): Unit tests for PersistentLoggingPlugin and GestureRecognizer (#696) * remove the log output in the issue report Co-authored-by: Abhash Kumar Singh <[email protected]>
1 parent ea9a45f commit 4dd436c

Some content is hidden

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

47 files changed

+2086
-6
lines changed

Amplify.xcodeproj/project.pbxproj

Lines changed: 212 additions & 0 deletions
Large diffs are not rendered by default.

Amplify/Amplify.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ public class Amplify {
6262
"Verify that the library version is correct and supports the plugin's category.")
6363
}
6464
}
65-
6665
}
6766

6867
extension Amplify: DefaultLogger { }

Amplify/Categories/DataStore/DataStoreCategory+HubPayloadEventName.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public extension HubPayload.EventName.DataStore {
4444

4545
/// Dispatched when all models have been synced
4646
static let syncQueriesReady = "DataStore.syncQueriesReady"
47-
47+
4848
/// Dispatched when:
4949
/// - local store has loaded outgoing mutations from local storage
5050
/// - if online, all data has finished syncing with cloud

Amplify/Categories/Logging/LoggingCategory.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ final public class LoggingCategory: Category {
4949
/// Returns the plugin added to the category. Upon creation, the LoggingCategory will have a default plugin and a
5050
/// configuration state reflecting that. Customers can still add custom plugins; doing so will remove the default
5151
/// plugin.
52-
var plugin: LoggingCategoryPlugin = AWSUnifiedLoggingPlugin()
52+
var plugin: LoggingCategoryPlugin = Amplify.getLoggingCategoryPlugin(loggingPlugin: AWSUnifiedLoggingPlugin())
5353

5454
// MARK: - Plugin handling
5555

@@ -77,7 +77,7 @@ final public class LoggingCategory: Category {
7777
throw error
7878
}
7979

80-
configurationState = .pendingConfiguration(plugin)
80+
configurationState = .pendingConfiguration(Amplify.getLoggingCategoryPlugin(loggingPlugin: plugin))
8181
}
8282
}
8383

@@ -103,7 +103,7 @@ final public class LoggingCategory: Category {
103103
guard plugin.key == key else {
104104
return
105105
}
106-
plugin = AWSUnifiedLoggingPlugin()
106+
plugin = Amplify.getLoggingCategoryPlugin(loggingPlugin: AWSUnifiedLoggingPlugin())
107107
}
108108
}
109109

Amplify/Core/Configuration/Internal/Amplify+Reset.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ extension Amplify {
4343
}
4444
}
4545

46+
if #available(iOS 13.0.0, *) {
47+
devMenu = nil
48+
}
49+
4650
group.wait()
4751

4852
// Initialize Logging and Hub first, to ensure their default plugins are registered and available to other
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// Copyright 2018-2020 Amazon.com,
3+
// Inc. or its affiliates. All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
10+
/// Extension of `Amplify` for supporting Developer Menu feature
11+
extension Amplify {
12+
13+
@available(iOS 13.0.0, *)
14+
static var devMenu: AmplifyDevMenu?
15+
16+
@available(iOS 13.0.0, *)
17+
public static func enableDevMenu(contextProvider: DevMenuPresentationContextProvider) {
18+
#if DEBUG
19+
devMenu = AmplifyDevMenu(devMenuPresentationContextProvider: contextProvider)
20+
#else
21+
Logging.warn(DevMenuStringConstants.logTag + "Developer Menu is available only in debug mode")
22+
#endif
23+
24+
}
25+
26+
/// Checks whether developer menu is enabled by developer
27+
@available(iOS 13.0.0, *)
28+
static func isDevMenuEnabled() -> Bool {
29+
return devMenu != nil
30+
}
31+
32+
/// Returns a `PersistentLoggingPlugin` if developer menu feature is enabled in debug mode
33+
static func getLoggingCategoryPlugin(loggingPlugin: LoggingCategoryPlugin) -> LoggingCategoryPlugin {
34+
if #available(iOS 13.0.0, *) {
35+
#if DEBUG
36+
if isDevMenuEnabled() {
37+
return PersistentLoggingPlugin(plugin: loggingPlugin)
38+
} else {
39+
return loggingPlugin
40+
}
41+
#else
42+
return loggingPlugin
43+
#endif
44+
} else {
45+
return loggingPlugin
46+
}
47+
}
48+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// Copyright 2018-2020 Amazon.com,
3+
// Inc. or its affiliates. All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
import UIKit
10+
import SwiftUI
11+
12+
/// Presents a developer menu using the provided `DevMenuPresentationContextProvider`
13+
/// upon notification from a `TriggerRecognizer`. Default recognizer is a `LongPressGestureRecognizer`
14+
@available(iOS 13.0.0, *)
15+
public final class AmplifyDevMenu: DevMenuBehavior, TriggerDelegate {
16+
17+
weak var devMenuPresentationContextProvider: DevMenuPresentationContextProvider?
18+
var triggerRecognizer: TriggerRecognizer?
19+
20+
init(devMenuPresentationContextProvider: DevMenuPresentationContextProvider) {
21+
self.devMenuPresentationContextProvider = devMenuPresentationContextProvider
22+
self.triggerRecognizer = LongPressGestureRecognizer(
23+
uiWindow: devMenuPresentationContextProvider.devMenuPresentationContext())
24+
triggerRecognizer?.updateTriggerDelegate(delegate: self)
25+
}
26+
27+
public func onTrigger(triggerRecognizer: TriggerRecognizer) {
28+
showMenu()
29+
}
30+
31+
public func showMenu() {
32+
guard let rootViewController =
33+
devMenuPresentationContextProvider?.devMenuPresentationContext().rootViewController else {
34+
Amplify.Logging.warn(DevMenuStringConstants.logTag +
35+
"RootViewController of the UIWindow is nil")
36+
return
37+
}
38+
let viewController = UIHostingController(rootView: DevMenuList())
39+
rootViewController.present(viewController, animated: true)
40+
}
41+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// Copyright 2018-2020 Amazon.com,
3+
// Inc. or its affiliates. All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
10+
/// Implement this protocol to support versioning in your plugin
11+
protocol AmplifyVersionable {
12+
var version: String { get }
13+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// Copyright 2018-2020 Amazon.com,
3+
// Inc. or its affiliates. All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
10+
/// Data class for a row shown in the Developer Menu
11+
@available(iOS 13.0.0, *)
12+
struct DevMenuItem: Identifiable {
13+
let id = UUID()
14+
let type: DevMenuItemType
15+
16+
init(type: DevMenuItemType) {
17+
self.type = type
18+
}
19+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// Copyright 2018-2020 Amazon.com,
3+
// Inc. or its affiliates. All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import Foundation
9+
10+
/// Item types for each row in the Developer Menu
11+
enum DevMenuItemType {
12+
case environmentInformation
13+
case deviceInformation
14+
case logViewer
15+
case reportIssue
16+
17+
var stringValue: String {
18+
switch self {
19+
case .environmentInformation:
20+
return "Environment Information"
21+
case .deviceInformation:
22+
return "Device Information"
23+
case .logViewer:
24+
return "Log Viewer"
25+
case .reportIssue:
26+
return "Report Issue"
27+
}
28+
}
29+
30+
// systemName parameter for SFSymbols used in `UIImage(systemName:)` initializer
31+
var iconName: String {
32+
switch self {
33+
case .environmentInformation:
34+
return "globe"
35+
case .deviceInformation:
36+
return "desktopcomputer"
37+
case .logViewer:
38+
return "eyeglasses"
39+
case .reportIssue:
40+
return "exclamationmark.circle"
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)