====== Bevezető duma ======
Egy hibát nyomozok a Siskin IM nevű, nyílt forrású, iOS appban.
A hibaüzenet:
{{:it:screenshot_20201014-143153.jpg?400|Siskin IM push reg error}}
Végignéztem a kódot, csak nem értem. :)
====== Kódrészletek ======
[[https://github.com/tigase/siskin-im/blob/ab733cbc3bc5bf6eafaf0d860546729e8da84b70/SiskinIM/AppDelegate.swift|AppDelegate.swift (585):]]
@objc func pushNotificationRegistrationFailed(_ notification: NSNotification) {
let account = notification.userInfo?["account"] as? BareJID;
let errorCondition = (notification.userInfo?["errorCondition"] as? ErrorCondition) ?? ErrorCondition.internal_server_error;
let content = UNMutableNotificationContent();
switch errorCondition {
case .remote_server_timeout:
content.body = "It was not possible to contact push notification component.\nTry again later."
case .remote_server_not_found:
content.body = "It was not possible to contact push notification component."
case .service_unavailable:
content.body = "Push notifications not available";
default:
content.body = "It was not possible to contact push notification component: \(errorCondition.rawValue)"; // <--- the error we get, with errorCondition.rawValue = undefined-condition
}
[[https://github.com/tigase/siskin-im/blob/a5a8643c295ad9acad3993ccac15cfae349c3cf1/SiskinIM/settings/AccountSettingsViewController.swift|AccountSettingsViewController.swift (238):]]
fileprivate func enablePushNotifications(action: UIAlertAction) {
let accountJid = self.account!;
let onError = { (_ errorCondition: ErrorCondition?) in // <--- definition of onError
DispatchQueue.main.async {
var userInfo: [AnyHashable:Any] = ["account": accountJid];
if errorCondition != nil {
userInfo["errorCondition"] = errorCondition;
}
NotificationCenter.default.post(name: Notification.Name("pushNotificationsRegistrationFailed"), object: self, userInfo: userInfo);
}
}
// let's check if push notifications component is accessible
if let pushModule: SiskinPushNotificationsModule = XmppService.instance.getClient(forJid: accountJid)?.modulesManager.getModule(SiskinPushNotificationsModule.ID), let deviceId = PushEventHandler.instance.deviceId {
pushModule.registerDeviceAndEnable(deviceId: deviceId, pushkitDeviceId: PushEventHandler.instance.pushkitDeviceId, completionHandler: { result in // <--- actual registration attempt
switch result {
case .success(_):
break;
case .failure(let errorCondition): // <--- errorCondition is set here
DispatchQueue.main.async {
self.pushNotificationSwitch.isOn = false;
self.pushNotificationsForAwaySwitch.isOn = false;
}
onError(errorCondition); // <--- onError is called here
}
});
[[https://github.com/tigase/siskin-im/blob/275a939f1cb4a070473ae81c49e0fedffc43f6b4/SiskinIM/xmpp/SiskinPushNotificationsModule.swift|SiskinPushNotificationsModule.swift (99):]]
open func registerDeviceAndEnable(deviceId: String, pushkitDeviceId: String?, completionHandler: @escaping (Result)->Void) {
self.findPushComponent { result in
switch result {
case .success(let jid):
self.registerDeviceAndEnable(deviceId: deviceId, pushkitDeviceId: pushkitDeviceId, pushServiceJid: jid, completionHandler: completionHandler);
case .failure(_):
self.registerDeviceAndEnable(deviceId: deviceId, pushkitDeviceId: pushkitDeviceId, pushServiceJid: self.defaultPushServiceJid, completionHandler: completionHandler);
}
}
}
[[https://github.com/tigase/siskin-im/blob/275a939f1cb4a070473ae81c49e0fedffc43f6b4/SiskinIM/xmpp/SiskinPushNotificationsModule.swift
|SiskinPushNotificationsModule.swift (265):]]
func findPushComponent(completionHandler: @escaping (Result)->Void) {
self.findPushComponent(requiredFeatures: ["urn:xmpp:push:0", self.providerId], completionHandler: completionHandler);
}
====== Kérdések ======
** 1. Mi annak a szemantikája, hogy egy függvény meghívja önmagát? Vagy mi történik itt pontosan? **
Két példa is van rá:
func registerDeviceAndEnable (...) {
...
self.registerDeviceAndEnable (...)
...
}
func findPushComponent(completionHandler: @escaping (Result)->Void) {
self.findPushComponent(
requiredFeatures: ["urn:xmpp:push:0", self.providerId],
completionHandler: completionHandler
);
}
A második eset még érdekesebb.
**2. Van plusz egy argumentum a hívásnál. Ez hogy lehetséges?**
**3. A függvénynek egy sora van, ami – ha jól értem – az implicit visszatérési értéke. Önmagával tér vissza a függvény? Ez mire jó?**
====== Felelősségkizárás és köszönet ======
Az ügy nem sürgős, csak akkor válaszolj, ha nincs fontosabb.
És előre is nagyon köszi a segítséget. :)