Hi,
I have a paid macOS app available in the Mac App Store for the past few years, and I'm looking into converting it into a freemium app. I wanted to add a check to see if the app was purchased legitimately or not, since I know there's a lot of pirated copies available on the internet.
I just did some basic analytics with the app already on the store, the app receipt validation fails because there's no file found at the receipt URL location. I'm just doing this basic check and it fails for a lot of the cases ....
NSURL *receiptURL = [NSBundle mainBundle].appStoreReceiptURL;
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:receiptURL.path isDirectory:nil];
Does this signify that the user has a non-AppStore copy of the app? Or could the receipt be missing for other legitimate reasons? Do I have to make a call to refresh the receipt to confirm this (as I would on iOS)?
Again, this is for an existing app on the Mac App Store, not testing for sandbox users.
Thanks.
Post
Replies
Boosts
Views
Activity
Hi,
I have been using the BackgroundTasks API on iOS for a while, and it works great. I want to do something similar on macOS, where I can easily run some background process from my app every X minutes, even if the app is closed. My Mac app runs in the sandbox, and isn't Catalyst-based, so I can't run the UIKit 'BackgroundTasks' API, and I haven't found anything similar on macOS. Does something like that exist, that is easy to adopt?
I want to test my UNUserNotificationCenter authorization workflow for my MacOS app. I can't seem to find a way to reset the authorization status to notDetermined again. tccutil doesn't seem to contain any options for this. Any suggestions?
I have been using CLGeocoder’s “geocodePostalAddress” API for many years, and it’s been working just fine. Since yesterday, a lot of users have started complaining that they are getting “no results” for their geocoding requests, and I have also confirmed this case. It seems like the “geocodePostalAddress” returns “No Result” in many cases where it used to work correctly before, even though the “geocodeAddressString” API still works correctly. Has anyone else noticed this problem? Has there been some server change that is causing this?
Here's a unit test I wrote to test this out:
import CoreLocation
final class CJTestCLGeocoderRequests: XCTestCase {
func testGeocoderWithCNPostalAddressBerkeley() async throws {
let geocoder = CLGeocoder()
do {
let postalAddress = CNMutablePostalAddress()
postalAddress.street = "2300 College Ave"
postalAddress.city = "Berkeley"
postalAddress.state = "CA"
postalAddress.postalCode = "94108"
postalAddress.country = "United States"
let placemarks3 = try await geocoder.geocodePostalAddress(postalAddress)
XCTAssertTrue(placemarks3.count > 0, "Geocoder works and gets an placemark")
XCTAssertTrue(placemarks3.first?.postalCode == "94108", "Geocode placemark has right postal code")
} catch {
XCTFail("Geocoder failed: placemarks = \(error).") // get failure here, with error code 8 (
}
do {
let collegeAveString = "2300 College Ave, Berkeley, CA, 94704, United States"
let placemarksString = try await geocoder.geocodeAddressString(collegeAveString)
XCTAssertTrue(placemarksString.count > 0, "Geocoder works and gets an placemark")
XCTAssertTrue(placemarksString.first?.postalCode == "94704", "Geocode placemark has right postal code")
} catch {
XCTFail("Geocoder failed: placemark string = \(error).")
}
}
Would love any help regarding this.
I recently had to make a change to my Mac app where I need to add a special "Contact Notes" entitlement, so that means that I can't rely on "Automatic Code Signing" anymore. So here are the steps I took to build and distribute the app with manual code signing:
from "Certificates, Identifiers & Profiles" from the Developer, I added entitlement to my app identifier, and then created new manual provisioning profiles (one for "macOS App Development" under Development, and one for "Mac App Store" under Distribution)
in Xcode, added the entitlement to the Entitlements files
in Xcode, in Signing & Capabilities, unselected the checkbox for "Automatically manage signing", and under "Provisioning Profile", for both Debug and Release builds, I chose to import the new provisioning profiles that were created
I can build and run in debug mode, and it works fine. I then created an 'archive' of the app, which also built fine, and opened up Organizer.
In Organizer, I choose the "Distribute" button, select "App Store Connect" as the distribution method, and choose "Upload" as the destination. After it prepares the archive, it shows the usual two checkboxes for "upload app symbols" and "manage version and build number", and I select Next.
Till now, everything works as expected.
Now I get the "Select certificates and Mac App Store profiles" page ... here, for the dropdowns for my app's targets, I select the correct provisioning profiles. BUT .. the "Next" button never next gets enabled, so I can't move forward! There's no error message, or anything in Console that makes sense to me. But I just can't seem to be able to select "Next" to the final step before uploading the build to App Store Connect.
When I went back and selected "Automatically manage signing" again, and build and archive, the new archive doesn't have this step again, so it works fine and goes to the final upload page.
What can I do to find out the issue that's causing this page to not validate? Can I upload the archive build through some other way (like from Terminal) that might give more information?
NEVERMIND: turns out, I needed to "Mac Installer Distribution" Certificate, which I generated from the dropbox.
Hi,
With StoreKit2 giving us the up-to-date subscription status using Transaction.currentEntitlements, is there any value in storing the status separately in keychain as well? Or will that just add an unnecessary layer to manage (and possibly mess up)? I just want to subscription status to know if I need to unlock certain features in the app or not, and wondering if just looking at currentEntitlements and saving that in my Store object is enough.
Thanks.
The iPhone 14 Pro has a A16 Bionic chip with 16 Billion transistors, two performance cores + 4 high-efficiency cores, a 5-core GPU and 16-core neural engine, and can perform 4 trillion OPS per photo. But sadly, we can only schedule up to 64 User Notifications on it (per app). This limitation has been there since iOS3 I believe, when UILocalNotifications were first introduced, along with the iPhone 3G.
What gives? Why does this limit never seem to change? I would love to understand the reasons. I am trying to build a 'timer' app, and can't understand how to build one with this limitation in place (unless I use Remote Push notifications, which requires a lot of infrastructure outside the app).
Btw, I filed a Radar for this 5 years ago, which was changed to this Feedback Request: FB5978935
Hi,
Is DataScannerViewController available to be called directly from Objective-C? I see the header file has an "objc" attribute on it, but trying to initialize it from an Objective-C file doesn't seem to be working for me. Maybe it's something I'm doing wrong, but I wanted to first clarify and confirm that if it indeed possible to use it directly in Objective-C, or not?
Hi,
I want to work with some of the new iOS16 APIs while maintaining backward compatibility with iOS15 as well as Xcode 13. I'm running into a problem here that I can't seem to store the new iOS16 API as a property of an existing class.
For e.g. I'm interested in using the new DataScannerViewController and want to store it as a property so I can reference it when scanning. If I declare it in my ViewController:
var dataScanner: DataScannerViewController?
it won't compile with Xcode13. I can't seem to also mark this with @available or #available(iOS 16) either:
if #available(iOS 16, *) {
var dataScanner: DataScannerViewController?
}
What's the best way to handle this? In Objective-C, we could use __IPHONE_OS_VERSION_MIN_REQUIRED or something to that effect to avoid this problem, but I'm not sure what the best Swift solution is.
Hi,
The presentation "Capture Machine Readable Codes and Text with VisionKit" mentions at the end that the DataScannerViewController can be used with an async stream. In the presentation, there is a code snipper for the updateViewAsyncStream method, but it's not really used anywhere. How do utilize this when the DataScannerViewController is active and capture the recognized items?
Also there is a sendDidChangeNotification() function sat the end but the compiler complains that it's not in scope.
Thanks.
Hi,
I can't seem to find a way to view the Build Timeline with Xcode 14. I see a "Recent Build Timeline" option in the drop-down when I click on the top-left button in the editor (where "Recent Files" lives), but it doesn't do anything.
Do I have to build the app in some special way to make this visible?
I'm confused about this ... the MailKit headers files seem to suggest that MailKit APIs are available for iOS16 now. But I haven't seen any documentation mention it, and you can't create a MailKit extension for iOS (using Xcode 14) like you can with macOS. So is it available to use in iOS or not? If so, how do we create an iOS target for the MailKit extension?
Hi,
I am getting a crash report from a user, where they get an application crash when they open a CSV file on their device. I use the standard DataFrame(contentsOfCSVFile: fileURL, options: options) initializer to create a DataFrame, but that's where it's crashing, even though it's inside a try-catch block:
public func loadInitialCSVData(withURL fileURL: URL) throws -> DataFrame {
let options = CSVReadingOptions(hasHeaderRow: true, delimiter: ",")
do {
let dataFrame = try DataFrame(contentsOfCSVFile: fileURL, options: options)
} catch {
// log error here - doesn't get here
}
This is from the crash report:
Exception Type: SIGTRAP
Exception Codes: TRAP_BRKPT at 0x21e02be38
Crashed Thread: 0
Thread 0 Crashed:
0 TabularData 0x000000021e02be38 __swift_project_boxed_opaque_existential_1 + 9488
1 TabularData 0x000000021e099d64 __swift_memcpy17_8 + 4612
2 TabularData 0x000000021e099958 __swift_memcpy17_8 + 3576
3 TabularData 0x000000021e09935c __swift_memcpy17_8 + 2044
4 Contacts Journal CRM 0x000000010433f614 Contacts_Journal_CRM.CJCSVHeaderMapper.loadInitialCSVData(withURL: Foundation.URL) throws -> TabularData.DataFrame (CJCSVHeaderMapper.swift:26)
5 Contacts Journal CRM 0x00000001043009d8 (extension in Contacts_Journal_CRM):__C.MacContactsViewController.handleSelectedCSVFileForURL(selectedURL: Foundation.URL) -> () (MacContactsViewControllerExtension.swift:28)
6 Contacts Journal CRM 0x0000000104301e64 @objc (extension in Contacts_Journal_CRM):__C.MacContactsViewController.handleSelectedCSVFileForURL(selectedURL: Foundation.URL) -> () (<compiler-generated>:0)
7 Contacts Journal CRM 0x0000000104222c94 __51-[MacContactsViewController importCSVFileSelected:]_block_invoke (MacContactsViewController.m:954)
8 AppKit 0x00000001bbe8f294 -[NSSavePanel didEndPanelWithReturnCode:] + 84`
I can't diagnose the crash, because it doesn't have more information. I don't have access to the CSV file currently either, so I don't know what else I can do to prevent it.
What could possibly be causing this crash? Does it not matter that I am also trying to catch the errors it's throwing, or can the app crash because of some internal reasons with the framework?
Hi,
I have a paid app available through the Mac App Store, and when the user opens the app, I want to verify that the transaction of the payment is valid. I would have assumed that in StoreKit2, the 'Transaction.all' would work, but when I tested this, it shows 0 transactions for all users.
This is what I'm testing:
for await result in Transaction.all {
guard case .verified(let transaction) = result else { continue }
print("verified product = \(transaction.productID)")
// send to analytics
}
But nothing gets observed in the analytics.
Does the StoreKit2 framework have an easy way to determine transactions that are made for paid-up-front apps?
Hi,
I am trying to invoke this NSApplicationDelegate callback from my Mac app, but it's not getting called:
- (void)application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls
I have registered the URL scheme in my Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.my.testapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>mytestapp</string>
</array>
</dict>
</array>
Now I use a 2nd Mac app to test this out, by invoking the following code:
if let url = URL(string: "mytestapp://") {
NSWorkspace.shared.open(url)
}
This causes my first app to come to the foreground, and the
"applicationDidBecomeActive:(NSNotification *)notification" method gets called, but the "application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls" method mentioned above doesn't get invoked, which is what I want.
Any ideas about why that might be the case?