tools - Advertencia de XCode 8 "El método de instancia casi coincide con el requisito opcional"
xcode for ipad (8)
Convertí mi proyecto (macOS) a Swift 3 en XCode 8 y recibí las siguientes advertencias con varios métodos de delegado que implementé en clases rápidas:
Instance method ''someMethod'' nearly matches optional requirement of protocol ''protocolName''
Obtengo esto para varios métodos NSApplicationDelegate como applicationDidFinishLaunching
y applicationDidBecomeActive
:
Pero también para implementaciones de tableViewSelectionDidChange
:
Utilicé la finalización del código para insertar las firmas de método y también intenté copiarlas desde los encabezados del SDK para descartar errores tipográficos. Las advertencias simplemente no desaparecen y los métodos nunca se llaman.
¿Que me estoy perdiendo aqui?
Contactamos con Apple Developer Technical Support (DTS) con este problema. Respondieron que esto es un error en XCode 8 .
Presentamos un informe de error y esperamos una actualización rápida. (Identificación del informe de errores de Apple: 28315920).
Si experimenta un problema similar, también presente un informe de error (refiriéndose al nuestro) para que los ingenieros de Apple consideren que no es un solo caso.
Actualización para XCode ≥ 8.1
El problema parece estar solucionado ahora, al menos para los métodos de delegado que estamos utilizando en nuestro proyecto.
Después de horas de búsqueda encontré esto: Swift 3 ObjC Método de protocolo opcional no llamado en la subclase
Puede solucionar el error prefijando la declaración objetivo-c en la función
@objc(tableViewSettingsDidChange:notification:)
func tableViewSettingsDidChange(_ notification:Notification)
Encontré que esta advertencia se debe principalmente a cuando se ajusta al protocolo de UITableViewDelegate
lugar de UITableViewDataSource
Por favor, comprueba dos UITableViewDataSource
si UITableViewDataSource
Esto es lo que lo solucionó.
Estaba recibiendo la misma advertencia en algún código que estaba seguro de que escribí inicialmente en el editor y le permití que se autocompletara. Posteriormente volví atrás y revisé la advertencia e intenté simplemente escribir la misma función nuevamente después de mi función existente. Cuando ingresé nuevamente el nombre de la función, mi firma de función cambió y los parms coincidieron exactamente con lo que Xcode esperaba y la advertencia fue suprimida.
Entonces, si quiere hacer una revisión de cordura rápida, hágase un favor e intente escribir la función una vez más y vea si los tipos de parm cambian. Eso podría ser todo lo que necesitas.
Otra causa de esta advertencia cuando NSError
está NSError
a Swift:
Dado este método delegado de Objective-C:
- (void)myService:(id<MYService>)myService didFailForSomeReason:(NSError *)error;
Eso genera automáticamente este método Swift:
public func myService(_ myService: MYService!, didFailForSomeReason error: Error!)
La advertencia fue mostrada.
En mi caso, la razón era que mi clase tenía su propio tipo de Error
por lo que la firma se estaba resolviendo en MyClass.Error
lugar de Swift.Error
. La solución fue escribir completamente el parámetro Error al cambiarlo a Swift.Error
. Swift.Error
:
public func myService(_ myService: MYService!, didFailForSomeReason error: Swift.Error!)
Para el registro, tuve el mismo problema al implementar el método delegado didFailProvisionalNavigation de WKWebView. La solución fue agregar la declaración @objc y cambiar el tipo del último parámetro de Error a NSError:
@objc(webView:didFailProvisionalNavigation:withError:)
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
// handle error
}
Para xcode 8.1> = y swift 3,
agregue @nonobjc al principio del método para silenciar esta advertencia.
Solo para agregar una aclaración a esta solución bastante complicada: ¿alguien puede ver por qué lo siguiente no está disparando / trabajando cuando se está tomando la acción?
extension AppDelegate: UNUserNotificationCenterDelegate {
@objc(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("RESPONSE FROM NOTIFICATION!")
switch response.actionIdentifier {
case "reply":
print("Reply action received!")
case "ignore":
print("Ignore action received!")
default: print("Error - Unknown action received!")
break
}
}
}