Post

Replies

Boosts

Views

Activity

Reply to Unable to build project for localization string extraction
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?
Jan ’23
Reply to Call swift code from objc code in objc project
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"); }];
Dec ’22