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

Abstract ContextManager usages behind CoreDataStack #24191

Draft
wants to merge 2 commits into
base: trunk
Choose a base branch
from

Conversation

mokagio
Copy link
Contributor

@mokagio mokagio commented Mar 11, 2025

Part of #24165


Problem I can't move AbstractPost and other Objective-C models in WordPressDataObj because they access ContextManager which is defined in the Swift WordPressData.

Solution Decouple from knowing about a specific type (ContextManager) and use a protocol instead (CoreDataStack). This came with a few compromises (see inline comments) but I think it got the job done relatively clean.

I tested this by running Jetpack on my iPhone and doing a smoke test checking the various tabs.


An alternative solution if we run into more Swift leakages into Objective-C would be to backtrack and create a framework target where we can have mixed languages. I might set aside some time today to search for #import "WordPress-Swift.h" usages and see how much extra steps like this would be needed if we kept the packages setup.

@dangermattic
Copy link
Collaborator

1 Message
📖 This PR is still a Draft: some checks will be skipped.

Generated by 🚫 Danger

@mokagio mokagio force-pushed the mokagio/abstract-contextmanager branch from c4bae80 to 963f98e Compare March 11, 2025 22:26
Comment on lines -22 to +26
@objc init(contextManager: ContextManager) {
self.coreDataStack = contextManager
@objc init(contextManager: CoreDataStack) {
guard let typeCastStack = contextManager as? CoreDataStackSwift else {
fatalError("Expected a CoreDataStackSwift-conforming type even though this initializer is marked @objc.")
}
self.coreDataStack = typeCastStack
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not proud of this one. I don't know if there's a neater way to go about it because if CoreDataStackSwift could be defined in Objective-C, then we wouldn't have needed it in the first place.

Luckily, this hack has to be used only twice, so I think we can live with it...?

Of course, one possible solution would be to convert the Objective-C consumers to Swift... But I think we ought to focus on moving forward with the Core Data migration at the moment.

Copy link
Contributor

Choose a reason for hiding this comment

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

IMO, it'd be okay to remove the argument and use the shared instance internally.

ContextManager.shared.resetEverything()
//
// We can afford to force cast here because we are in a test-specific code
(ContextManager.shared as! ContextManager).resetEverything()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In particular, this code will run only in the UI tests and only if a certain launch argument is given

https://github.com/wordpress-mobile/WordPress-iOS/pull/24191/files#diff-666427fc460fbbf821022ce337766cb3f1f3e56a2900c16e041d0fb28c51ae19L26-L28

@@ -17,7 +18,7 @@ extension Blog {

static func createRestApiBlog(
with details: WpApiApplicationPasswordDetails,
in contextManager: ContextManager,
in contextManager: CoreDataStackSwift,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In this PR, I decided not to rename the contextManager variable that now have CoreDataStackSwift to keep the diff smaller.

We might want to do it later on, but it does not seem urgent.

@mokagio mokagio changed the title Replace all ContextManager sharedInstance() usages with shared Abstract ContextManager usages behind CoreDataStack Mar 11, 2025
@wpmobilebot
Copy link
Contributor

wpmobilebot commented Mar 11, 2025

WordPress Alpha📲 You can test the changes from this Pull Request in WordPress Alpha by scanning the QR code below to install the corresponding build.
App NameWordPress Alpha WordPress Alpha
ConfigurationRelease-Alpha
Build Numberpr24191-cb9162d
Version25.8
Bundle IDorg.wordpress.alpha
Commitcb9162d
App Center BuildWPiOS - One-Offs #11635
Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.

@wpmobilebot
Copy link
Contributor

wpmobilebot commented Mar 11, 2025

Jetpack Alpha📲 You can test the changes from this Pull Request in Jetpack Alpha by scanning the QR code below to install the corresponding build.
App NameJetpack Alpha Jetpack Alpha
ConfigurationRelease-Alpha
Build Numberpr24191-cb9162d
Version25.8
Bundle IDcom.jetpack.alpha
Commitcb9162d
App Center Buildjetpack-installable-builds #10666
Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.

Copy link
Contributor

@crazytonyli crazytonyli left a comment

Choose a reason for hiding this comment

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

Sorry if I missed the discussion, but any reason not moving ContextManager into WordPressData too?

Comment on lines -22 to +26
@objc init(contextManager: ContextManager) {
self.coreDataStack = contextManager
@objc init(contextManager: CoreDataStack) {
guard let typeCastStack = contextManager as? CoreDataStackSwift else {
fatalError("Expected a CoreDataStackSwift-conforming type even though this initializer is marked @objc.")
}
self.coreDataStack = typeCastStack
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO, it'd be okay to remove the argument and use the shared instance internally.

@mokagio
Copy link
Contributor Author

mokagio commented Mar 12, 2025

@crazytonyli

Sorry if I missed the discussion, but any reason not moving ContextManager into WordPressData too?

ContextManager will eventually go into WordPressData, yes. (Current broken WIP PR that reveals all these issues #24166)

@crazytonyli
Copy link
Contributor

I wonder whether moving ContextManager first would be easier for moving the managed objects. Like, this decoupling refactor would not be necessary if ContextManager is already in WordPressData.

@mokagio
Copy link
Contributor Author

mokagio commented Mar 12, 2025

this decoupling refactor would not be necessary if ContextManager is already in WordPressData.

I think it would still be necessary if we have WordPressData the Swift package + WordPressDataObjC the Swift package with only Objective-C files. Because WordPressData depends on WordPressDataObjC, and therefore WordPressDataObjC cannot depend on WordPressData. But ContextManager is in WordPressData and the AbstractPost in WordPressDataObjc.

@mokagio
Copy link
Contributor Author

mokagio commented Mar 12, 2025

@crazytonyli your question actually made me realize that some of the models are Objective-C and others are Swift. I'll need to quickly verify whether they can work sparse between the two packages, or if I should just call it quits on the package and use a framework instead :/

mokagio added 2 commits March 12, 2025 15:04
This is to decouple the Objective-C implementation from knowing about
components (i.e. `ContextManager`) in the Swift layer.
@mokagio mokagio force-pushed the mokagio/abstract-contextmanager branch from 963f98e to cb9162d Compare March 12, 2025 04:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants