Skip to content

Commit

Permalink
Merge pull request #20213 from wordpress-mobile/fix/19755-infinite-ap…
Browse files Browse the repository at this point in the history
…p-redirect
  • Loading branch information
dvdchr authored Feb 28, 2023
2 parents 4609f4c + 324b004 commit 68f6127
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Foundation
enum AppScheme: String {
case wordpress = "wordpress://"
case wordpressMigrationV1 = "wordpressmigration+v1://"
case jetpack = "jetpack://"
}

extension UIApplication {
Expand Down
16 changes: 16 additions & 0 deletions WordPress/Classes/System/WordPressAppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,22 @@ extension WordPressAppDelegate {
return
}

// When a counterpart WordPress/Jetpack app is detected, ensure that the router can handle the URL.
// Passing a URL that the router couldn't handle results in opening the URL in Safari, which will
// cause the other app to "catch" the intent — and leads to a navigation loop between the two apps.
//
// TODO: Remove this after the Universal Link routes for the WordPress app are removed.
//
// Read more: https://github.com/wordpress-mobile/WordPress-iOS/issues/19755
if MigrationAppDetection.isCounterpartAppInstalled {
// If we can handle the URL, then let the UniversalLinkRouter do it.
guard UniversalLinkRouter.shared.canHandle(url: url) else {
// Otherwise, try to convert the URL to a WP Admin link and open it in Safari.
WPAdminConvertibleRouter.shared.handle(url: url)
return
}
}

trackDeepLink(for: url) { url in
UniversalLinkRouter.shared.handle(url: url)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/// A router that handles routes that can be converted to /wp-admin links.
///
/// Note that this is a workaround for an infinite redirect issue between WordPress and Jetpack
/// when both apps are installed.
///
/// This can be removed once we remove the Universal Link routes for the WordPress app.
struct WPAdminConvertibleRouter: LinkRouter {
static let shared = WPAdminConvertibleRouter(routes: [
EditPostRoute()
])

let routes: [Route]
let matcher: RouteMatcher

init(routes: [Route]) {
self.routes = routes
matcher = RouteMatcher(routes: routes)
}

func canHandle(url: URL) -> Bool {
return matcher.routesMatching(url).count > 0
}

func handle(url: URL, shouldTrack track: Bool = false, source: DeepLinkSource? = nil) {
matcher.routesMatching(url).forEach { route in
route.action.perform(route.values, source: nil, router: self)
}
}
}

// MARK: - Routes

struct EditPostRoute: Route {
let path = "/post/:domain/:postID"
let section: DeepLinkSection? = nil
let action: NavigationAction = WPAdminConvertibleNavigationAction.editPost
let jetpackPowered: Bool = false
}

// MARK: - Navigation Action

enum WPAdminConvertibleNavigationAction: NavigationAction {
case editPost

func perform(_ values: [String: String], source: UIViewController?, router: LinkRouter) {
let wpAdminURL: URL? = {
switch self {
case .editPost:
guard let url = blogURLString(from: values),
let postID = postID(from: values) else {
return nil
}

var components = URLComponents(string: "https://\(url)/wp-admin/post.php")
components?.queryItems = [
.init(name: "post", value: postID),
.init(name: "action", value: "edit"),
.init(name: "calypsoify", value: "1")
]
return components?.url
}
}()

guard let wpAdminURL else {
return
}

UIApplication.shared.open(wpAdminURL)
}
}

private extension WPAdminConvertibleNavigationAction {
func blogURLString(from values: [String: String]?) -> String? {
guard let domain = values?["domain"] else {
return nil
}

// First, check if the provided domain is a siteID.
// If it is, then try to look up existing blogs and return the URL instead.
if let siteID = Int(domain) {
let blog = try? Blog.lookup(withID: siteID, in: ContextManager.shared.mainContext)
return blog?.hostURL as? String
}

if let _ = URL(string: domain) {
return domain
}

return nil
}

func postID(from values: [String: String]?) -> String? {
return values?["postID"]
}
}
8 changes: 8 additions & 0 deletions WordPress/Classes/Utility/Universal Links/Route.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ extension NavigationAction {
return false
}

// TODO: This is a workaround. Remove after the Universal Link routes for the WordPress app are removed.
//
// Don't fallback to Safari if the counterpart WordPress/Jetpack app is installed.
// Read more: https://github.com/wordpress-mobile/WordPress-iOS/issues/19755
if MigrationAppDetection.isCounterpartAppInstalled {
return false
}

let noOptions: [UIApplication.OpenExternalURLOptionsKey: Any] = [:]
UIApplication.shared.open(url, options: noOptions, completionHandler: nil)
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ struct UniversalLinkRouter: LinkRouter {
}

if matches.isEmpty {
// TODO: This is a workaround. Remove after the Universal Link routes for the WordPress app are removed.
//
// Don't fallback to Safari if the counterpart WordPress/Jetpack app is installed.
// Read more: https://github.com/wordpress-mobile/WordPress-iOS/issues/19755
if MigrationAppDetection.isCounterpartAppInstalled {
return
}

UIApplication.shared.open(url,
options: [:],
completionHandler: nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ struct MigrationAppDetection {

return .wordPressNotInstalled
}

static var isCounterpartAppInstalled: Bool {
let scheme: AppScheme = AppConfiguration.isJetpack ? .wordpress : .jetpack
return UIApplication.shared.canOpen(app: scheme)
}
}
6 changes: 6 additions & 0 deletions WordPress/WordPress.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -5304,6 +5304,8 @@
FE23EB4C26E7C91F005A1698 /* richCommentStyle.css in Resources */ = {isa = PBXBuildFile; fileRef = FE23EB4826E7C91F005A1698 /* richCommentStyle.css */; };
FE25C235271F23000084E1DB /* ReaderCommentsNotificationSheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE25C234271F23000084E1DB /* ReaderCommentsNotificationSheetViewController.swift */; };
FE25C236271F23000084E1DB /* ReaderCommentsNotificationSheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE25C234271F23000084E1DB /* ReaderCommentsNotificationSheetViewController.swift */; };
FE29EFCD29A91160007CE034 /* WPAdminConvertibleRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE29EFCC29A91160007CE034 /* WPAdminConvertibleRouter.swift */; };
FE29EFCE29A91160007CE034 /* WPAdminConvertibleRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE29EFCC29A91160007CE034 /* WPAdminConvertibleRouter.swift */; };
FE2E3729281C839C00A1E82A /* BloggingPromptsServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE2E3728281C839C00A1E82A /* BloggingPromptsServiceTests.swift */; };
FE320CC5294705990046899B /* ReaderPostBackupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE320CC4294705990046899B /* ReaderPostBackupTests.swift */; };
FE32E7F12844971000744D80 /* ReminderScheduleCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE32E7F02844971000744D80 /* ReminderScheduleCoordinatorTests.swift */; };
Expand Down Expand Up @@ -8987,6 +8989,7 @@
FE23EB4726E7C91F005A1698 /* richCommentTemplate.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = richCommentTemplate.html; path = Resources/HTML/richCommentTemplate.html; sourceTree = "<group>"; };
FE23EB4826E7C91F005A1698 /* richCommentStyle.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; name = richCommentStyle.css; path = Resources/HTML/richCommentStyle.css; sourceTree = "<group>"; };
FE25C234271F23000084E1DB /* ReaderCommentsNotificationSheetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReaderCommentsNotificationSheetViewController.swift; sourceTree = "<group>"; };
FE29EFCC29A91160007CE034 /* WPAdminConvertibleRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WPAdminConvertibleRouter.swift; sourceTree = "<group>"; };
FE2E3728281C839C00A1E82A /* BloggingPromptsServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BloggingPromptsServiceTests.swift; sourceTree = "<group>"; };
FE320CC4294705990046899B /* ReaderPostBackupTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReaderPostBackupTests.swift; sourceTree = "<group>"; };
FE32E7F02844971000744D80 /* ReminderScheduleCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReminderScheduleCoordinatorTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -17476,6 +17479,7 @@
children = (
FE4DC5A2293A75FC008F322F /* MigrationDeepLinkRouter.swift */,
FE4DC5A6293A79F1008F322F /* WordPressExportRoute.swift */,
FE29EFCC29A91160007CE034 /* WPAdminConvertibleRouter.swift */,
);
path = Migration;
sourceTree = "<group>";
Expand Down Expand Up @@ -20949,6 +20953,7 @@
F5D399302541F25B0058D0AB /* SheetActions.swift in Sources */,
93F7214F271831820021A09F /* SiteStatsPinnedItemStore.swift in Sources */,
9895401126C1F39300EDEB5A /* EditCommentTableViewController.swift in Sources */,
FE29EFCD29A91160007CE034 /* WPAdminConvertibleRouter.swift in Sources */,
8B7F51C924EED804008CF5B5 /* ReaderTracker.swift in Sources */,
E6F2788421BC1A4A008B4DB5 /* PlanFeature.swift in Sources */,
931215E4267F5003008C3B69 /* ReferrerDetailsTableViewController.swift in Sources */,
Expand Down Expand Up @@ -22962,6 +22967,7 @@
FABB20CF2602FC2C00C8785C /* PageListViewController.swift in Sources */,
FABB20D02602FC2C00C8785C /* CoreDataHelper.swift in Sources */,
FABB20D12602FC2C00C8785C /* LocalCoreDataService.m in Sources */,
FE29EFCE29A91160007CE034 /* WPAdminConvertibleRouter.swift in Sources */,
FABB20D22602FC2C00C8785C /* AztecNavigationController.swift in Sources */,
FABB20D32602FC2C00C8785C /* Notification+Interface.swift in Sources */,
FABB20D42602FC2C00C8785C /* ReaderSaveForLater+Analytics.swift in Sources */,
Expand Down

0 comments on commit 68f6127

Please sign in to comment.