Force reload watchOS 2 Complications - ios

I have issues getting Complications to work. It would be helpful if I was able to reliably refresh them.
Therefore I linked a force-press menu button to the following method
#IBAction func updateComplication() {
let complicationServer = CLKComplicationServer.sharedInstance()
for complication in complicationServer.activeComplications {
complicationServer.reloadTimelineForComplication(complication)
}
}
Unfortunately this leads to the app crashing. with a fatal error: unexpectedly found nil while unwrapping an Optional value.
I understand that calling reloadTimelineForComplication(complication) is budgeted but that can't be the issue here as it doesn't work from the very beginning.
I am currently using watchOS2 + Xcode 7 GM
I'd appreciate any ideas on making Complications refresh while the app is running?

Trace or use the exception breakpoint and focus on reading the whole error message where it tells you exactly on which line it found the nil unexpectedly (I do suspect the complicationServer). Use 'if let' instead of 'let' to force unwrap the respective variable.
private func reloadComplications() {
if let complications: [CLKComplication] = CLKComplicationServer.sharedInstance().activeComplications {
if complications.count > 0 {
for complication in complications {
CLKComplicationServer.sharedInstance().reloadTimelineForComplication(complication)
NSLog("Reloading complication \(complication.description)...")
}
WKInterfaceDevice.currentDevice().playHaptic(WKHapticType.Click) // haptic only for debugging
}
}
}

Related

Firebase crashlytics does not telling me the exact crash problem with swift

I've already read a lot of questions about this on stack, but is there any solution to fix this to get the missing part of the crashreport?
I understand that these crashes were caused by some reason of nil or unwrapped options or something else, but crashes from objc are much better:
My project is based on objetive-c (started a few years ago) but the new big parts are written in swift. All crashes which are coming from the objc part are well detailed but those which are coming from the swift part not.
So the question is, how will I get readable crash reports instead of EXC_BREAKPOINT 0x00000001028817ac
For such cases, I would recommend adding advanced analytics of user behavior in the app and then try to repeat the same steps as the user. This will help to find the root of such crashes. I can share the code on the foundation of which you may add the necessary functionality on the screens of your app:
import Foundation
import Crashlytics
class EventLogger {
/// Log a handled non-fatal exception
class func logException(_ exception: NSException) {
print("Catched exception: \(exception.debugDescription)")
let frames = exception.callStackSymbols.map { symbol in CLSStackFrame(symbol: symbol) }
Crashlytics.sharedInstance().recordCustomExceptionName(exception.name.rawValue, reason: exception.reason, frameArray: frames)
}
private class func log(_ string: String) {
CLSLogv(string, getVaList([]))
}
class func log(screen: String) {
log("User is located at \(screen) Screen")
}
/// Log a status of feature
class func log(feature: String, status: String) {
log("Feature \(feature) was \(status)")
}
/// Log an event
class func log(event: String) {
log("Event: \(event)")
}
}
and impement it like here:
EventLogger.log(event: "Pressed login button")
After the crash, you can see the action log exactly for this crash

Re-Assigning instance of AVAudioPlayer in iOS13 leads to BAD_ACCESS runtime error

I have an app, that is for many years in the AppStore and runs without any crashes (last deployment target iOS 12.4). I have some code for playing a sound on certain events in the app.
Now I tried to upgrade my app for iOS 13 and without changing any code related to that “playSound” thing, I always get this runtime error, when testing on a real device. Does not happen on simulator.
Thread 1: EXC_BAD_ACCESS (code=1, address=0x48)
PLEASE: Before you mark that question as “duplicate”, consider that this must have something to do with the release of iOS13, because before it didn’t happen and the code is just "usual".
Here is my code, also on gitHub.
I have a property in my ViewController to prevent ARC deallocating my AVAudioPlayer:
private var mySoundPlayer: AVAudioPlayer = AVAudioPlayer()
I have a routine, where the “play sound” should be performed (here happens the error, when assigning a new instance of AVAudioPlayer. The resourceURL is not the problem, the RE-ASSIGNING is the problem, I tested it with a new instance not being assigned and i did not crash.
// -------------------------------------------------
// MARK: Private Methods
// -------------------------------------------------
private func makeSoundEvent(_ soundEvent : SoundEvent) {
guard Settings().getSound() == .soundON else { return }
guard let urlToRessource : URL = soundEvent.getFileURLToSoundRessource() else { return }
do {
mySoundPlayer = try AVAudioPlayer(contentsOf: urlToRessource)
try? AVAudioSession.sharedInstance().setActive(true)
mySoundPlayer.play()
}
catch { print("Could not create AVPlayer for ressource \(urlToRessource)") }
}
And here I have the call of that subroutine, somewhere in my viewDidLoad() with a delay of 2 seconds.
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.makeSoundEvent(.startFanfare)
}
I think it somehow does not work because of the async thread. But since it is on the main thread, I thought this should work.
Just remove the initialisation and it will work
private var mySoundPlayer: AVAudioPlayer!
Cheers!!!
private var mySoundPlayer: AVAudioPlayer = AVAudioPlayer()
AVAudioPlayer doesn't have init() listed as a valid initializer. The reference page shows four separate initializers, all of which take at least one parameter. If you were using the line above in code prior to iOS 13.1 without crashing, you were initializing the audio player incorrectly and probably just getting lucky that it wasn't a problem.
I don't know what changed specifically with AVAudioPlayer in iOS 13.1, but the release notes show quite a few audio-related changes, and it seems likely that some change to that class introduced a dependency on something that happens at initialization time.

Unexplainable Swift EXC_BREAKPOINT Crash

consider the following code:
#objc public func endAllSessionsWithReason(_ reason: Reason, completion completionBlock: (() -> Void)?) {
let allActiveSessions = self.activeSessions.map({$0.value})
for session in allActiveSessions {
if (reason != .undetermined) {
session.reason = reason
}
self.endSession(session, deleteSession: false)
}
let allActiveSessionIds = allActiveSessions.map({$0.sessionId})
self.deleteSessionsWithIds(sessionIds: allActiveSessionIds, completion: completionBlock)
}
Crashlytics is reporting the following crash in this code:
Crashed: com.apple.main-thread
EXC_BREAKPOINT 0x0000000103032788
SessionController.swift line 183
specialized SessionController.endAllSessionsWithReason(_:completion:)
where line 183 refers to:
let allActiveSessionIds = allActiveSessions.map({$0.sessionId})
I've tried figuring out what could cause this crash for a few days now, and haven't been able to reproduce it. I don't see any implicit unwraps or optionals here, but sessionId is a non-optional value in the session object if that matters.
self.activeSessions is a non-optional value as well, but can be empty.
I am using swift 4.1, and the crashes occur on on iOS devices running all the different flavors of iOS 10, 11, and 12. The app does support some builds of iOS 9, but none have been reported (although that may be irrelevant because the iOS 9 user base for the app is extremely small).

Crash when unwrapping optional

I have several clients that are complaining of a crash in my app. I have never been able to reproduce it. Crashlitics has detected the crash :
func addDevice(unconfiguredDevice: UnconfiguredDevice) {
if let macSegment = unconfiguredDevice.macSegmentFromSSID { <<-CRASH
print("unconfigured mac: \( macSegment )")
if let setupDevice = self.unconfiguredDevices.value.first(where: { Device in Device.macEnd == unconfiguredDevice.macSegmentFromSSID! }) {
setupDevice.unconfiguredDevice = unconfiguredDevice
} else {
self.unconfiguredDevices.value.append(SetupDevice(unconfiguredDevice: unconfiguredDevice))
}
}
}
The crash type is EXC_BREAKPOINT. I have seen on several other threads around here that this kind of crash might be related to optional unwrapping, and indeed that macSegment method there returns an optional. But I don't understand what the problem might be. (BTW this method is for detecting devices that are configurable via WAC).
Any ideas/tips/suggestions ?
The crash occurs because macSegmentFromSSID was nil when you tried to unwrap it.
try like
if let setupDevice = self.unconfiguredDevices.value.first(where: { Device in Device.macEnd == macSegment}) {
setupDevice.unconfiguredDevice = unconfiguredDevice
}

How to make a phone call with Swift 3?

I'm building an app for a business and I've run into a dead end. I need a button that will start a phone call to a client's mobile number.
I have this, which is how it should work in Swift 2:
#IBAction func clientMobile(_ sender: AnyObject) {
UIApplication.shared.openURL(self.mobile!)
}
However openURL is deprecated and I don't see any alternative in the intellisense. What is the Swift 3 equivalent of the above line of code?
One other thing, when I run this code I have thee following error:
fatal error: unexpectedly found nil while unwrapping an Optional value
I know the error is related to self.mobile but I'm not sure how to fix it.
Declarations and extra information:
self.mobileis declared and initialised like this:
var mobile : URL?
//inside view will appear
self.mobile = URL(string: "telprompt://" + (self.dog?.client?.mobile)!)
you much check iOS version
guard let number = URL(string: "telprompt://123456789") else { return }
if #available(iOS 10.0, *) {
UIApplication.shared.open(number)
} else {
// Fallback on earlier versions
UIApplication.shared.openURL(number)
}
From the looks of it, you should be checking dog.client.mobile for some invalid characters in the phone number, or even nil (I can't tell if mobile is really optional there, if so you should check for nil before even attempting to launch the call).
Looks like your URL is coming back as nil, and you're trying to pass that to your openURL.
Your phone number should be free of symbols such as ()+-. You can easily remove those using stringByReplacingCharactersInSet (can't remember the exact name in Swift 3 right now.
openURL(:) is deprecated in iOS 10.
The new method is:
- (void)openURL:(NSURL*)url options:(NSDictionary<NSString *, id> *)options
completionHandler:(void (^ __nullable)(BOOL success))completion
Example usage to support both iOS 10 and earlier versions:
// iOS10 check
if (UIApplication.shared.respondsToSelector(#selector(UIApplication.shared.openURL(_:options:completionHandler:))) {
UIApplication.shared.openURL(self.mobile!, options: [:], completionHandler:nil)
} else {
UIApplication.shared.openURL(self.mobile!)
}
(hope this helps, sorry for any errors im on mobile atm)

Resources