Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions shared/ios/Keybase.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
DBDF89F62DF7779900EA18C2 /* Pusher.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBDF89F52DF7779900EA18C2 /* Pusher.swift */; };
DBF123462DF1234500A12345 /* ShareIntentDonatorImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF123452DF1234500A12345 /* ShareIntentDonatorImpl.swift */; };
DBPERF022600000002 /* PerfFPSMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBPERF022600000001 /* PerfFPSMonitor.swift */; };
DBSCENE00270000000000002 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBSCENE00270000000000001 /* SceneDelegate.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -120,6 +121,7 @@
DBDF89F52DF7779900EA18C2 /* Pusher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pusher.swift; sourceTree = "<group>"; };
DBF123452DF1234500A12345 /* ShareIntentDonatorImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareIntentDonatorImpl.swift; sourceTree = "<group>"; };
DBPERF022600000001 /* PerfFPSMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerfFPSMonitor.swift; sourceTree = "<group>"; };
DBSCENE00270000000000001 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
F68DC40B579A1F9AC0F34950 /* Pods_KeybaseShare.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KeybaseShare.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -270,6 +272,7 @@
children = (
005BF9961BB9C6B000BD8953 /* Keybase.entitlements */,
DBB8CC202DF336C200D43215 /* AppDelegate.swift */,
DBSCENE00270000000000001 /* SceneDelegate.swift */,
DBDCF3081B8D03DD00BA95D8 /* Images.xcassets */,
DBDCF3091B8D03DD00BA95D8 /* Info.plist */,
DB07050422E21B8B002F273D /* KeepThisFile.swift */,
Expand Down Expand Up @@ -592,6 +595,7 @@
buildActionMask = 2147483647;
files = (
DBB8CC212DF336C200D43215 /* AppDelegate.swift in Sources */,
DBSCENE00270000000000002 /* SceneDelegate.swift in Sources */,
DB07050522E21B8B002F273D /* KeepThisFile.swift in Sources */,
DBDF89F62DF7779900EA18C2 /* Pusher.swift in Sources */,
DBF123462DF1234500A12345 /* ShareIntentDonatorImpl.swift in Sources */,
Expand Down
109 changes: 45 additions & 64 deletions shared/ios/Keybase/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,13 @@ import os

private let log = Logger(subsystem: "com.keybase.app", category: "delegate")

class KeyboardWindow: UIWindow {
override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
guard let key = presses.first?.key else {
super.pressesBegan(presses, with: event)
return
}

if key.keyCode == .keyboardReturnOrEnter {
if key.modifierFlags.contains(.shift) {
NotificationCenter.default.post(name: NSNotification.Name("hardwareKeyPressed"),
object: nil,
userInfo: ["pressedKey": "shift-enter"])
} else {
NotificationCenter.default.post(name: NSNotification.Name("hardwareKeyPressed"),
object: nil,
userInfo: ["pressedKey": "enter"])
}
return
}

super.pressesBegan(presses, with: event)
}
}

@main
class AppDelegate: ExpoAppDelegate, UNUserNotificationCenterDelegate, UIDropInteractionDelegate {
class AppDelegate: ExpoAppDelegate, ExpoReactNativeFactoryProvider, UNUserNotificationCenterDelegate, UIDropInteractionDelegate {
var window: UIWindow?

var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
var reactNativeFactory: RCTReactNativeFactory?
var reactNativeFactoryModuleName: String { "Keybase" }

var resignImageView: UIImageView?
var fsPaths: [String: String] = [:]
Expand Down Expand Up @@ -89,15 +66,6 @@ class AppDelegate: ExpoAppDelegate, UNUserNotificationCenterDelegate, UIDropInte
reactNativeDelegate = delegate
reactNativeFactory = factory

#if os(iOS) || os(tvOS)
let screenBounds = (UIApplication.shared.connectedScenes.first as? UIWindowScene)?.screen.bounds ?? UIScreen.main.bounds
window = KeyboardWindow(frame: screenBounds)
factory.startReactNative(
withModuleName: "Keybase",
in: window,
launchOptions: launchOptions)
#endif

self.writeStartupTimingLog("After RN init")
self.closeStartupLogFile()

Expand All @@ -106,31 +74,33 @@ class AppDelegate: ExpoAppDelegate, UNUserNotificationCenterDelegate, UIDropInte
// Start FPS monitoring if launched with -PERF_FPS_MONITOR
PerfFPSMonitor.startIfEnabled()

if let rootView = self.window?.rootViewController?.view {
self.addDrop(rootView)
self.didLaunchSetupAfter(application: application, rootView: rootView)
}
self.didLaunchSetupAfter(application: application)

return true
}

// Linking API
override func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
}
// Hardware keyboard enter/shift-enter reaches the app delegate at the end of the
// responder chain (window -> scene -> application -> delegate).
override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
guard let key = presses.first?.key else {
super.pressesBegan(presses, with: event)
return
}

// Universal Links
override func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
if key.keyCode == .keyboardReturnOrEnter {
if key.modifierFlags.contains(.shift) {
NotificationCenter.default.post(name: NSNotification.Name("hardwareKeyPressed"),
object: nil,
userInfo: ["pressedKey": "shift-enter"])
} else {
NotificationCenter.default.post(name: NSNotification.Name("hardwareKeyPressed"),
object: nil,
userInfo: ["pressedKey": "enter"])
}
return
}

super.pressesBegan(presses, with: event)
}

/////// KB specific
Expand Down Expand Up @@ -249,13 +219,26 @@ class AppDelegate: ExpoAppDelegate, UNUserNotificationCenterDelegate, UIDropInte
UNUserNotificationCenter.current().delegate = self
}

func didLaunchSetupAfter(application: UIApplication, rootView: UIView) {
// BGTaskScheduler.register must run before didFinishLaunching returns, so this
// can't wait for the scene to connect.
func didLaunchSetupAfter(application: UIApplication) {
notifyAppState(application)

BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.keybase.app.refresh", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
scheduleAppRefresh()
}

// Called by SceneDelegate once the window exists and React Native has started in it.
func didStartReactNative(in window: UIWindow) {
guard let rootView = window.rootViewController?.view else { return }
addDrop(rootView)

rootView.backgroundColor = .systemBackground

// Snapshot resizing workaround for iPad
let screenBounds = self.window?.windowScene?.screen.bounds ?? UIScreen.main.bounds
let screenBounds = window.windowScene?.screen.bounds ?? window.bounds
var dim = screenBounds.width
if screenBounds.height > dim {
dim = screenBounds.height
Expand All @@ -266,12 +249,7 @@ class AppDelegate: ExpoAppDelegate, UNUserNotificationCenterDelegate, UIDropInte
self.resignImageView?.alpha = 0
self.resignImageView?.backgroundColor = rootView.backgroundColor
self.resignImageView?.image = UIImage(named: "LaunchImage")
if let view = self.resignImageView { self.window?.addSubview(view) }

BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.keybase.app.refresh", using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
scheduleAppRefresh()
if let view = self.resignImageView { window.addSubview(view) }
}

func addDrop(_ rootView: UIView) {
Expand All @@ -295,7 +273,8 @@ class AppDelegate: ExpoAppDelegate, UNUserNotificationCenterDelegate, UIDropInte
self.iph = ItemProviderHelper(forShare: false, withItems: [items]) { [weak self] in
guard let self else { return }
let url = URL(string: "keybase://incoming-share")!
_ = self.application(UIApplication.shared, open: url, options: [:])
let app = UIApplication.shared
_ = self.application(app, open: url, options: [:]) || RCTLinkingManager.application(app, open: url, options: [:])
self.iph = nil
}
self.iph?.startProcessing()
Expand Down Expand Up @@ -469,7 +448,9 @@ class AppDelegate: ExpoAppDelegate, UNUserNotificationCenterDelegate, UIDropInte
log.info("applicationDidBecomeActive: hiding keyz screen.")
hideCover()
log.info("applicationDidBecomeActive: notifying service.")
notifyAppState(application)
// Forwarded from sceneDidBecomeActive, where applicationState still reads
// .inactive; notifyAppState would stop the http server.
Keybasego.KeybaseSetAppStateForeground()

// Re-emit a notification the user tapped while React Native wasn't ready yet.
KbEmitStoredNotificationOnBecomeActive()
Expand Down
17 changes: 17 additions & 0 deletions shared/ios/Keybase/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,23 @@
<string>SourceCodePro-Semibold.ttf</string>
<string>kb.ttf</string>
</array>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.keybase.app.refresh</string>
Expand Down
18 changes: 18 additions & 0 deletions shared/ios/Keybase/SceneDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
internal import Expo
import UIKit

@objc(SceneDelegate)
class SceneDelegate: ExpoAppSceneDelegate {
override func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
super.scene(scene, willConnectTo: session, options: connectionOptions)

guard let window = self.window,
let appDelegate = UIApplication.shared.delegate as? AppDelegate
else { return }
appDelegate.didStartReactNative(in: window)
}
}