====== 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. :)