SlideShare a Scribd company logo
How to instantiate any
controller for free
Benoît Caron & Vincent Pradeilles – Worldline
Insert clickbait here
Why?
Why?
You have to make sure an app displays properly on the iPhone X, but:
• Data is driven by web-services
• No mocks are available
• More than 150 different screens
• Some screens are part of complex business scenarios
What’s the right tool?
A debug view!
• Lists all available UIViewControllers
• Search bar and index
• Indicate a specific use case, if
needed
• Instantiates and pushes or
presents the controller
How do we get the data?
Objective-C
import ObjectiveC
The ObjectiveC module
• Exposes C APIs to interact with the ObjectiveC runtime
• Perfectly OK to use it with Swift
• More information: https://vimeo.com/107707576
• Swift and C - Mike Ash - NSSpain 2014
The ObjectiveC module
public func objc_copyClassNamesForImage(_ image: UnsafePointer<Int8>,
_ outCount: UnsafeMutablePointer<UInt32>?)
-> UnsafeMutablePointer<UnsafePointer<Int8>>?
• This function returns a list of all the classes defined in a given bundle
• That’s all the data you’ll ever need to build a basic debug view
How to use it?
extension Bundle {
func retrieveAllViewControllers() -> [String] {
guard let bundlePath = self.executablePath else { return [] }
var viewControllers = [String]()
var size: UInt32 = 0
let classes = objc_copyClassNamesForImage(bundlePath, &size)
for index in 0..<size {
if let className = classes?[Int(index)],
let name = NSString.init(utf8String:className) as String?,
NSClassFromString(name) is UIViewController.Type
{
viewControllers.append(name)
}
}
return viewControllers
}
}
How to use it?
extension Bundle {
func retrieveAllViewControllers() -> [String] {
guard let bundlePath = self.executablePath else { return [] }
var viewControllers = [String]()
var size: UInt32 = 0
let classes = objc_copyClassNamesForImage(bundlePath, &size)
for index in 0..<size {
if let className = classes?[Int(index)],
let name = NSString.init(utf8String:className) as String?,
NSClassFromString(name) is UIViewController.Type
{
viewControllers.append(name)
}
}
return viewControllers
}
}
How to use it?
extension Bundle {
func retrieveAllViewControllers() -> [String] {
guard let bundlePath = self.executablePath else { return [] }
var viewControllers = [String]()
var size: UInt32 = 0
let classes = objc_copyClassNamesForImage(bundlePath, &size)
for index in 0..<size {
if let className = classes?[Int(index)],
let name = NSString.init(utf8String:className) as String?,
NSClassFromString(name) is UIViewController.Type
{
viewControllers.append(name)
}
}
return viewControllers
}
}
How to use it?
extension Bundle {
func retrieveAllViewControllers() -> [String] {
guard let bundlePath = self.executablePath else { return [] }
var viewControllers = [String]()
var size: UInt32 = 0
let classes = objc_copyClassNamesForImage(bundlePath, &size)
for index in 0..<size {
if let className = classes?[Int(index)],
let name = NSString.init(utf8String:className) as String?,
NSClassFromString(name) is UIViewController.Type
{
viewControllers.append(name)
}
}
return viewControllers
}
}
How to use it?
extension Bundle {
func retrieveAllViewControllers() -> [String] {
guard let bundlePath = self.executablePath else { return [] }
var viewControllers = [String]()
var size: UInt32 = 0
let classes = objc_copyClassNamesForImage(bundlePath, &size)
for index in 0..<size {
if let className = classes?[Int(index)],
let name = NSString.init(utf8String:className) as String?,
NSClassFromString(name) is UIViewController.Type
{
viewControllers.append(name)
}
}
return viewControllers
}
}
How to use it?
func classFromString(_ className: String) -> AnyClass? {
let cls: AnyClass? = NSClassFromString(className)
return cls
}
That’s it
Current state
• We are able to list all the controllers of an app
• We are limited to the initializers provided by UIViewController
• We can’t provide initial data
Configure for debug
@objc public protocol ControllerFactoryCompliant {
func prepareForControllerFactory()
}
extension MyViewController: ControllerFactoryCompliant {
func prepareForControllerFactory() {
// do some configuration
}
}
Defining debug use cases
@objc public protocol ControllerFactoryUseCaseCompliant {
static func getUseCases() -> [String]
func prepareForControllerFactory(useCase: String)
}
extension MyViewController: ControllerFactoryUseCaseCompliant {
static func getUseCases() -> [String] {
return ["Case 1", "Case 2"]
}
func prepareForControllerFactory(useCase: String) {
// do some configuration according to `useCase`
}
}
Configure for debug
@objc public protocol ControllerFactoryInstantiable {
static func initForControllerFactory() -> UIViewController
}
extension MyViewController: ControllerFactoryInstantiable {
static func initForControllerFactory() -> UIViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController =
storyboard.instantiateViewController("MyViewController") as!
MyViewController
return viewController
}
}
Defining debug use cases
@objc public protocol ControllerFactoryUseCaseInstantiable {
static func getUseCases() -> [String]
static func initForControllerFactory(useCase: String) -> UIViewController
}
extension MyViewController: ControllerFactoryUseCaseInstantiable {
static func getUseCases() -> [String] {
return ["Case 1", "Case 2"]
}
static func initForControllerFactory(useCase: String) -> UIViewController {
// do some configuration according to `useCase`
}
}
Does it work?
Does it work?
YES!
How to use it in a project?
How to use it in a project?
• Available on Github : https://github.com/worldline/ControllerFactory
• Works with CocoaPods and Carthage
• Open Source (MIT License)
Questions?
Thank you!

More Related Content

PDF
Practical Google App Engine Applications In Py
PDF
Mirage For Beginners
PDF
Workshop 23: ReactJS, React & Redux testing
PDF
NestJS
PDF
Java Quiz - Meetup
PPTX
Typescript barcelona
PPTX
Swift LA Meetup at eHarmony- What's New in Swift 2.0
PDF
Martin Anderson - threads v actors
Practical Google App Engine Applications In Py
Mirage For Beginners
Workshop 23: ReactJS, React & Redux testing
NestJS
Java Quiz - Meetup
Typescript barcelona
Swift LA Meetup at eHarmony- What's New in Swift 2.0
Martin Anderson - threads v actors

What's hot (20)

PDF
Callbacks and control flow in Node js
DOCX
Cursor Demo App
PDF
LvivPy4 - Threading vs asyncio
PDF
Unit Testing Express and Koa Middleware in ES2015
PDF
Nestjs MasterClass Slides
PDF
What's New in Django 1.6
PDF
Angular - Improve Runtime performance 2019
PDF
What's new in Django 1.7
DOCX
7th lab
PPTX
Durable Functions
PPTX
Code generation with javac plugin
PDF
Reactive, component 그리고 angular2
PPTX
Avoiding callback hell in Node js using promises
PDF
Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24
PDF
End to end todo list app with NestJs - Angular - Redux & Redux Saga
PDF
Workshop 14: AngularJS Parte III
PDF
Angular 2.0 - What to expect
PPTX
From Web Developer to Hardware Developer
PDF
Reactive Thinking in Java
PDF
Angular & RXJS: examples and use cases
Callbacks and control flow in Node js
Cursor Demo App
LvivPy4 - Threading vs asyncio
Unit Testing Express and Koa Middleware in ES2015
Nestjs MasterClass Slides
What's New in Django 1.6
Angular - Improve Runtime performance 2019
What's new in Django 1.7
7th lab
Durable Functions
Code generation with javac plugin
Reactive, component 그리고 angular2
Avoiding callback hell in Node js using promises
Nevyn — Promise, It's Async! Swift Language User Group Lightning Talk 2015-09-24
End to end todo list app with NestJs - Angular - Redux & Redux Saga
Workshop 14: AngularJS Parte III
Angular 2.0 - What to expect
From Web Developer to Hardware Developer
Reactive Thinking in Java
Angular & RXJS: examples and use cases
Ad

Similar to How to instantiate any view controller for free (20)

PDF
How to build a debug view almost for free
PDF
Threads, Queues, and More: Async Programming in iOS
PDF
Optimize CollectionView Scrolling
PDF
Models, controllers and views
PDF
Objective-C Runtime overview
PDF
Mvc interview questions – deep dive jinal desai
PPTX
Asp.net mvc
PPTX
Top 10 Mistakes AngularJS Developers Make
PPT
Open Cv 2005 Q4 Tutorial
PDF
Intro to Unit Testing in AngularJS
PDF
Declarative presentations UIKonf
PPT
Rcp by example
PPTX
Surviving UI Automation Armageddon with BELLATRIX.pptx
PDF
Describe's Full of It's
PDF
Code Kata: String Calculator in Flex
PPT
Inside asp.net mvc framework
PPT
Inside ASP.NET MVC framework
KEY
L0020 - The Basic RCP Application
PPT
Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
PPTX
C#on linux
How to build a debug view almost for free
Threads, Queues, and More: Async Programming in iOS
Optimize CollectionView Scrolling
Models, controllers and views
Objective-C Runtime overview
Mvc interview questions – deep dive jinal desai
Asp.net mvc
Top 10 Mistakes AngularJS Developers Make
Open Cv 2005 Q4 Tutorial
Intro to Unit Testing in AngularJS
Declarative presentations UIKonf
Rcp by example
Surviving UI Automation Armageddon with BELLATRIX.pptx
Describe's Full of It's
Code Kata: String Calculator in Flex
Inside asp.net mvc framework
Inside ASP.NET MVC framework
L0020 - The Basic RCP Application
Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
C#on linux
Ad

Recently uploaded (20)

PPTX
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
PDF
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PPTX
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
PDF
PPT on Performance Review to get promotions
PPTX
IOT PPTs Week 10 Lecture Material.pptx of NPTEL Smart Cities contd
PDF
Operating System & Kernel Study Guide-1 - converted.pdf
PPTX
Sustainable Sites - Green Building Construction
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
PDF
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
PPTX
CYBER-CRIMES AND SECURITY A guide to understanding
PPTX
additive manufacturing of ss316l using mig welding
PPTX
OOP with Java - Java Introduction (Basics)
PPTX
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
PDF
TFEC-4-2020-Design-Guide-for-Timber-Roof-Trusses.pdf
PDF
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
DOCX
573137875-Attendance-Management-System-original
PPTX
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
PPT on Performance Review to get promotions
IOT PPTs Week 10 Lecture Material.pptx of NPTEL Smart Cities contd
Operating System & Kernel Study Guide-1 - converted.pdf
Sustainable Sites - Green Building Construction
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
UNIT-1 - COAL BASED THERMAL POWER PLANTS
CYBER-CRIMES AND SECURITY A guide to understanding
additive manufacturing of ss316l using mig welding
OOP with Java - Java Introduction (Basics)
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
TFEC-4-2020-Design-Guide-for-Timber-Roof-Trusses.pdf
Enhancing Cyber Defense Against Zero-Day Attacks using Ensemble Neural Networks
573137875-Attendance-Management-System-original
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx

How to instantiate any view controller for free

  • 1. How to instantiate any controller for free Benoît Caron & Vincent Pradeilles – Worldline Insert clickbait here
  • 3. Why? You have to make sure an app displays properly on the iPhone X, but: • Data is driven by web-services • No mocks are available • More than 150 different screens • Some screens are part of complex business scenarios
  • 5. A debug view! • Lists all available UIViewControllers • Search bar and index • Indicate a specific use case, if needed • Instantiates and pushes or presents the controller
  • 6. How do we get the data?
  • 9. The ObjectiveC module • Exposes C APIs to interact with the ObjectiveC runtime • Perfectly OK to use it with Swift • More information: https://vimeo.com/107707576 • Swift and C - Mike Ash - NSSpain 2014
  • 10. The ObjectiveC module public func objc_copyClassNamesForImage(_ image: UnsafePointer<Int8>, _ outCount: UnsafeMutablePointer<UInt32>?) -> UnsafeMutablePointer<UnsafePointer<Int8>>? • This function returns a list of all the classes defined in a given bundle • That’s all the data you’ll ever need to build a basic debug view
  • 11. How to use it? extension Bundle { func retrieveAllViewControllers() -> [String] { guard let bundlePath = self.executablePath else { return [] } var viewControllers = [String]() var size: UInt32 = 0 let classes = objc_copyClassNamesForImage(bundlePath, &size) for index in 0..<size { if let className = classes?[Int(index)], let name = NSString.init(utf8String:className) as String?, NSClassFromString(name) is UIViewController.Type { viewControllers.append(name) } } return viewControllers } }
  • 12. How to use it? extension Bundle { func retrieveAllViewControllers() -> [String] { guard let bundlePath = self.executablePath else { return [] } var viewControllers = [String]() var size: UInt32 = 0 let classes = objc_copyClassNamesForImage(bundlePath, &size) for index in 0..<size { if let className = classes?[Int(index)], let name = NSString.init(utf8String:className) as String?, NSClassFromString(name) is UIViewController.Type { viewControllers.append(name) } } return viewControllers } }
  • 13. How to use it? extension Bundle { func retrieveAllViewControllers() -> [String] { guard let bundlePath = self.executablePath else { return [] } var viewControllers = [String]() var size: UInt32 = 0 let classes = objc_copyClassNamesForImage(bundlePath, &size) for index in 0..<size { if let className = classes?[Int(index)], let name = NSString.init(utf8String:className) as String?, NSClassFromString(name) is UIViewController.Type { viewControllers.append(name) } } return viewControllers } }
  • 14. How to use it? extension Bundle { func retrieveAllViewControllers() -> [String] { guard let bundlePath = self.executablePath else { return [] } var viewControllers = [String]() var size: UInt32 = 0 let classes = objc_copyClassNamesForImage(bundlePath, &size) for index in 0..<size { if let className = classes?[Int(index)], let name = NSString.init(utf8String:className) as String?, NSClassFromString(name) is UIViewController.Type { viewControllers.append(name) } } return viewControllers } }
  • 15. How to use it? extension Bundle { func retrieveAllViewControllers() -> [String] { guard let bundlePath = self.executablePath else { return [] } var viewControllers = [String]() var size: UInt32 = 0 let classes = objc_copyClassNamesForImage(bundlePath, &size) for index in 0..<size { if let className = classes?[Int(index)], let name = NSString.init(utf8String:className) as String?, NSClassFromString(name) is UIViewController.Type { viewControllers.append(name) } } return viewControllers } }
  • 16. How to use it? func classFromString(_ className: String) -> AnyClass? { let cls: AnyClass? = NSClassFromString(className) return cls } That’s it
  • 17. Current state • We are able to list all the controllers of an app • We are limited to the initializers provided by UIViewController • We can’t provide initial data
  • 18. Configure for debug @objc public protocol ControllerFactoryCompliant { func prepareForControllerFactory() } extension MyViewController: ControllerFactoryCompliant { func prepareForControllerFactory() { // do some configuration } }
  • 19. Defining debug use cases @objc public protocol ControllerFactoryUseCaseCompliant { static func getUseCases() -> [String] func prepareForControllerFactory(useCase: String) } extension MyViewController: ControllerFactoryUseCaseCompliant { static func getUseCases() -> [String] { return ["Case 1", "Case 2"] } func prepareForControllerFactory(useCase: String) { // do some configuration according to `useCase` } }
  • 20. Configure for debug @objc public protocol ControllerFactoryInstantiable { static func initForControllerFactory() -> UIViewController } extension MyViewController: ControllerFactoryInstantiable { static func initForControllerFactory() -> UIViewController { let storyboard = UIStoryboard(name: "Main", bundle: nil) let viewController = storyboard.instantiateViewController("MyViewController") as! MyViewController return viewController } }
  • 21. Defining debug use cases @objc public protocol ControllerFactoryUseCaseInstantiable { static func getUseCases() -> [String] static func initForControllerFactory(useCase: String) -> UIViewController } extension MyViewController: ControllerFactoryUseCaseInstantiable { static func getUseCases() -> [String] { return ["Case 1", "Case 2"] } static func initForControllerFactory(useCase: String) -> UIViewController { // do some configuration according to `useCase` } }
  • 24. How to use it in a project?
  • 25. How to use it in a project? • Available on Github : https://github.com/worldline/ControllerFactory • Works with CocoaPods and Carthage • Open Source (MIT License)