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

Fix: Make RCTransaction public #315

Merged
merged 9 commits into from
Aug 20, 2020
Merged

Conversation

aboedo
Copy link
Member

@aboedo aboedo commented Aug 14, 2020

Addresses #314

The issue was Transaction was forward-declared, but its implementation wasn't publicly available, so calling purchaserInfo.nonSubscriptionTransactions worked, but trying to access properties of the transaction wouldn't work.

This is the first public Swift file, so figuring out the best path to make it public was sort of tricky, mostly because of the difference in structure we have between most package managers and SPM.
For most package managers, it's only a matter of declaring the type public.

However, since SPM isn't compatible with mixed-language frameworks, we separated its code into an objc and a swift target, with the objc target being the public-facing one, which depends on swift.
The issue there is that a public swift file wouldn't be publicly available.

I tried a few approaches:

  • Keeping the file internal in swift and then providing a public interface for it is a problem for package managers other than SPM because it effectively generates a duplicated symbol. This doesn't happen if both swift and obj parts are internal, but it's a problem if either of the two is public.
  • I tried re-structuring the SPM solution so that a 3rd framework that unifies both parts is the public-facing one, and then using @_exported import PurchasesObjc and @_exported import PurchasesSwift to expose the public stuff in both. That almost worked, but the objc portion won't build for some reason that escapes me.
  • I tried having a header that uses a pre-processor macro so that it's only included in SPM. That didn't work because the pre-processor macros don't get included when used for public stuff, only internal. (See 'HEADER TRAPS' here).

The current approach is to have:

  • the file be public for all package managers.
  • a public objc interface for the file, that's only used by SPM. In order to achive this bit, there's a new folder in Public called SPMSwiftInterfaces, for this purpose. It's automatically included in SPM because it's located in Public.
  • exclude Public/SPMSwiftInterfaces in the podspec
  • exclude the files in that folder from xcode by not including them in the target.

I think at some point we may want to restructure the project so that there's no difference between SPM and other package managers.

@aboedo aboedo self-assigned this Aug 14, 2020
NS_SWIFT_NAME(Purchases.Transaction)
@interface RCTransaction : NSObject

@property (nonatomic, readonly, copy) NSString *revenueCatId;
Copy link
Member Author

Choose a reason for hiding this comment

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

one easy way to generate the code for this file, so that you don't have to manually do the conversion into objc, is to make the file public in swift, then go to derived data and look for Purchases-swift.h. That file is an objc version of the public interface for the framework, you just have to find the class and copy/paste it. then maybe clean it up a bit.

@aboedo aboedo merged commit e71dcd1 into develop Aug 20, 2020
@aboedo aboedo deleted the fix/make_rctransaction_public branch August 20, 2020 18:57
@aboedo aboedo mentioned this pull request Aug 27, 2020
@aboedo aboedo mentioned this pull request Sep 10, 2020
@aboedo aboedo mentioned this pull request Jul 13, 2021
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.

2 participants