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

Automatic loading of PFObject subclasses does not work on Xcode 16 / iOS 18 #1792

Closed
4 tasks done
mman opened this issue Jun 17, 2024 · 19 comments · Fixed by #1811
Closed
4 tasks done

Automatic loading of PFObject subclasses does not work on Xcode 16 / iOS 18 #1792

mman opened this issue Jun 17, 2024 · 19 comments · Fixed by #1811
Labels
bounty:$100 Bounty applies for fixing this issue (Parse Bounty Program) state:released Released as stable version type:bug Impaired feature or lacking behavior that is likely assumed

Comments

@mman
Copy link
Contributor

mman commented Jun 17, 2024

New Issue Checklist

Issue Description

Parse iOS / OSX SDK uses PFObject instances for basically everything. All subclasses of PFObject are represented in MongoDB/PostgreSQL as collections/tables with given names. Mapping of the PFObject subclasses and their names in MongoDB/PostreSQL need to be known to Parse SDK so that PFObject subclasses can be loaded/stored properly to the database.

Originally registration of all classes was needed to be done manually by invoking code like this after initialising the Parse SDK:

[PFInstallation registerSubclass];
[PFUser registerSublcass];
[PFSession registerSubclass];

Then came #967 that made things much simpler by scanning executable bundles (read frameworks) for all classes that are subclassing PFObject and registering them during SDK startup automatically.

The code is here:

classNames = objc_copyClassNamesForImage(potentialPaths[i], &bundleClassCount);
if (bundleClassCount) {
break;
}

Building with Xcode 16 seems to break the functionality because objc_copyClassNamesForImage returns nothing.

More investigation is needed. I have not yet been able to see if this is a compiler option that needs to be toggled, or some new measure preventing apps from examining available runtime classes and their properties via Objective-C runtime reflection.

Steps to reproduce

Recompile your app with Xcode 16 and try to run against iOS 18. And see if that works for you.

It fails for me with unrelated error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid class name. Class names cannot start with an underscore.'

This is actually an exception coming from deep inside the Parse SDK where it tries to instantiate PFInstallation with collection name _Installation and failing because PFInstallation class was not registered.

Actual Outcome

Recompiling working code using Xcode 16 breaks the app.

Workaround

For the moment registering all required classes manually seems to work around the problem:

        Parse.initialize(
            with: ParseClientConfiguration() { config in
                
                config.applicationId = .apiAppIdString
                config.clientKey = .apiKeyString
                config.server = .apiURLString
                config.applicationGroupIdentifier = .appGroup
                config.networkRetryAttempts = 2

        })

        PFInstallation.registerSubclass()
        PFUser.registerSubclass()
        PFSession.registerSubclass()

Environment

Client

  • Parse ObjC SDK version: master

Server

  • Parse Server version: master
Copy link

Thanks for opening this issue!

  • 🚀 You can help us to fix this issue faster by opening a pull request with a failing test. See our Contribution Guide for how to make a pull request, or read our New Contributor's Guide if this is your first time contributing.

@mtrezza mtrezza added type:bug Impaired feature or lacking behavior that is likely assumed bounty:$20 Bounty applies for fixing this issue (Parse Bounty Program) labels Jun 20, 2024
@mtrezza mtrezza pinned this issue Jun 28, 2024
@mtrezza mtrezza added bounty:$50 Bounty applies for fixing this issue (Parse Bounty Program) and removed bounty:$20 Bounty applies for fixing this issue (Parse Bounty Program) labels Jul 26, 2024
@justasza
Copy link

Im getting subclassing error with 4.1.1 version.
'The class PFPin must be registered with registerSubclass before using Parse.'
Could this be related?
Provided workaround would not work, because PFPin is internal.

@rgomesbr
Copy link

rgomesbr commented Sep 9, 2024

Same as @justasza here; running Xcode 16 RC — Version 16.0 (16A242)
"The class PFPin must be registered with registerSubclass before using Parse."

@mtrezza mtrezza added bounty:$100 Bounty applies for fixing this issue (Parse Bounty Program) and removed bounty:$50 Bounty applies for fixing this issue (Parse Bounty Program) labels Sep 10, 2024
@mtrezza
Copy link
Member

mtrezza commented Sep 10, 2024

Bumping bounty given the impact of this issue. Anyone wants to take a look at this?

@mapierce
Copy link

Hey @mtrezza I believe my linked PR should solve the issue

@mobinzk
Copy link

mobinzk commented Sep 19, 2024

Hey @mtrezza I believe my linked PR should solve the issue

I've tested your code and it did fix the issue for me. Looking forward to this get merged.

@Satyam-Tripathi-89
Copy link

Please merge this PR asap.

@Satyam-Tripathi-89
Copy link

The class PFPin must be registered with registerSubclass before using Parse.

I am getting this error. Is there any workaround for it?

@dhoerl
Copy link

dhoerl commented Sep 25, 2024

A closed Issue had the information on how to get Xcode to run with the Parse Swift Package, but its not here in this thread.

Copying this from a closed Issue:
When adding Parse-SDK using Swift Package Manager use this commit d2b9580db7ce44d6d4d0f626d5e388901f81f5ed instead of the latest 4.1.1 version.

Also - you do not need any "registerSubClass()" statements - this commit is all you need.

@mtrezza
Copy link
Member

mtrezza commented Sep 25, 2024

The issue mentioned above is #1809 (comment).

@toto
Copy link
Contributor

toto commented Sep 27, 2024

@dhoerl Note that this works for compiling for Simulator/Device in DEBUG it still breaks if SwiftUI Previews so something more is :/

@dhoerl
Copy link

dhoerl commented Sep 27, 2024

I’m using it with Production and it’s fine.

@KaitoKid
Copy link

KaitoKid commented Oct 8, 2024

I've been able to verify that the commit hash mentioned by dhoerl does indeed work

@mtrezza
Copy link
Member

mtrezza commented Oct 8, 2024

Could someone try out #1811 whether it fixes the issue? Also for SwiftUI previews, @toto?

Using a commit hash won't help much in the long term. We have 2 PRs open in attempts to fix this:

@Jaycyn
Copy link

Jaycyn commented Oct 11, 2024

Just tried #1811 and it seems to work

I was able to remove all of the .registerSubclass() calls and the

The class PFPin must be registered with registerSubclass before using Parse

is not being thrown.

So the initialization called per the below code seems good.

override func viewDidLoad() {
    super.viewDidLoad()

    let parseConfig = ParseClientConfiguration {
        $0.applicationId = "parseApplicationId"
        $0.clientKey = "parseClientKey"
        $0.server = "http://somehost:1337/parse"
        $0.isLocalDatastoreEnabled = true
    }

    Parse.initialize(with: parseConfig)
}

XCode 16, macOS Sonoma.

@mtrezza
Copy link
Member

mtrezza commented Oct 12, 2024

Could @toto or someone else confirm that this also works for SwiftUI previews?

@toto
Copy link
Contributor

toto commented Oct 13, 2024

@mtrezza I can confirm it #1811 also fixes the SwiftUI preview issue 👍

@mtrezza
Copy link
Member

mtrezza commented Oct 14, 2024

Great; I'll go ahead and merge

@parseplatformorg
Copy link
Contributor

🎉 This change has been released in version 4.1.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bounty:$100 Bounty applies for fixing this issue (Parse Bounty Program) state:released Released as stable version type:bug Impaired feature or lacking behavior that is likely assumed
Projects
None yet