Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge/release 21.8 finalized into trunk #20243

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5be1d95
Don't bounce to Safari when both apps are installed
dvdchr Feb 24, 2023
06090e9
Add a router to convert eligible routes to WPAdmin
dvdchr Feb 24, 2023
8acd7e4
Return nil if the siteID is not found
dvdchr Feb 24, 2023
324b004
Only convert to wp-admin when the URL cannot be handled
dvdchr Feb 24, 2023
407ff3f
Bump version number
mokagio Feb 27, 2023
851dc30
Add options to migrate the imported WordPress database automatically
wargcm Feb 24, 2023
b91c18b
Fix migration logic in `migrateDataModelsIfNecessary`
wargcm Feb 24, 2023
f353613
Attempt to manually migrate the imported database before using it
wargcm Feb 24, 2023
1f4f9a7
Fix database migration issue with different database models (#20217)
mokagio Feb 28, 2023
5faf182
Merge remote-tracking branch 'origin/release/21.8' into merge/hotfix-…
mokagio Feb 28, 2023
68f6127
Merge pull request #20213 from wordpress-mobile/fix/19755-infinite-ap…
dvdchr Feb 28, 2023
a02f146
Merge 21.7.2 hotfix into 21.8 (#20221)
mokagio Mar 1, 2023
dc5ee77
Release script: Update gutenberg-mobile ref
dcalhoun Mar 1, 2023
a9f3845
docs: Add release note
dcalhoun Mar 1, 2023
c19644a
build: Update Gutenberg ref
dcalhoun Mar 1, 2023
8683b88
Merge pull request #20231 from wordpress-mobile/gutenberg/integrate_r…
dcalhoun Mar 1, 2023
f9ff4f1
Update app translations – `Localizable.strings`
mokagio Mar 3, 2023
637a9a9
Update WordPress metadata translations
mokagio Mar 3, 2023
dde547b
Update Jetpack metadata translations
mokagio Mar 3, 2023
7eb6e88
Bump version number
mokagio Mar 3, 2023
f596f9d
Merge 'origin/trunk' into merge/release-21.8-finalized-into-trunk
mokagio Mar 3, 2023
4388c84
Fix "can" verb conjugation in a comment
mokagio Mar 3, 2023
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
1 change: 1 addition & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* [*] Reader: Add ability to block a followed site. [#20053]
* [*] Reader: Add ability to report a post's author. [#20064]
* [*] [internal] Refactored the topic related features in the Reader tab (i.e. following, unfollowing, and search). [#20150]
* [*] Fix inaccessible block settings within the unsupported block editor [https://github.com/WordPress/gutenberg/pull/48435]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


21.7
-----
Expand Down
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 can'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
69 changes: 35 additions & 34 deletions WordPress/Classes/Utility/ContextManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,41 @@ public class ContextManager: NSObject, CoreDataStack, CoreDataStackSwift {
save(context, .asynchronously)
}
}

static func migrateDataModelsIfNecessary(storeURL: URL, objectModel: NSManagedObjectModel) throws {
guard FileManager.default.fileExists(atPath: storeURL.path) else {
DDLogInfo("No store exists at \(storeURL). Skipping migration.")
return
}

guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: storeURL),
!objectModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata)
else {
return
}

DDLogWarn("Migration required for persistent store.")

guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd") else {
fatalError("Can't find WordPress.momd")
}

guard let versionInfo = NSDictionary(contentsOf: modelFileURL.appendingPathComponent("VersionInfo.plist")) else {
fatalError("Can't get the object model's version info")
}

guard let modelNames = (versionInfo["NSManagedObjectModel_VersionHashes"] as? [String: AnyObject])?.keys else {
fatalError("Can't parse the model versions")
}

let sortedModelNames = modelNames.sorted { $0.compare($1, options: .numeric) == .orderedAscending }
try CoreDataIterativeMigrator.iterativeMigrate(
sourceStore: storeURL,
storeType: NSSQLiteStoreType,
to: objectModel,
using: sortedModelNames
)
}
}

// MARK: - Private methods
Expand Down Expand Up @@ -236,40 +271,6 @@ private extension ContextManager {
return persistentContainer
}

static func migrateDataModelsIfNecessary(storeURL: URL, objectModel: NSManagedObjectModel) throws {
guard FileManager.default.fileExists(atPath: storeURL.path) else {
DDLogInfo("No store exists at \(storeURL). Skipping migration.")
return
}

guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: storeURL),
objectModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata)
else {
return
}

DDLogWarn("Migration required for persistent store.")

guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd") else {
fatalError("Can't find WordPress.momd")
}

guard let versionInfo = NSDictionary(contentsOf: modelFileURL.appendingPathComponent("VersionInfo.plist")) else {
fatalError("Can't get the object model's version info")
}

guard let modelNames = (versionInfo["NSManagedObjectModel_VersionHashes"] as? [String: AnyObject])?.keys else {
fatalError("Can't parse the model versions")
}

let sortedModelNames = modelNames.sorted { $0.compare($1, options: .numeric) == .orderedAscending }
try CoreDataIterativeMigrator.iterativeMigrate(
sourceStore: storeURL,
storeType: NSSQLiteStoreType,
to: objectModel,
using: sortedModelNames
)
}
}

extension ContextManager {
Expand Down
15 changes: 14 additions & 1 deletion WordPress/Classes/Utility/CoreDataHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,19 @@ extension CoreDataStack {
throw ContextManager.ContextManagerError.missingDatabase
}

try? migrateDatabaseIfNecessary(at: databaseLocation)

mainContext.reset()
try storeCoordinator.remove(store)
let databaseReplaced = replaceDatabase(from: databaseLocation, to: currentDatabaseLocation)

do {
let options = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
try storeCoordinator.addPersistentStore(ofType: NSSQLiteStoreType,
configurationName: nil,
at: currentDatabaseLocation)
at: currentDatabaseLocation,
options: options)

if databaseReplaced {
// The database was replaced successfully and the store added with no errors so we
Expand Down Expand Up @@ -327,4 +332,12 @@ extension CoreDataStack {
_ = try? FileManager.default.replaceItemAt(locationShm, withItemAt: shmBackup)
_ = try? FileManager.default.replaceItemAt(locationWal, withItemAt: walBackup)
}

private func migrateDatabaseIfNecessary(at databaseLocation: URL) throws {
guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd"),
let objectModel = NSManagedObjectModel(contentsOf: modelFileURL) else {
return
}
try ContextManager.migrateDataModelsIfNecessary(storeURL: databaseLocation, objectModel: objectModel)
}
}
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)
}
}
Loading