Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

310
Vistas
Swift: cambio de método para el método del marco privado y luego invocación de la implementación original

Estoy tratando de cambiar el método de un marco privado para realizar una lógica personalizada y luego me gustaría llamar a la implementación original.

Código:

 class SwizzlingHelper { private struct Constants { static let privateFrameworkClassName = "privateFrameworkClassName" static let swizzledMethodSignature = "swizzledMethodSignature:" } static func swizzle() { let originalSelector = NSSelectorFromString(Constants.swizzledMethodSignature) if let swizzlingClass: AnyClass = NSClassFromString(Constants.privateFrameworkClassName), let originalMethod = class_getInstanceMethod(swizzlingClass.self, originalSelector), let swizzledMethod = class_getClassMethod(SwizzlingHelper.self, #selector(swizzledMethod)) { method_exchangeImplementations(originalMethod, swizzledMethod) } } @objc private static func swizzledMethod(_ arg: String) { // Custom logic // Call original method here - how? } }

He visto varios ejemplos de cómo se realiza el swizzling extendiendo una clase y luego invocando la implementación original llamando a self.originalImplementation() dentro del método swizzled. Dado que esta es una clase de marco privado, no puedo extenderla y, por lo tanto, la clase SwizzlingHelper ayuda a ayudar con el swizzling. Sin embargo, no hay acceso a self dentro del método swizzled para llamar a la implementación original.

Cualquier pista será apreciada. ¡Gracias!

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Realmente no veo el propósito de swizzling en este escenario. Si desea ejecutar la lógica del método original al final, entonces el swizzling no tiene mucho sentido para mí. Parece que podría simplemente pasar un bloque que ejecuta el método del marco después de ejecutar su propia lógica.

Dicho esto, se me ocurrió esto:

 typealias PrivateClassFunction = @convention(c) () -> Void class SwizzingHelper { private let originalMethod: PrivateClassFunction init(forClass: String, methodSignature: String) { let originalSelector: Selector = NSSelectorFromString(methodSignature) guard let swizzledClass = NSClassFromString(forClass), let swizzledMethod = class_getInstanceMethod(SwizzingHelper.self, #selector(run)), let originalMethod = class_getInstanceMethod(swizzledClass.self, originalSelector) else { fatalError() } self.originalMethod = unsafeBitCast(originalMethod, to: PrivateClassFunction.self) method_exchangeImplementations(originalMethod, swizzledMethod) } @objc func run() { print("Running new logic") originalMethod() } }

Pasar el nombre de la clase y las cadenas de selección solo lo hace un poco más flexible en caso de que desee cambiar otros métodos/clases en el futuro. También podría idear alguna forma de hacer que PrivateClassFunction sea más variable (tal como está, querrá ajustar eso para que coincida con los parámetros y el tipo de retorno de los métodos de su marco privado).

Ejecutará el código así:

 let swizzler = SwizzingHelper(forClass: "PrivateClass", methodSignature: "privateClassMethodWithArg:") swizzler.run()
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda