Adding some more details based on my current experience: My task is to convert an OBJC codebase from premium to freemium on IOS16, and I want to use the new features of StoreKit2 (originalPurchaseDate and originalAppVersion) in my objective-C code. I'm using the Storekit2 example code (https://developer.apple.com/documentation/storekit/in-app_purchase/implementing_a_store_in_your_app_using_the_storekit_api), especially the file "store.swift", and my problem was to be able to call the functions in that file from my OBJC modules. So here is what helped me:
Create an object in store.swift, and flag it with @objc (see below). As the object is in the swift file, it can call all the swift code. The @objc makes the object visible to the OBJC code as well.
Each property and each function that should be visible to OBJC must be proceeded with "@objc"
import Foundation
import StoreKit
@objc(MySwiftObject)
class MySwiftObject : NSObject {
@objc
var someProperty: AnyObject = "Some Initializer Val" as NSString
override init() {
}
@objc
func someFunction(someArg: Any) -> NSString {
return "You sent me \(someArg)" as NSString
}
@objc
func myAppTransaction() async {
do {
// Get the appTransaction.
if #available(iOS 16.0, *) {
let shared = try await AppTransaction.shared
if case .verified(let appTransaction) = shared {
// Get the major version number of the version the customer originally purchased.
let versionComponents = appTransaction.originalAppVersion.split(separator: ".")
let originalMajorVersion = versionComponents[0]
if originalMajorVersion < "2" {
// This customer purchased the app before the business model changed.
// Deliver content that they're entitled to based on their app purchase.
}
else {
// This customer purchased the app after the business model changed.
}
}
} else {
// Fallback on earlier versions
}
}
catch {
// Handle errors.
}
}
}
To make anything visible in OBJC code, we need an include file, which is auto-generated by the compiler - this was the point that I didn't understand for a long time. The name of the include file is "-Swift.h", for e.g. my app name is "dogwalk", so the include file is named "dogwalk-Swift.h", this is what you can use in the #include statement, no help from autocomplete, you have to type the full statement. See below for the OBJC example code:
#import "dogwalk-Swift.h"
MySwiftObject * myOb = [[MySwiftObject alloc] init];
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
NSString * retString = [myOb someFunctionWithSomeArg:@"my string example"];
NSLog(@"RetString: %@", retString);
[myOb myAppTransactionWithCompletionHandler:^{
NSLog(@"appTransaction completed");
}];
Post
Replies
Boosts
Views
Activity
Same for me, but cannot solve the error:
My app has one target only, based on SwiftUI
In some files I'm using OBJC from UIKit, no problem, app compiles and works well
When exporting localizations, compiler aborts with "error: no such module 'UIKit'"
I don't understand what I should do to solve this. Obviously it finds UIKit, as the app runs fine. Why does exporting localisation not find it? How can I fix it?
Might be as apple engineer you have some future versions on your desktop :-) I'm using Xcode 14.2 currently, no "isPresented" option is shown when typing PhotosPicker ... Or was it removed again?