Post not yet marked as solved
A couple of days ago I changed laptops from an Intel/Big Sur to a MacBook Pro M1/Monterey.
Since then I've encountered endless endless problems building in Xcode (for iOS).
The very first attempt at building my project after setting up the laptop was successful, but since then builds just fail randomly without making any code changes. i.e. make a build and its successful, change nothing whatsoever and it fails.
Once a build fails it takes an eternity to get it building successfully again, doing a clean, delete derived data, quit/re-launch Xcode doesn't necessarily fix the problem, it might be necessary to do this 3 or 4 times before the build succeeds again. But that build success will only be temporary before it fails again.
The failures are different each time, but one thing they seem to have in common is a Killed: 9 message, here's an example
Script-00DD1BFF1BD5951E006B06BC.sh: line 5: 22679 Killed: 9 ../node_modules/@sentry/cli/bin/sentry-cli react-native xcode ../node_modules/react-native/scripts/react-native-xcode.sh
Command PhaseScriptExecution failed with a nonzero exit code
I've had about 6 or 7 different random failures in different places, but they all say Killed: 9 Command PhaseScriptExecution failed with a nonzero exit code.
The project used to build fine on the old laptop, its the exact same project/code, the only variable here is the laptop itself and the MacOS.
I've been struggling with this for the last 3 days, the problems are just endless. The build failures are random, like I mentioned a build will work fine one time, then just stop for no reason. They could occur at any random moment in any random component of the project or its dependencies.
Its utterly impossible to proceed like this, I'm the first in my company out of about 100 employees who are going to upgrade their laptops from Intel to Silicon. I will be telling our IT department we absolutely cannot make that switch as things are just unusable and its impossible to proceed with this combination of laptop|OS|Xcode.
I'm on Monterey 12.2.1 | Xcode 13.2.1, but the problem was also present with Monterey 12.0.1|Xcode 13.2.1
Opening Xcode with Rosetta makes no difference to the problems.
Post not yet marked as solved
I'm currently using 4 extensions within my app and use a group in combination with UserDefaults.init(suiteName:) to share settings between the extensions and the app.
However I've just tried adding an unwanted communications extension and found that data writing to defaults, in the exact same way as the other extensions, isn't saved.
At first I noticed data written by the UCE wasn't present when the app tried to read it, so performed an experiment and found that while the extension is running, it can write and read data to user defaults, but the next time the extension runs, all that data has gone.
I've tried using the old and now default UserDefaults.synchronize() but it makes no difference.
Why is the UC extension different from every other extension? Is it possible to write and persist data from within it?
let groupName = "group.com.mycompany.appName"
let sharedDefaults = UserDefaults.init(suiteName: groupName)
var theValue = sharedDefaults!.value(forKey: "some key")
NSLog("\(theValue)") // prints nothing, despite the extension having previously run
sharedDefaults!.set("some value", forKey: "some key"))
sharedDefaults!.synchronize()
theValue = sharedDefaults!.value(forKey: "some key")
NSLog("\(theValue)") // prints "some value"
Post not yet marked as solved
If a unwanted communication extension target is created,then the auto-generated template code doesn't work. This can very quickly be demonstrated by:
In Xcode create a new iOS project
In that project create an unwanted communication extension target (I called it cheese so its easy to see in the console)
Add some logging lines to the UnwantedCommunicationReportingExtension code that was created.
Install app to iPhone, and select it in the settings app
Swipe on a call in the call history.
The following lines can be seen in the iPhone console:
Unknown class _TtC6cheese13MainInterface in Interface Builder file.
View controller is not of class ILClassificationUIExtensionViewController
None of the logging lines added to the code are displayed, also the Done button in the presented UI is disabled - but in the code that is generated by the target templete is:
self.extensionContext.isReadyForClassificationResponse = true
Which is supposed to enable the Done button.
In the storyboard that gets created the custom class is set to MainInterface:
How are you supposed to get this stuff working if it doesn't work out of the box? MainInterface isn't being recognized as the view controller class, and in the drop down UnwantedCommunicationReportingExtension doesn't appear.
class UnwantedCommunicationReportingExtension: ILClassificationUIExtensionViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
NSLog("viewDidAppear")
// Notify the system when you have completed gathering information
// from the user and you are ready with a classification response
self.extensionContext.isReadyForClassificationResponse = true
}
// Customize UI based on the classification request before the view is loaded
override func prepare(for classificationRequest: ILClassificationRequest) {
NSLog("prepare")
// Configure your views for the classification request
}
// Provide a classification response for the classification request
override func classificationResponse(for request:ILClassificationRequest) -> ILClassificationResponse {
return ILClassificationResponse(action: .none)
}
}
Post not yet marked as solved
I've got an iOS app with lots of extensions, some of them complex and doing a lot of stuff.
After a bug I'd like to be able to use OSLogStore to get a holistic picture of logging for the app and its extensions and send that to a debugging server to retrospectively view logs for the app and its extensions.
The constructor is OSLogStore.init(scope: OSLogStore.Scope), however scope only has one value .currentProcessIdentifier.
Implying if that is called from within the app it can only get access to logging for its process only. I tried it out to confirm this is the case - if I log something in an extension (using Logger), then run the app with code like this:
let logStore = try! OSLogStore(scope: .currentProcessIdentifier)
let oneHourAgo = logStore.position(date: Date().addingTimeInterval(-3600))
let allEntries = try! logStore.getEntries(at: oneHourAgo)
for entry in allEntries {
look at the content of the entry
Then none of the entries are from the extension.
Is there anyway from within the app I can access logging made within an extension?
Post not yet marked as solved
I've got a notification service extension which is working as expected unless the user
a) turns the passcode for the iPhone on and
b) turns on Auto-lock and the iPhone is locked when a push arrives
If auto-lock is turned on and the phone is locked but passcode is not turned on, then the notification is displayed as expected.
The iPhone displays a notification with the top line being the name of the app and the second line saying "Notification", which is neither the content within the push payload, not what is being set as the content within the extension.
There's no difference in behaviour of the extension when passcode is enabled. Adding logging to the extension I can confirm the content is being replaced and posted as expected:
NSLog("Going to post notification title: \(notificationContent.title) subtitle: \(notificationContent.subtitle) body: \(notificationContent.body)")
contentHandler(notificationContent)
The notificationContent is as expected and is identical when passcode is on off.
Why is the iPhone displaying the notification incorrectly if passcode is turned on and the phone locked?
Post not yet marked as solved
I'm running an app with the com.apple.developer.usernotifications.filtering entitlement and the filtering works fine with iOS 15.
However I tried running it on an older phone / OS (iPhone 8 / iOS 13.1.2) and it does not work.
Is this entitlement not supported with iOS 13.1.2? If so, what is the earliest iOS version that supports it?
The handset logged this:
The OS displayed:
default 07:55:58.800825-0800 NotificationServiceExtension
Mutated notification request will not visibly alert the user, will deliver original content
If the app is run on iOS 15, it says :
default 07:20:27.251600-0800 SpringBoard Mutated notification request will not visibly alert the user, will supress original content
I'm working on an out-sourced application for a company and when a version of it built using ids and provisioning profiles from my Apple account it runs without problems.
However when it is built and run using the company's ids and provisioning profiles I am seeing an issue with it.
What is happening is when a notification service extension uses a call extension then the OS logs:
doQueryCallExtensionStatusWithDispatchGroup() COMPLETED WITH ERROR: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.CallKit.CallDirectory was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo=
NSDebugDescription=The connection to service named com.apple.CallKit.CallDirectory was invalidated: failed at lookup with error 159 - Sandbox restriction.
I noticed that in the company's provising profile for the notification service extension the app identier prefix is different from the team identifer. In my own provisioning profile the app identifier prefix and team identifer are the same.
Could it be the case that this difference in identifiers within the provisioning profile is leading to the sandbox error message?
Attached is the notification service extension provisioning profle provided to me by the company (converted to a .plist for readability)
Post not yet marked as solved
We have an app which gets sent APNSs by the server and use a Notification Service Extension to intercept them.
In my observations I've never seen throttling applied on the device to these pushes (unlike app directed push where its easy to observe happening if you let the batter run low for example).
The Apple documentation says it may perform server side throttling, but when, how often, under what circumstances?
If the app has 30 million users and the server sends them 10m or 100 pushes per day will it get throttled?
Does anybody have any have any documented or observed info on this.
Post not yet marked as solved
It an app receives a Voip push, but has to terminate the call, then if this happens a few times the OS is terminating the app (Message from debugger: Terminated due to signal 9) and then it stops delivering future pushes to the app.i.e. with code let endCallAction = CXEndCallAction(call: callUUID) let transation = CXTransaction(action: endCallAction) self.callController.request(transation) { (error) in } provider.reportNewIncomingCall(with: callUUID, update: callUpdate) { error in Model.priorityLog("GRUNT reportNewIncomingCall completion error \(String(describing: error))") completion() }
Post not yet marked as solved
I've been using push for years and years and years in multiple apps. Over that time what I've noticed is that for the last few versions of iOSs the apn push token can change but its not that common to do so.However with iOS 13 I'm observing it happening all the time - if I install the app via XCode then everytime the app is freshly installed it will change. Ok, not too much of an issue, however I'm also seeing it change every few executions despite the app not being deleted between running.I haven't experimented with release builds, but this happens all the time with a dev build. iOS 13 is going to be released next week, I sincerely hope this behaviour is not going to occur with a production build - its going to result in the app (which has millions of users) having to needlessly contact the server to notify it of the changed apn token, every time the app runs.
Post not yet marked as solved
If the app schedules a a discretionay background URL session for some point in the future, is the OS actually going to run it? Even if the app gets terminated before will the OS launch the app in the background? Or does the OS only scheudle the url session based on app usages patters? - i.e. suppose the app schedules a background URL session with a lengthy earliest begin date of something a month, but then if the user doesn't actually interact with the app much if at all during that period, will the OS not bother to schedule the session because the user didn't use the app much? (similar to current background schedulding, where the OS doesn't schedule the app at all if the user doesn't use it).
Post not yet marked as solved
With iOS 13 its mandatory that an app should call CXProvider.reportNewIncommingCall() when it receives a Voip Push.This results in a call screen being displayed to the user.However there are instances when the app may receive a Voip push but there is no actual call associated with it (the call might have been dropped or not completed, or the user may want to block receiving calls from that number).How can the app simultaneously satisfy the mandatory requirement that CXProvider.reportNewIncommingCall() should be called but where there is not an actual call and the call screen should not be displayed?
Post not yet marked as solved
CallKit's call directory extension can be used to block standard phone calls.However how is blocking a VoiP call supposed to work with iOS 13?When there is a Voip call your app receives a voip push, but now with iOS 13 Apple are mandating that when the push is received the app *must* call CXProvider.reportNewIncomingCall().However when reportNewIncomingCall() is called, the OS displays an incoming call screen (which is not the same as for a regular incoming call). It is apparently not possible for this call screen to be suppressed, and even if reportNewIncomminCall() is invoked with a parameter which is a phone number which has been registered as blocked with the CallKit extension, the call screen will still be displayed.So it would seem it is impossible for an application to offer the ability to block a Voip phone call (unless the app sends its list of blocked numbers to the server, and the server doesn't send the push for a particular handset for blocked numbers. But if the app is installed on hundreds of thousands or millions of handsets that is a big implementation to manage on the server side without considerable undertaking).
Post not yet marked as solved
All the examples I've seen of using pushes use [NSData description] to obtain the push token in order to send to the server.However when an app is built with XCode 11 the result of this is different than when built with Xcode 10, similarly for [NSString stringWithFormat].Example: NSData* theToken = ...
....
NSString* stringWithFormat = [NSString stringWithFormat"@"%@", theToken];
NSString* description = [theToken description];When compiled with Xcode 10 and run, the results for both are : @"<44154da7 32345001 53106883 ffc1071f a59c0d24 a70871e5 aa8dbb41>"However when compiled with Xcode 11 and run the results are: @"{length =32, bytes = 0x44154da7 32345001 53106883 ffc1071f ... a70871e5 aa8dbb41}"(This latter result does not occur if the code is compiled with Xcode 10 and then run on iOS 13.)How can you convert the NSData to NSString when compiled with Xcode 11 that will give the same results as XCode10, or how can you extract just the bytes section into an NSString from the return result if compiled with Xcode 10?
Post not yet marked as solved
With XCode 11 I am no longer able to view the full value for a push token. Here's some example code to illustrate: func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType)
{
var method1 = NSString(format: "%@", credentials.token as CVarArg) as String
print("method1: \(method1)")
method1 = method1.replacingOccurrences(of: " ", with: "")
method1 = method1.replacingOccurrences(of: "<", with: "")
method1 = method1.replacingOccurrences(of: ">", with: "")
print("method1 again: \(method1)")
let method2 = String(decoding: credentials.token, as: UTF8.self)
print("method2: \(String(describing: method2))")
let method3 = credentials.token.description as String
print("method3: \(method3)")However when the above code is run with Xcode 11, this is the output: method1: {length = 32, bytes = 0x5b3f44e0 6d2c5ee5 5252d3db f5bb915b ... 12844aeb 13259e7e }
method1 again: {length=32,bytes=0x5b3f44e06d2c5ee55252d3dbf5bb915b...12844aeb13259e7e}
method2: [?D�m,^�RR�����[� � ��>� �J� %�~
method3: 32 bytesIn previous versions of Xcode, method1 would be logged/viewable as something like this:44154da73234500153106883ffc1071fa59c0d24f1a1d29ea70871e5aa8dbb41But now its this: 0x5b3f44e06d2c5ee55252d3dbf5bb915b...12844aeb13259e7eThere is ... in the middle of it.How can I just log/interactively view the contents of credentials.token with Xcode 11?I want to copy/paste the value into a php script to manually send push message to the app for testing purposes.