Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

297
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!