es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Intercambiador de métodos con Swift 5.5

Estoy intentando sobrescribir el método initWithString en NSURL, he revisado estos problemas/publicaciones anteriores:
– https://stackoverflow.com/questions/46361065/method-swizzling-in-swift-4/46361066#46361066
– https://stackoverflow.com/questions/34317766/how-to-swizzle-init-in-swift
– https://www.uraimo.com/2015/10/23/effective-method-swizzling-with-swift/

He intentado el siguiente código pero no he podido fijar el nuevo método log_initWithString, swiftc no indica nada pero al ejecutarlo obtengo index/index.swift:20: Fatal error: Unexpectedly found nil while unwrapping an Optional value.

import AppKit
import WebKit

let app = NSApplication.shared

//ejemplo: https://github.com/kickstarter/ios-oss/blob/39edeeaefb5cfb26276112e0af5eb6948865cf34/Library/DataSource/UIView-Extensions.swift

private var hasSwizzled = false

extension NSURL {
    public final class func doSwizzle() {
        guard !hasSwizzled else { return }

    hasSwizzled = true

    let original = Selector("initWithString:")
    let swizzled = Selector("log_initWithString:")

    let originalMethod = class_getInstanceMethod(NSURL.self, original)!
    let swizzledMethod = class_getInstanceMethod(NSURL.self, swizzled)!

    let didAddMethod = class_addMethod(NSURL.self, original, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))

    if didAddMethod {
        class_replaceMethod(NSURL.self, swizzled, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod)
    }
}

@objc internal func log_initWithString(string URLString: String) {
    NSLog("Hola desde initWithString")

    return log_initWithString(string: URLString)
}


}

class AppDelegate: NSObject, NSApplicationDelegate {
    let window = NSWindow.init(contentRect: NSRect(x: 0, y: 0, width: 750, height: 600), styleMask: [
        NSWindow.StyleMask.titled,
        NSWindow.StyleMask.closable,
        NSWindow.StyleMask.resizable,
        NSWindow.StyleMask.miniaturizable
    ], backing: NSWindow.BackingStoreType.buffered, defer: false)

func applicationDidFinishLaunching(_ notification: Notification) {
    NSURL.doSwizzle()

    let webview = WKWebView(frame: window.contentView!.frame)
    let request = URLRequest(url: URL(string: "https://google.com")!)

    window.contentView?.addSubview(webview)
    webview.load(request)

    window.makeKeyAndOrderFront(nil)
    window.orderFrontRegardless()
    window.center()
}


}

let delegate = AppDelegate()

app.delegate = delegate

app.run()
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que estás intentando usar la metodología de intercambio de métodos para sobrescribir el método initWithString en NSURL. Basándote en los recursos que has consultado, parece que vas por el buen camino.

    Es posible que el problema que estás experimentando esté relacionado con el orden en el que estás llamando a los métodos. Asegúrate de llamar a NSURL.doSwizzle() antes de crear la instancia de WKWebView.

    También es posible que el problema esté relacionado con el URLRequest que estás creando. Asegúrate de que la URL que estás pasando al inicializador de URLRequest no sea nil.

Comments are closed.