Xcode configuration Part 1

In a non-trivial application, you probably have more than just a single environment for your project and you would find it difficult to manage the many environments and configurations manually in the code.
In this post we will tackle this issue using Xcode configuration files, and we will see how we can switch between configurations without manually modifying our codebase.

Use Case

You have an app that has different environments namely local, staging, and production. Each environment requires different configuration; the endpoints are different, the product app is different, as you want to have different app for each environment where each app has different app icon and name for example. Another ability you want, is that on staging / local builds you want to be able to use some debugging tools like Inspector or capturing network calls but not on App Store version for instance.

Setting up

  1. Go to your beloved IDE Xcode :). Create a new project or open an existent project. Since in the end we won’t to test our release App(s) you should have a valid App id (creating app ids and profiles is handled automatically by Xcode these days), so you should have access to an apple account with sufficient permissions to create certificates…
  2. Create a folder called Configurations to make it easier to spot your configuration files, in the configurations folder lets create configuration files by clicking right click and selecting new file which will open a window to select the type of the file, in the search box type config and you will see a file with Configuration Settings File, select it and click next , now name it something like Staging-Debug, keep doing this and create Staging-Release, Production-Debug, and Production-Release. “You can have as many configurations as you wish , we will stick with 4 , for this tutorial”.
  3. We will be having 2 products with different App Ids , you can name them the way you wish based on your app. for me they will be com.whitetorch.Configuragtions (Appstore/production version) and com.whitetorch.Configuragtions.staging for staging environment.
  4. To achieve that without create a target for each one, we will have to play around the product bundle identifier. In the configuration files create a new setting with name PRODUCT_BUNDLE_ID = <#the App id for configuration#> , e.g. for Staging configuration files it will be PRODUCT_BUNDLE_ID=com.whitetorch.Configuragtions.staging and for production configuration files something like PRODUCT_BUNDLE_ID=com.whitetorch.Configuragtions.
  5. Now head to Targets -> choose app target -> build settings and find Product bundle identifier setting in the Packaging section , you will find the bundle id specified explicitly but since we want it be configurable , change it to $(PRODUCT_BUNDLE_ID).
  6. Go to the Project (the blue icon with the project name) -> Info -> Configurations section, duplicate Debug and name it Staging-Debug, also duplicate Release and name it Staging-Release, and leave the original for production configurations but you can also rename them.
  7. Select each configuration and select the matching configuration file name from the drop down list a long the project name.

if you go back to the target->build settings -> product bundle identifier , you will see the correct bundle id is listed for each configuration. Also if you go to Signing and Capabilities tab , you will see that Xcode spectated both bundle identifier meaning you can actually use different teams 😀 which can be useful say you building a product for a client , you can only have the production id on the client apple account, and other stuff on your development account.

Cool!! Lengthy steps!!! !^_^.

Let’s actually use that!

Configure the schemes:

Select the only Scheme we have setup by Xcode and click on edit scheme , that will be our production scheme so we will leave the configurations as is , but make sure that “Run” has Debug build configuration, and archive has Release build configuration.

Click on Manage Schemes and rename the selected scheme to be Production App , to make it easier to distinguish.

go back to edit Scheme window and click on “Duplicate Scheme” this time change the build configuration for Run to be “Staging-Debug” and for Archive to be “Staging-Release”. In Manage Schemes window make sure the Shared checkbox is selected for both Schemes.

Test it on simulator

Finally some demoing, select the “Production App” scheme and run it on your simulator or on a device.
Select the “Staging App” Scheme and run again on same place , you should be seeing two app icons with same name which means We are on the right track :).

Now we have a proof of concept for our strategy that we can build on it, so let’s do some more.

change the app name

in each configuration file create a setting and call APP_NAME. and set it , e.g. APP_NAME = Staging app.

go to info.plist and add a new key , just select any row and press Enter, and type Bundle display name, and in the value field type $(APP_NAME), this means set the displayed name on springboard/search/settings app to the APP_NAME setting we provided earlier.

Use that in code to change View Color/Theme

As you saw before to use the settings in the Xcode level we can wrap it with $(setting_name), but we can’t do that alas in our code. and to achieve that we need another way.

  • Let’s create a new property list file and name it configuration.plist, inside it we create two new keys with Dictionary type. namely Staging and Production , under each key create a new key with String type and name it colorName. Now we have Staging and Production dictionaries where each has one key named colorName, which will be used to determine the view color of your choice.
  • Head to info.plist and create a new Key and name it ‘Environment’ of type String and in the value field type $(Environment) , now head to the configurations files xcconfig files and add new setting, name it ‘Environment’ and set a value for it matching the name we used in the configuration.plist file, so for Stage-Debug and Staging-Release.xcconfig we add Environment=Staging and so on.
  • Let’s create a utility file to be able to parse the configurations from configurations.plist to avoid redundancy.
  • Now head to the view you want to change its color and type
let colorName: String = AppConfigurations().get(key: AppConfigurationsKey.colorName)         
let color = UIColor.init(named: colorName) self.view.backgroundColor = color

AppConfigurations is a utility file , you can find it in the repo here.

make sure you add the color name in Assets.xcassets file.

This is meant just as an example , you can have whatever you want , you can add and endpoint url for instance , or maybe Some SDK key, etc…

Cool!!! Now we have a tool that can let us achieve many things.

I will stop right here , it’s too long post already. maybe it will be followed with another post soon, as am planning.

You can find the project with the custom configurations here

Useful links and references

build settings reference: https://help.apple.com/xcode/mac/10.2/#/itcaec37c2a6

Configuration Settings https://help.apple.com/xcode/mac/10.2/#/dev745c5c974



Run your iOS App in the Playground

You may have wondered if you can run the whole app inside the playground!, say you want to experiment a little faster.
Here we will go through the steps needed to achieve that.

Add the playground

Click file ->new->Playground and create a single view playground , give it a name e.g. playground and save it somewhere, then go to the directory where you saved it and copy it to your project.

Create a Cocoa Touch Framework

We need to create a framework that can be exposed to the playground later on.
To do that select the project file and under the targets section and click on the + button then choose Cocoa touch framework and name it something like playground.

Update the target membership of the source files

For the playground framework to be useful we need to add files to it, and since we are trying to run the whole project we need to add all the project files to it , and you can do that by going to the files and bundles and from the file inspector -> target membership check the playground box.

Import the project in the playground

This is where we get to see some results finally ,

@testable import playground

@testable is needed here so that the internal methods would be accessible from the playground, otherwise you need to go to each class and mark any function, property or type as public.

Cocoa pods

If you are using cocoa pods you need to add these lines to the podfile , which will add the frameworks to the playground framework target, and remove the need to code sign it. add these lines to your pod file.

given your target name is myapp

target 'myapp' do
    target 'playground' do
        inherit! :search_paths

and after that add these

post_install do |installer|
installer.pods_project.build_configurations.each do |config|

installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|

Same goes for any other framework, where you need to update the target membership of it and include the playground framework target.

Separate the playground framework from production

Since you don’t want the playground framework you just created to be shipped with the app, which will add extra space to the app binaries, you can create a development target instead and un-link the playground framework from the production target.


  • Whenever you change something in your project, you need to build it first to be able to see it on the playground.
  • Playground is not that smooth most of the time, so I won’t rely on this technique for heavy testing , but it can be nice to try out part of your project logic directly.


That should be it , you can find a working example in the demo repo, feel free to download it and try it yourself.

Xcode: increment build number per configuration

In your current Xcode project, you might have different configurations and certain configurations might have different product bundle identifier, say you have a product id for staging, another for production, and another for development.

When you push your build for TestFlight for instance you have to update the build number or the version, if you have another app for staging say com.myapp.com.staging and you use agvtool or fastlane action increment_build_number which uses agvtool , the new number will be set for the whole configurations and you will find that your staging or production builds in TestFlight have no clear convention.

we can use this script as a fastlane lane .

desc("increase the current_project_version config based on configuration")
    lane :increase_build do |option|
        fastlane_require 'Xcodeproj'
        project = "../#{urProjectName.xcodeproj}"
        target = <#targetName#>
        buildConfiguration = <#release_configuration_name#> 
        project = Xcodeproj::Project.open(project)
        project.targets.each do |mtarget|
            if mtarget.name == target
                mtarget.build_configurations.each do |mbuild|
                    if mbuild.name == buildConfiguration
                        CUSTOM_BUILD_NUMBER = mbuild.build_settings['CURRENT_PROJECT_VERSION']
                        mbuild.build_settings['CURRENT_PROJECT_VERSION'] = CUSTOM_BUILD_NUMBER.to_i + 1

to get the build number for configuration you may use almost the same script like this

lane :get_build_number_for_configuraiton do |option|
        fastlane_require 'Xcodeproj'
        project = "../#{urProjectName.xcodeproj}"
        target = <#targetName#>
        buildConfiguration = <#release_configuration_name#> 

        project = Xcodeproj::Project.open(project)
        project.targets.each do |mtarget|
            if mtarget.name == target
                mtarget.build_configurations.each do |mbuild|
                    if mbuild.name == buildConfiguration
                        CUSTOM_BUILD_NUMBER = mbuild.build_settings['CURRENT_PROJECT_VERSION']

In the info.plist file you need to set the value $(CURRENT_PROJECT_VERSION) for the key Bundle version

Versioning system in build settings should be set to Apple generic.

And make sure in the General tap the build number has a value so Xcode does not complain.

it can use some refactoring , but that should do it.


Deploying through bitbucket pipeline

bitbucket pipelines is a great feature and it can facilitate a lot of work, I won’t say its better than Jenkins or other CI tools, but I like how simple it is.

Here I will be talking about deploying a PHP api codebase into a server, it could be your production code , staging, etc…

The problem I faced is that I wanted to work locally on my php project without worrying about deploying the code into the public server, though you can use netbeans syncing feature, but that means every change you make will be deployed directly without testing, also it would be hard to avoid conflicts if you are working with other developers on the same codebase. Another way to solve it, is to use git, where you push your code and then go to the server and pull your code there, but as you see here , you need to go to the server and pull your code manually.

So the idea here is that whenever I push some code into the master branch or certain branch(s), I want my code to be deployed into the server as fast as possible, without shutting the service for long time.

Bitbucket pipeline can help us tremendously here , as we can trigger the pipeline script(s) on certain triggers (manual, schedules, on commit ), check https://confluence.atlassian.com/bitbucket/configure-bitbucket-pipelines-yml-792298910.html for more info.

after the pipeline is triggered, a certain script will be executed, and there where the work is done.

the pipeline file is a YAML file (https://en.wikipedia.org/wiki/YAML), which is really convenient to use, before we start scripting we need to enable pipeline for our project, so go to settings -> Pipelines -> settings -> click on enable pipeline switch. You will find a button saying configure bitbucket-pipelines.yml, click it.

you will see a page asking you to choose a language template , I will be using php here.

you will see an editor where you can edit the yaml file and on the side there is pipelines templates sections where you can find already made scripts you can use, like deploying to Amazon s3, firebase and so on.

For me I am going to deploy my project through ssh, you may use SFTP here and there is an already made pipeline called SFTP-deploy that you can find in the pipelines templets, but if you have a non trivial code base , it will be slow to move all the files on each commit/file change!!.

So am not going to use any pipeline and stick with the default one as starter. To transfer the data over ssh , am going to use Rsync tool, which is the one used by netbeans to sync your files with the remote server quickly since whenever you make some changes like adding new file or deleting one , rsync can sync only the updated files and does not copy the whole codebase all over again as if you used SFTP-deploy or FTP-deploy pipelines.

you can read more about rsync here “https://en.wikipedia.org/wiki/Rsync” and here https://linux.die.net/man/1/rsync

ok the pipeline code

image: "php:7.2.13"
      - step:
          name: "deployment"
          deployment: "staging" 
            - composer
            - echo "Starting Staging deplyment from master"
            - apt-get update
            - apt-get -qq install sshpass
            - "apt-get update && apt-get install -y unzip"
            - "curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer"
            - "composer install"
            - sshpass -p $FTP_PASSWORD rsync -are "ssh" --delete ./* [email protected]$HOST:$HOST_PATH --exclude runtime/

So in the pipeline configuration file here we ask to download php docker image and use it (it might need to match the one on your server), you see there is branches and under it staging, this means that when new code is updated on the branch named “Staging” run next steps , and we have 1 steps here , the first which will install dependencies and move the code from the bitbucket CI into our server. Note that none of these commands is actually executing on our server.

note that we install sshpass tool , since where moving a the files here using ssh with password , and rsync will prompt you to ask for a password in the terminal , but the script running on the CI is not interactive so we use it to overcome that hurdle.

you see that we use something like $FTP_PASSWORD, these are called repository variables and you can set them from settings->pipelines->repository variables and the cool thing about it is that you can have secured variables for something like password, so you don’t have to put the password in a plain text in the repository.

--delete : is used to be able to delete files when deleted by the source , and --exclude runtime/ means we don’t want to sync this directory since its would be a place for things like logs, and cache and we don’t want to tamper with the web service logs.

so that’s basically it.

hope its been useful for you, took me days to figure it out !^_^.

disclaimer: this is tested on small/medium size monolithic projects only and not on production, so do your testing/research and be careful. I am just sharing my experience, but please let me know if you have suggestions or rectifications.

Cleaner way to handle UITableViewCell

Its really funny and confusing when you start to implement the cellForRow or itemForRow datasource method.  Usually we do that in the ViewController, or in a special dataSource object, and you find yourself asking where should you add that piece of code responsible for configuring or handling the Cell, you would then add it in the Cell subclass itself or just bring more code to the ViewController that is barely controlling his direct view(s).

In a non-trivial world you won’t just set the title and description for the Cell, ending up with 2 to 3 lines, no!, there will be buttons, images , special layout , events and a whole set of operations going on, that is when you handle that in the ViewController it’d be messy and looks so wrong!!!


Yup , Just like UIViewController , we need a UITableViewCellController, its a bit long name so we will use CellController , since it can be a table view cell or collection view cell, or any list based views element.


simply to isolate the mess of handling a cell.

How does it look like?

class UserCellController {

let cell: UserTableViewCell
let model: UserModel

init(cell: UserTableViewCell, model: UserModel) {
self.model  = model
self.cell  = cell

func configure() {

// here we fill view items

private func fill() {
//e.g. namelabel.text = model.name

private func style() {
//e.g. namelabel.cornerRadius = 10


Inside cellForITem or the method you handle the filling the cell. 

let model = ….

let cell = …

let cellcontroller = UserCellController(cell: cell , model: model)


Now you can fill,configure and style the cell based on the model, you can validate the model and modify the input or anything else inside the CellController instead of the tableView datasource method.

As you noted there is a loose end here, as the CellController object should not live in memory for long, and its pointing strongly to the cell object, given the same cell object should be reused and filled with other content.

Based on how many cells can be visible, the table will allocate certain number of cells and keep reusing them.

To solve that we will keep these controllers a live by adding them to dictionary inside the Viewcontroller in our case.

private var controllers: [Int: UserCellController] = [:]

and inside cellForRow…

let cellcontroller = UserCellController(cell: cell , model: model)


self.controllers[cell.hash] = controller

The trick here is to use cell.hash as there are a fixed number of hashes since cells are reusable inside a tableView .


now we can handle filling and styling the cell easily , what about actions coming from the Cell itself, what if you have a button inside the cell and you want to handle it inside the ViewController since its probably something bigger than our little CellController can handle.

In that case , it is as simple as adding completion handler to the CellController constructor, or add call back as property , or  Streams as in RxSwift as property , or delegate Oo (just kidding,don’t) …



That should be it , you got yourself a separate controller that can handle list items more cleanly than dumping all the functionality inside the tableView datasource since life is not that simple and you will need to have a lot of functionalities handled by the Cell.


Useful Tools and services for iOS development 

I’d like to share a few tools I use when I work on iOS projects.


Consist of a set of great tools that you can easily integrate to your app , one of the most valuables tools for me is Crashlytics where you can send Beta builds and receive crashes when they occur. You can add as many apps freely and manage them, and you can have teams with ability to manage their access. Also service hooks is really handy e.g. send a slack message when a crash reaches some level on some App. Answers tool will give you Analytics with many options as setting events ,observing retention, engagement and many more.. All you need is download the fabric app and it will guide you through the integration seamlessly. There is an iOS app for fabric for tracking your apps.


Automate your deployment from generating certificates to uploading to the App Store , it’s wonderful and time saving. One of my favorite tools is match which will automate certification and provisioning for the whole team using git, along with register_devices action you will be able to add new devices , recreate certs and profile without even visiting developer.apple.com (you still need to have access to the apple account). It has many actions and the docs is neat, you may check the many examples as well. (Having some knowledge of ruby will be very handy to you).


The famous dependency manager for swift and Obj-c. It allows you to use open source / private libraries easily, few commands and your up to go. It makes it easy to update your dependencies and easy for Pods makers to update their Pods, so when there is new swift version , all you have to do is to update the Pods and you should be fine (JK you still have to suffer 😂😅, but it will be easier 😄). Another important feature is private pods that you may share with your team privately.

Another famous dependency manager is Carthage which I don’t use a lot, but one thing good about it is that it makes build time faster, so if you are using a big and well known frameworks you may consider using carthage for them, and leaving smaller and less complete libraries in Cocoapods so that you can change and experiment on them on Spot.


An awesome tool for code generation from static files such as fonts , images , string files , nibs/storyboards, colors from .clr files.. which means no miss spelling errors and you get compile time assistant. I made this script that will generate Obj-c class from localizable.string which is a good practice to have your Strings encapsulated in methods or properties ..


It allows you to generate Model classes from JSON Objects, which is very useful for mapping API responses. It supports Java,Obj-C, and Swift, with number of libraries like Mappable, Realm, CoreData … JSON Accelerator is another amazing tool with the same goal for obj-c ,java, and Python.


To generate app icons including icons for App Store, all you need is to upload 1024 icon and you will get all icon sizes for ios,android, and watch os.


Upload an IPA and send it to the customer and they can view it on the web, no UDID needed!!!. Its great for demoing an example of a library or framework you made instead of asking the user to download and integrate or making a gif!!!. Really useful and amazing.


This is the best GUI tool you can get to deal with Git and its free!!. It make working with Git a breeze. You get many options  like commit,push,merge,rebase,stash,resolve conflicts,reset , log all commits for certain file and revert to any version , add to index ,remove ,ignore ,checkout from any commit and more without the need to use terminal… though you still have terminal button to use terminal for more advanced operations .
If you use bitbucket like me, you get clone in sourcetree button for faster cloning as bonus, but you can have account added in the App and you can fetch all your repositories and clone any without going to bitbucket website.

Another tool is Github Desktop but with way less feature than sourcetree. Still useful to have it to use the open in desktop button in github !!.


Its awesome website that you should check if you have not, where you can find amazing controls for iOS, macOS, watchOS,and tvOS. there are thousands of useful open source projects mainly as UI Components. Most of the New Projects have appetize embedded and you can try the control before using it. I would suggest to keep checking it from time to time , and to try to contribute in the projects.


awesome website for importing and generating xliff files for iOS, you simply import your xliff file, update the translation on the website and then export it to be used in Xcode.  Localise.biz  is not free but you can generate android xml and iOS .string localization files altogether.


Paw (trial)

Best API Tool I ever used , what makes it great is that it can generate code for you in many languages, which you can use for fast prototyping. Paw has ability to add extensions for Importers (e.g. API blueprint, swagger, postman) and Exporters (curl, swift , java ..). and many other features.

Sketch (trial)

The best tool to design a mobile app, its simple to use for developers, where you can easily explore the design given by the designer and export its elements, figure out the sizes and colors , and modify the design easily. It’s even simpler for non-designers like me to use and make nice designs with help of free resources like this amazing website https://www.sketchappsources.com .

One amazing thing is that its pluggable where you can find many plug ins that do awesome features like AutoLayout by anime . Another nice thing is that it’s vector based where you can design in 1x and export in 3x and more , plus with the ability of Xcode to handle pdf you can export sketch resources in pdf :).

PaintCode (trial)

Will convert your SVG drawings and designs into Code ,swift/objc/android/javascript . Having the design in code will give you more abilities , simply you can customize anything like fill color, border colors/width/shape, etc.. and one important thing is Animation, PaintCode have a feature called Variable which makes it easy play with things like colors, positions, rotations …


These are useful subset of tools That I use always and works perfectly for me. There are many great tools out there that can make your life better and it’s good to try and see, one website that can help in that is thoughtworks.com.

Xcode interface builder Tips and tricks

Xcode 8.2, Interface builder, Storyboard, Swift

Hey, I wanted to share view tips and tricks you may use if you like laying your design in interface builder.

Media Library

In the Utilities section (the one on the right), there is libraries section where there is the Object Library we use all the time, on the right of it you can see the Media library where you can find images way faster and drag-drop them into your views. Your images are not supposed to be in an Assets Catalog, but I noted 1x images are not recognized.

Localization Lock

Allows you to look some or all of a view properties. Comes in handy to avoid accidental modification e.g. on layout or strings. You can lock the whole storyboard from Edit menu -> Localization Lock or specific views from Identity Inspector under Document.

Embed In /Unembed And Arrange

You may have a couple of views you want to bundle together under a UIView/ScrollView/stackView, Instead of dragging new view and then drag them into it , you can select them and from edit->Embed in you may select one of the options UIView/ScrollView/stackView, and you can embed your scene into a UINavigationController/UITabbarController unless its a Tab Bar Controller, in case it’s a navigation controller it can be embedded into a Tab Bar Controller only . The other way you can select the containing View and choose Unembed from editor. Note that Autolayout constraints will be cleared.

Arrange (send to front,back,backward, and forward): select a view and from edit->arrange you may change its order among its siblings view (same level).

Refactor to storyboard

You may select a scene or more than one and the edit->refactor to storyboard then you will be asked to name the storyboard and you will have a new storyboard file with the selected scene(s).

First Responder

It’s a set of functions that can be applied to the first respondere.g. TextField. There are some of functions already defined such as undo,selectAll,copy,… . plus you can create your own functions. all you need is to connect UIControls actions in the storyboard as usual but now with the First Responder.

Color Palette

This is very useful feature , since you will use certain set of colors redundantly in the project, it’d be helpful to create a color palette for ease of access. You may check how from here.

Designables And Inspectable

Marking a UIView subclass as @IBDesignable will tell the interface builder to refresh the view whenever a change occurs to its attributes. Although in more complex scenes and bigger storyboards this feature could be a pain to the compiler and you may ending up turning it off 😀 .

Marking a property as Inspectable will make it shows in the Attributes Inspector and allows you to edit your custom properties from the interface builder.
Using Both features Can be great for prototyping. To avoid slowness you need to turn off “Automatically refresh views” form edit menu. plus make your storyboards smaller.

That’s it for now, will keep adding whenever I find more interesting IB stuff. Hopefully they come in handy.

Xcode : Create color Palette in Interface builder

Every project has its own set of colors, and if you use Interface builder like me, then you probably would like to create a color set for each project so you don’t get mad when you want to set a color for some text and not finding it in the “Recently used Colors” Section !.

You can simply create your own color palette in IB by clicking on the color picker -> Color palettes -> Click on the settings icon and click on new. 🙂

After that you can click on the settings icon again and rename the palette. And then you can add the colors related to the project you want.

And here you can see how it’s done in pictures . Have fun.


screen-shot-2016-12-15-at-10-31-49-am screen-shot-2016-12-15-at-10-32-08-am screen-shot-2016-12-15-at-10-32-15-am screen-shot-2016-12-15-at-10-32-31-am screen-shot-2016-12-15-at-10-32-42-am screen-shot-2016-12-15-at-10-33-34-am


Xcode 8.1 umbrella header not found

I have an xcode project that I use as a framework.
I got this issue after upgrading to xcode 8.1 saying ” Umbrella header ‘nameofmodule.h’ not found’







create a header file and name it as your modulename is.

screen-shot-2016-11-21-at-2-45-38-pm screen-shot-2016-11-21-at-2-45-47-pm








in the header file add these lines

#ifdef __OBJC__

#import <UIKit/UIKit.h>


FOUNDATION_EXPORT double <#modulename#>swiftVersionNumber;

FOUNDATION_EXPORT const unsigned char <#modulename#>swiftVersionString[];


thats it.



Protect your project from dependencies (iOS – swift)

The Issue

Here I will talk about some ways I use to protect my projects against changes in its dependencies.
Whats clear is that every library/framework you use in your project would change at some time, and sometimes we change our mind about these dependencies and replace them with others.

Lets first talk about replacing a library. So we have some library that filter an image, lets call it MOImagesFilter, where you provide it an image and what filter you want to use and then it returns the filtered image. Later you find that this library produce a couple of bugs or does not work well with orientation or 3x screen …. And you decide to use a more famous library called e.g. FastImageFilters! and try it.

But wait …

You already imported MOImagesFilter in 10 classes , and in each class there is a couple of lines related to it. FastImageFilters may have totally different APIs and eventually you find yourself updating 30 lines of code !!! Oo

Adapters to the rescue

The idea here is to point all those calls to one class thats more native to our project where you don’t event need to import it in other classes. That class will be responsible to translate the library we intend to use into one formatted language our project understands.

So we create a class lets call it ImageFiltersAdapter that deals only with MOImagesFilter and does what it does , so we don’t have to deal directly with MOImagesFilter directly at all.
We predefine a set of functions that we actually need from the library , we might not need all of the function , in our case we only needs a function where we give it an image with the intended filter and it returns a filtered image.

Later on if we decide to use FastImageFilters we only change in the adapter class , not all the e.g. 3o lines of code and 10 classes.
Another benefit is that we might not need all the functionalities from some library but just a subset.
Also anyone including you when later tries to understand what we are doing here with the filter class will understand easily instead of going to the original library and read through it.

This not only useful when we replace libraries but also when we update a library where its APIs may have changed.