CHICIO CODING

Dirty clean code. Creative Stuff. Stuff.

Design thinking and Design sprint: embrace you creativity

In this new post I will talk about my experience with design sprint and design thinking during a workshop I attended.


As I already told you in a previous post, in the last few months I worked in the team Lynch at lastminute.com group on a big “app relaunch” project where we basically rewrote some sections of our main mobile apps using React Native and we did a general restyle of them with a more modern and engaging design. As a reward for the hard work the team did, our customer area manager Elena Bianchini, a manager with many years of experiences in big companies (e.g. Vodafone), decided to give us a two days retreat with a one day workshop in the location of Castelnuovo Calcea (Asti) at the bed & breakfast “Cascina Il Quercin”. Below you can find some photos of this beautiful location (yes, I want you to be envy :grin:)

Cascina Il Quercin Castelnuovo Calcea

What was the main topic of the workshop? Well, in this one day workshop our UX team shown us what is the Design Thinking and the Design Sprint framework and we tried to apply it to came up with a solution for one of the next big projects we have on the mobile app. Our UX team is composed by:

  • Diletta Assandri is a senior UX designer with many years of experiences in project all over the world with Accenture Italia. She is truly passionate for her work. She is one of the first designer I worked with that listen to what the developers have to say (“NON SI PUÒ FARE” (that we could translate as “this can’t be done”) is one of her biggest nightmares :laughing:).
  • Federica Pisuttu is the last new entry in the team Lynch. She is a Senior UX designer with many years of experience in big companies like Assist Digital and she also collaborate with various digital startup.

Let’s start from the definition of design thinking and design sprint:

Design thinking is a method for the practical, creative resolution of problems using the strategies designers use during the process of designing. Design thinking has also been developed as an approach to resolve issues outside of professional design practice, such as in business and social contexts. The design thinking process has various stages including: defining the problem, researching, forming ideas, prototyping and testing. The steps can occur simultaneously and be repeated.

A design sprint is a five-phase framework that helps answer critical business questions through rapid prototyping and user testing. Sprints let your team reach clearly defined goals and deliverables and gain key learnings, quickly. The process helps spark innovation, encourage user-centered thinking, align your team under a shared vision, and get you to product launch faster.

So design thinking is an approach to design product based on iterations of a series of step that includes: acquire a deep knowledge of the problem, prototyping and user test your new product ideas. The design sprint is the formalisation of design thinking: it is a time constrained process (usually 5 days) where all the design thinking steps are applied in sequence. During the workshop we tried to simulate a design sprint. We had just one day, so we compressed all the phases of a sprint in just a few hours :grin:.

agenda

We created two separated teams and then we started our design sprint. Let’s see the various phases we went through and the final result.

Understand

In the first phase of our design sprint we tried to understand the problem we were approaching. To do this we used an exercise called “A day in a life”. It helped us to think like our users. To apply it:

  • Start with the user’s first step or entrance into your product experience.
  • Add each step in the journey until the user’s goal has been reached.
  • Include descriptions for each step and highlight pain points along the journey.

By the end of this activity we had been able to highlight all the weakest/negative points of the section of the app we analyzed.

Crazy 8

The second phase is the crazy 8. Let’s see how our UX designers explained us this activity:

Fold your paper into 8 rectangles. Sketch 1 idea in each rectangle rather than a storyboard. Go for quantity, don’t worry about making these beautiful, these are just for yourself. Try to get beyond your initial idea.

So basically we tried to sketch out some ideas of how we could improve the section we analyzed in previous step by creating some sketch. As the definition says, in this phase it is better to favor quantity over quality of the sketch. The more ideas you get, the better it is. So everyone in the two teams started to draw at the speed of light like a 10 years old children :laughing:.

crazy 8

One big idea

The next phase is called “one big idea”. In this phase we had to choose some of the ideas we created during the crazy 8 and try to go deeper in the details. It is basically a selection of ideas: you choose what you think are the best ideas you created in the crazy 8 phase and you create a new prototype with a little bit more of details. As our UX designers explained us we had to follow these key points:

  • Start outside of the software.
  • Focus on emotions.
  • Enough fidelity to start building a prototype.

one big idea

Decide

In this phase we decided which one were the best ideas created in the previous phases. We decided by doing another exercise, the “Share & Vote”. Basically we had 3 minutes to present our idea. After the presentations each team member got “budget” of 3 dot stickers: we had to use them to vote what we thought was the best ideas. After voting the best 3 ideas were chosen as the base to create a detail prototype. So the final prototype is a mix of the best ideas created during the sprint.

decide

Prototyping

In this phase you need to create some prototype. Which kind of prototype? Let’s see again how our UX designer explained us the features of good prototype:

Your Sprint is an attempt to identify the solution to a problem. Your prototype is a chance to see how good the ideas from your Decide phase are. To do this you have to make it real enough that you can get a realistic response from a potential user when you’re in the Validate phase.

So in this phase we had to go much deeper in the details of our ideas to get a working prototype that could be used as a test with some real user. We used some of the famous tools available on the market, like balsamiq for example, and for some parts of our prototype we created a real demo.

Conclusion

That was the end of our workshop (we didn’t have enough real user for the validation test). It was very interesting to be a UX designer just for one day. Honestly, a lot of time I found myself thinking: how can I do a job where I can use and improve my creativity? Software development requires a lot of creativity, but it is not the same kind of creativity that is required to be a UX designer :relieved:. I don’t think I will ever be a designer but it was a good starting point to let me try to enter in the mindset of a UX designer (and also life is unpredictable so who knows? :blush:). Anyway…after the hard work…we had some relaxing moments :relieved:.

relax

To be noted, in the right lower corner you can see Alessandro Romano during some swim stunts with the lastminute.com mascot :laughing:. He is “the clean” a senior frontend developer with many years of experience that just got graduated from University of Insubria in Varese (student/worker at the same time like I was some years ago :blush:). So, what do you think about design thinking and design sprint? Let me know in the comments section below :blush:.

Eat Your Own Dog Food: distribute a beta version of your iOS app using Apple Enterprise Developer Program

In this post I will show you how to distribute a beta version of your iOS app using Apple Enterprise Developer Program.


In a previous post I talked about the “app relaunch” project I was involved in the last few months at lastminute.com group. During one of the last sprint before the release we started to think about putting in place an internal beta testing program to have more testing data and eventually discover more bugs before the release on the App Store (we really wanted to eat our food :smile:). We thought about using the TestFlight environment with external testers. But this solution didn’t work for us because:

  • we wanted to let everyone in the company be able to install the beta version without the need for any kind of registration. The external testers in the TestFlight environment must be registered in the “External Tester” section of you app in the App Store Connect (someone said iTunes Connect?!?!?! :stuck_out_tongue_closed_eyes:).
  • we wanted to associate the beta with a new bundle id so that we could have a custom monitoring section in the Fabric dashboard.
  • we didn’t want to go through the “light review” that Apple does each time you want to distribute a new build to your external tester. We also wanted to avoid the slow processing timing of TestFlight.

So what do we did? We put in place our custom Beta distribution program using Apple Enterprise Developer Program. By enrolling in this program you have the ability to distribute you app inside your company without the need of the App Store. You can basically create your own Company App Store!! :open_mouth: I worked on the creation of this custom internal Beta distribution program with my colleague Giordano Tamburrelli. Giordano is the Team Leader of the Lynch Team, the agile team where I work at lastminute.com group. He has a Phd in Computer Science at Politecnico di Milano university and a master degree in Computer Science at the University of Illinois. He is one of the most skilled person I ever met, both from a technical and managerial point of view (yes you know, I’m just kissing his ass :kissing_heart::stuck_out_tongue_closed_eyes:). Obviously, he is also one of the biggest nerd you could ever met :cupid::sparkling_heart:. So how did we decide to proceed? We basically did the following operation to put in place our beta program:

  • Create a new bundle identifier and a new provisioning profile in our enterprise account.
  • Create inside our app a new configuration with some customization for the Beta build.
  • Add some new scripts to automatize the creation and the upload of new beta ipa using Fastlane, Jenkins (CI), maven (for the upload) and Nexus as our repository manger (we already use all these platforms for the distribution of our release version and to store development snapshots of the ipa).
  • Put in place a mini website, configured specifically for the distribution of the beta app.

To show you the details and some screenshots of the operation we made I will use a sample project SampleBetaApp with bundle identifier it.chicio.SampleBetaApp.
Let’s start from the first step: configuration on the Apple developer account for our new enterprise program. As already explained before, we decided to create a new bundle identifier for the beta app and obviously a new provisioning profile. The procedure is basically the same of the standard program for both the bundle identifier and the provisioning profile. We just need to follow the instruction in the Apple Developer Account site in the section “Certificates, Identities & Profiles” (and maybe there’s a high chance that, if you’re reading this post you already release at least one app on the Apple app store so you already know the stuff to do :smirk:).

enterprise profiles

After that we created in our iOS project a new Beta configuration by duplicating the release one. In this way we were able to generate an ipa similar to the release one and were also able to customize some settings of our app.

beta configuration

The Build Setting that we customized are:

  • Obviously the bundle identifier. Here we used the one created in the first step (Apple Enterprise developer Account configuration). The entry that we modified in the Build settings is named “Product Bundle Identifier”.

beta bundle identifier

  • The app icon. You can add a new asset in your main assets catalog. The entry that we modified in the Build settings is named “Asset Catalog App Icon Set Name”.

beta icon

  • We added a new custom preprocessor macro in the “Preprocessor Macros” build setting to be able to detect in our source code that we are running a beta version and eventually do some custom stuff. For example we added the build version number in the about section only for the beta version. In this way our tester were able to tell us exactly which version they were using. This macro is visible only to Objective-C. If you need to do the same thing in Swift you need to customize the “Other Swift Flags” field.

beta preprocessor macro

Then we created the scripts needed to automatize the build on Jenkins and the upload of our artifacts repository to Nexus. As I said before we were already using Fastlane to automatize the releases of our app to the store. For the beta publishing process we decided to create a new lane in our Fastfile where we launch a custom script to do all the operation needed to publish our beta.

lane :create_beta_ipa do |options|
  sh './scripts/build_beta.sh'
end

As you can see below, in the script build_beta.sh we do three things:

  • We generate an archive of our app using the xcodebuild archive command using the Beta configuration we created before. We customized some other options. For example the archive path. At the end of this command we obtain a file named SampleBetaApp.xcarchive in the folder <project root>/DerivedData/Beta.
  • Then we exporte the ipa by using the xcodebuild -exportArchive command. This command needs and exportOptionsPlist file that contains some exporting options, including the provisioning profile name that must corresponds to the name of the provisioning profile we created at the beginning in the Apple Enterprise Developer account. Below the script you can find the exportOptions-SampleBetaApp.plist sample file for the SampleBetaApp project.
  • Last but not least, when the ipa is ready we upload it on Nexus using Maven (in the script below you can find some placeholder for some of the parameter used :wink:). The command is simple and clear: we are uploading our artifact, the ipa, without generating any pom version. One important thing to note: we use always 1 as version, because we decided that we don’t want to store the beta versions history. We just want to keep the last one we publish.
#!/usr/bin/env bash

TARGET="SampleBetaApp"
DERIVED_DATA_BETA_PATH="../DerivedData/Beta/"
BETA_TARGET_PATH=$DERIVED_DATA_BETA_PATH$TARGET
XARCHIVE="${BETA_TARGET_PATH}/${TARGET}.xcarchive"
IPA="${BETA_TARGET_PATH}/${TARGET}.ipa"

xcodebuild -workspace ../Container.xcworkspace
            -scheme "$TARGET"
            -sdk iphoneos
            -configuration Beta
            archive -archivePath "$XARCHIVE"

xcodebuild -exportArchive
            -archivePath "$XARCHIVE"
            -exportOptionsPlist "exportOptions-${TARGET}.plist"
            -exportPath "$BETA_TARGET_PATH"

mvn deploy:deploy-file -DgroupId="<group id project identifier>"
                        -DartifactId="$TARGET"
                        -Dversion=1
                        -DgeneratePom=false
                        -DrepositoryId=nexus
                        -Durl="<nexus repository url>"
                        -Dfile="$IPA"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>method</key>
        <string>enterprise</string>
        <key>signingCertificate</key>
        <string>iOS Distribution</string>
        <key>provisioningProfiles</key>
        <dict>
            <key>it.chicio.BETA.SampleBetaApp</key>
            <string>SampleApp Beta Distribution</string>
        </dict>
    </dict>
</plist>

At this moment we were ready to create the new Jenkins job to build our beta. We decided to trigger it using Jenkins webhook triggers. In this way we were able to trigger the build and release of a new beta by just calling an url. This job basically clone our app repository and then execute the lane create_beta_ipa that we defined before in the Fastlane Fastfile.
So in the end with all this steps above we obtained an ipa reachable at a public url (on Nexus). We decided to publish our beta using Github Pages (the same service that runs this website :hearts:). Why? Because we needed a server with HTTPS already configured. Github pages let us create the beta website really fast. So we created a new account and published a new html that contains the following code:

<html>
    <head>
    </head>
    <body>
        <p>
            <br />
            <br />
            <a href="itms-services://?action=download-manifest&url=<a base url>manifest.plist">
                <p>Install the SampleAppBeta app</p>
            </a>
        </p>
    </body>
</html>

As you can see above, in this html there’s a special link with the protocol itms-services. If a user clicks on this link from Safari browser on a iOS device, the download and the installation of the app will starts. If you look carefully at the content of the link above, you will notice there’s a reference to a url of a manifest.plist file. This is a file generated by Xcode if you export an archive with an enteprise certificate and contains some metadata for the ipa, including the location/url of the ipa to be downloaded. In our case this url was the Nexus link to the ipa. This file can be generated the first time and eventually edited if there’s any change. This is a sample manifest file that could be used for our SampleBetaApp.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>items</key>
        <array>
            <dict>
                <key>assets</key>
                <array>
                    <dict>
                        <key>kind</key>
                        <string>software-package</string>
                        <key>url</key>
                        <string>http://www.example-url-to-where-the-ipa-is.com/SampleBetaApp.ipa</string>
                    </dict>
                    <dict>
                        <key>kind</key>
                        <string>display-image</string>
                        <key>url</key>
                        <string>https://www.example.com/image.57x57.png</string>
                    </dict>
                    <dict>
                        <key>kind</key>
                        <string>full-size-image</string>
                        <key>url</key>
                        <string>https://www.example.com/image.512x512.png</string>
                    </dict>
                </array>
                <key>metadata</key>
                <dict>
                    <key>bundle-identifier</key>
                    <string>it.chicio.SampleBetaApp</string>
                    <key>bundle-version</key>
                    <string>1.0.0</string>
                    <key>kind</key>
                    <string>software</string>
                    <key>title</key>
                    <string>beta-sample.com</string>
                </dict>
            </dict>
        </array>
    </dict>
</plist>

Now we were ready to distribute our beta app, and you know everything is needed to create your own beta program. One last thing: you will need to explain to the less experienced user that they need to accept the enterprise provisioning profile from Settings -> Profiles & Device Management. If they don’t do it they will see the alert contained in the screenshot below.

enterprise untrusted developer

That’s it!!! Go to your boss and tell her/him you’re ready to create you custom iOS beta internal program!!! :sunglasses::apple:

React Native + Typescript, love at first sight. Setup in an existing app.

In this post I will show you how to setup React Native + Typescript in an existing app.


In the last few months at lastminute.com group I worked on the following project: rebuild the native mobile apps of the main brands lastminute.com, Volagratis and Rumbo with a new interface and new features. Let’s compare the old and the new home of the lastminute.com app. The changes are quite impressive :sunglasses:.

Compare home app lastminute.com

For this “app relaunch” project we decided to use React Native (I already talked about this framework in some previous posts that you can find in the archive section). We didn’t rewrite the apps from scratch. We decided to integrated React Native in the existing code base and:

  • use Native Modules to reuse some native code we already had in place for some features (for example the login).
  • write the new stuff completely in React Native whenever possible.

We also took another important decision when we started the project: we choose TypeScript instead of Javascript as main language to write our React Native stuff. What is TypeScript? It is an open-source programming language developed and maintained by Microsoft. They describe it on its official website with the following definition:

Typescript is a typed superset of Javascript that compiles to plain Javascript. Any browser. Any host. Any OS. Open source.

What does it means? It means that TypeScript is basically “Javascript on steroid”: it provides optional, static type checking at compile time. Since it is a superset of JavaScript, all JavaScript code is valid TypeScript code. TypeScript is helpful if you are a developer that comes from other strongly typed language and with you have a strong knowledge of Object Oriented programming because it let you reuse a lot of the programming technique you already know.
React Native officially supports Javascript. How can we setup React Native + Typescript? In this post we will see how to integrate React Native and Typescript in an existing app and we will add a new screen done in React Native where we will show the photo of the day that we will read from the Nasa open API. Below you can find what we will achieve. The first screen is a standard native screen. The second one is a React Native screen.

react native typescript app

Let’s start to setup our project for React Native and TypesScript. First, React Native integration. For this task we can just follow the React Native documentation regarding the integration with existing app. Then we can start to integrate TypeScript. We will use yarn as dependencies manager instead of npm (you can use it also to install the dependencies needed to setup React Native in an existing app). Yarn is a fast, reliable and secure dependencies manager released by Facebook in October 2016. Our project directories structure will be the one contained in the screenshots below. The existing native codebase is contained inside the ios and android folders.

react native typecript directories

So let’s start by installing TypeScript and the types for React Native. We can do it with the following commands from the root of our project:

 yarn add --dev typescript
 yarn add --dev @types/react @types/react-native

After that we need to configure TypeScript in our project. We can start to do that by running the following command:

yarn tsc --init --pretty --jsx react

Now we have a new file in the root of our project: the tsconfig.json file. This file is the configuration file for the tsc, the TypeScript compiler. We can customize it for our needs (React). In particular, we need to enable the option allowSyntheticDefaultImports to allow default imports from modules with no default export. We also customized the baseUrl and paths options. By settings them in this way and by adding a package.json file inside the app folder with name: "app", we can place all our source code in the app folder and when we need to import a class we will set the path starting from the app base folder (so basically we are defining the root of our source code in a nice way for our imports).
Below you can find the complete tsconfig.json file configured for our needs.

{
  "compilerOptions": {
    "target": "es2015",
    "module": "es2015",
    "allowJs": true,
    "checkJs": true,
    "jsx": "react-native",
    "removeComments": true,
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "moduleResolution": "node",
    "baseUrl": "app",
    "paths": {
      "app/*": [ "./*" ]
    },
    "allowSyntheticDefaultImports": true
  },
  "typeRoots": [
    "./node_modules/@types"
  ],
  "types": [
    "react",
    "react-native",
    "jasmine",
    "jest"
  ],
  "exclude": [
    "node_modules",
    "app/__tests__",
    "rn-cli.config.js"
  ]
}

After that we need to install the React Native TypeScript Transformer. This transformer will allow the React Native cli to automatically transpile our TypeScript code into Javascript on demand. This is the command to install the transformer:

yarn add --dev react-native-typescript-transformer

After that we need to configure the React Native cli to actually use the transformer by adding the following configuration to the rn-cli.config.js file (create it in the project root directory). This file is the React Native configuration file.

module.exports = {
  getTransformModulePath() {
    return require.resolve('react-native-typescript-transformer');
  },
  getSourceExts() {
    return ['ts', 'tsx'];
  },
};

That’s all for the main source code setup. Now we can start to set up also the testing infrastructure. We will use jest, a testing framework from Facebook, and typemoq, a TypeScript specific mocking library. To use Jest with Typescript we will install ts-jest, a TypeScript preprocessor with source map support for Jest that lets us use Jest to test projects written in TypeScript.

yarn add --dev ts-jest
yarn add --dev typemoq

As you remember from the directory structure I show you above, the __tests__ folder is not in the usual React Native project position. It is placed inside the app folder. To be able to put our test in this folder we need to add to it a jest.config.js file and set some custom option for related to the module resolution. Below you can find the entire file with all the details.

module.exports = {
    'preset': 'react-native',
    'moduleFileExtensions': [
        'ts',
        'tsx',
        'js',
    ],
    'rootDir': '../..',
    'transform': {
        '^.+\\.(js)$': '<rootDir>/node_modules/babel-jest',
        '\\.(ts|tsx)$': '<rootDir>/node_modules/ts-jest/preprocessor.js',
    },
    'testMatch': ['**/__tests__/**/*.(ts|tsx|js|jsx)?(x)', '**/?(*.)(spec|test).(ts|tsx|js|jsx)?(x)'],
    'testPathIgnorePatterns': [
        '\\.snap$',
        '<rootDir>/node_modules/',
        'jest.config.js',
    ],
    'moduleDirectories': [
        'node_modules',
        '../',
    ],
};

We are now ready to write our app. Basically the screen that shows the nasa photo is the NasaPhotoViewerScreen. This component uses NasaPhotoInformationComponent and some React Native standard component to show the information that comes from the API. The informations are fetched using the NasaPhotoService. The NasaPhotoViewerScreen and the NasaPhotoService are glued together using the Model-View-Presenter architecture
in the NasaPhotoComponentPresenter. As you can see from the code below, TypeScript has a syntax that is similar to other language like Java, C# (and many other :sunglasses:).

export class NasaPhotoService {
  async retrieve(): Promise<any> {
    return fetch('https://api.nasa.gov/planetary/apod?api_key=1cygunHJsSwDug6zJjF3emev3QAP8yFLppohLuxb')
      .then((response) => response.json())
  }
}

...

export class NasaPhotoComponentPresenter {
  private nasaPhotoRepository: NasaPhotoRepository
  private nasaPhotoView: NasaPhotoView

  constructor(nasaPhotoView: NasaPhotoView, nasaPhotoRepository: NasaPhotoRepository) {
    this.nasaPhotoRepository = nasaPhotoRepository
    this.nasaPhotoView = nasaPhotoView
  }

  async onStart(): Promise<void> {
    try {
      const nasaPhoto = await this.nasaPhotoRepository.load();
      this.nasaPhotoView.showValid(nasaPhoto);
    } catch (_) {
      this.nasaPhotoView.showAn("Network error")
    }
  }
}

...

export class NasaPhotoViewerScreen extends React.Component<Props, State> implements NasaPhotoView {
  private readonly presenter: NasaPhotoComponentPresenter

  constructor(props: Props) {
    super(props)
    this.state = {
      photo: NasaPhoto.empty()
    }
    this.presenter = new NasaPhotoComponentPresenter(
      this,
      new NasaPhotoRepository(new NasaPhotoService(), new NasaPhotoAdapter())
    )
  }

  componentWillMount() {
    this.presenter.onStart()
  }

  showAn(error: string): void {
    alert(error)
  }

  showValid(photo: NasaPhoto): void {
    this.setState({photo})
  }

  render() {
    return (
      <ScrollView style={styles.container}>
        <Image
          style={styles.image}
          source={{uri: this.state.photo.url}}
        />
        <NasaPhotoInformationComponent
          title={this.state.photo.title}
          date={this.state.photo.date}
          description={this.state.photo.description}
        />
      </ScrollView>
    );
  }
}

interface Props {
  name: string
}

interface State {
  photo: NasaPhoto
}

const styles = StyleSheet.create({
  container: {
    width: "100%",
    height: "100%"
  },
  image: {
    width: "100%",
    height: 220,
    resizeMode: "cover",
  }
});

You can check all the code of the sample described above in this github repository and see all the TypeScript components I created for the app I shown you above.
That’s it!!! React Native + TypeScript: :hearts: love at first sight :hearts:.

Blender tutorial: introduction to basics of modeling - part 2

In this new post of the series Blender tutorial I will continue to talk about the fundamental of modeling in Blender.


In the previous post of the series “Blender tutorial” we introduced the first part of basics of modeling. Let’s continue our exploration with other useful tool we can use for modeling.
Let’s start with Sculpt mode. We can enable it in the editing/interaction mode selector in the bottom bar of the 3D window. In this mode you can literally sculpt you mesh. It possible to customize the sculpt mode by setting some of its properties:

  • radius of the sculpt
  • feather of the sculpt, that changes how the sculpt fall-off
  • auto smooth
  • add/subtract to pull in/out vertices while sculpting

blender sculpting

Sculpt mode supports also paint textures and strokes. But more important it supports symmetry: by selecting and axis any change on one side will be mirrored on the other one.
Another interesting option is the edge loop modeling. Basically this means that if we select a edge loop with alt + right click in edit mode/edge select mode, we can modify the edge loop by using the 3D axis that are shown after the selection.
The next tool available for modeling is the extrude tool. With this tool we can modify our geometry and more details. In particular, we can use it to create branches, legs and other parts that are out of the main body of the mesh. We can activate the extrude under Mesh tools -> Extrude Region/Individual. The extrude region will push out the elements selected as a single block. The extrude individual will extrude the elements selected individually.

blender extrude

Another useful tool that we can use for modeling is smooth shading. We can use these to smooth the surface of objects where the polygons of the mesh have too much hard edges. We can find the it under Tools -> Shading while an object is selected in Object mode or under Shading -> Faces/Edges/Vertices while an object is in Edit mode.

blender smooth shading

The last tool we can use for some simple modeling is the subdiving mesh tool. There are two ways to do subdivision: tool:

  • subdivision of the mesh itself
  • subdivision surface

Now we will look at subdivision of the mesh itself. To do it we need to be in edit mode on the object and select all with the a key. We can find the subdivision option under Tools -> Subdivide. If we click on that a series of subdivision properties will appear, that let us customize the number of cuts, the smoothness and other minor properties.

blender subdivision

Remember: each number of cuts increment QUADRUPLICATE the number of polygon in your mesh.
In the next chapter we will talk about advanced modeling techniques and tools.

Asynchronous testing in Swift

In this post I will talk about asynchronous testing in Swift.


As we saw in this post and also in this other one, closures are one of the most important building block of Swift. They are extensively used inside the iOS SDK.
But in the previous posts about closures I didn’t answer one very important question: how can you do unit test asynchronous operation and closure? It seems Apple has the answer for us!! Inside the iOS Testing framework we have expectations.

Clarity closure expectation test

How do they work? To test that asynchronous operations (and closure) behave as expected, you create one or more expectations within your test, and then fulfill those expectations when the asynchronous operation completes successfully. Your test method waits until all expectations are fulfilled or a specified timeout expires. The general code structure for expectation with closure is like the following example:

let expectation = XCTestExpectation(description: "Expectation description")

yourInstance.method(param: "aParam") {
    <Your assert using XCTAssert...>
    expectation.fulfill()
}

wait(for: [expectation], timeout: <time to wait the fulfillment of the expecation>)

Basically to test asynchronous operation/closure you must:

  • create an expectation that is an instance of XCTestExpectation
  • execute your closure, make your assert on the closure return value/parameter and call the method fulfill of XCTestExpectation

So, what about a more complex example? Let’s see how powerful expectation are and most importantly how we can test them. Suppose for example we have a use case class called PasswordUpdateUseCase with the following implementation:

public class PasswordUpdateUseCase {
    private let passwordService: PasswordService
    private let passwordRepository: PasswordRepository
    
    public init(passwordService: PasswordService, passwordRepository: PasswordRepository) {
        self.passwordService = passwordService
        self.passwordRepository = passwordRepository
    }
    
    public func update(password: String) {
        passwordService.update(password: password) { success, error in
            if success {
                self.passwordRepository.save(password: password)
            }
        }
    }
}

As you can see inside the update method we have an instance of PasswordService that, as the method name suggest, execute an update of the user password and return the result of the operation inside a closure. How do we unit test? Let’s see how we can achieve our objective using some handmade mock and expectation. For this post I will NOT USE the “Given-then-when” structure I used in a previous post, because I want to keep the focus on the code structure. First of all, to test our use case we need to mock the PasswordRepository. In our test we want to verify if our save method has been called or not. We can achieve this objective by implementing a spy object, PasswordDatabaseRepositorySpy, that exposes a status property savePasswordHasBeenCalled.

class PasswordDatabaseRepositorySpy: PasswordRepository {
    private(set) var savePasswordHasBeenCalled = false
    
    func save(password: String) {
        savePasswordHasBeenCalled = true
    }
}

Now it’s time to mock our PasswordService. We need to mock it so that it has the following features:

  • it exposes a status property that let us know if the method update has been called
  • it simulates an asynchronous call inside the update method
  • it can fullfil the expecation of our test in time

A lot of stuff to do. Let’s see how we can implement it. We will call it PasswordNetworkServiceSpy.

class PasswordNetworkServiceSpy: PasswordService {
    private(set) var updatePasswordHasBeenCalled = false
    private let expectation: XCTestExpectation
    private let successful: Bool

    init(expectation: XCTestExpectation, successful: Bool) {
        self.expectation = expectation
        self.successful = successful
    }
    
    func update(password: String, completion: @escaping (Bool, Error) -> ()) {
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(200)) {
            self.updatePasswordHasBeenCalled = true
            completion(self.successful, NSError(domain: "error", code: -1, userInfo: nil))
            self.expectation.fulfill()
        }
    }
}

The interesting thing of our implementation is that our spy will be in charge of fulfill the expectation, because the closure executed inside the PasswordUpdateUseCase is created inside our PasswordService spy, and we have to be sure that after its execution the expectation.fulfill() is called.
Now we are ready to write our unit tests. We will test two cases: update successful and update failure.

class AsynchronousTestingClosureDependencyTests: XCTestCase {
    
    func testUseCaseUpdatePasswordSuccessful() {
        let updateExpectation = expectation(description: "updateExpectation")
        let service = PasswordNetworkServiceSpy(expectation: updateExpectation, successful: true)
        let repository = PasswordDatabaseRepositorySpy()
        let passwordUseCase = PasswordUpdateUseCase(passwordService: service,
                                                    passwordRepository: repository)
        passwordUseCase.update(password: "::password::")
        wait(for: [updateExpectation], timeout: 300)
        XCTAssertTrue(service.updatePasswordHasBeenCalled)
        XCTAssertTrue(repository.savePasswordHasBeenCalled)
    }
    
    func testUseCaseUpdatePasswordFail() {
        let updateExpectation = expectation(description: "updateExpectation")
        let service = PasswordNetworkServiceSpy(expectation: updateExpectation, successful: false)
        let repository = PasswordDatabaseRepositorySpy()
        let passwordUseCase = PasswordUpdateUseCase(passwordService: service,
                                                    passwordRepository: repository)
        passwordUseCase.update(password: "::password::")
        wait(for: [updateExpectation], timeout: 300)
        XCTAssertTrue(service.updatePasswordHasBeenCalled)
        XCTAssertFalse(repository.savePasswordHasBeenCalled)
    }
}

As you can see in this test we have an example of an expectation creation/usage. In each test we are calling the wait(for: [updateExpectation], timeout: 300) so that the tests will “wait” until the expectation is fulfilled or the max timeout is reach (and in the last case the test fails, no matter the other condition). The most strange thing is related to the order of instruction between the wait and the various XCTAssert. To make our tests work we need to wait until the closure inside the update method of the use case is completed. Then we can make our assertion and verify that our conditions are verified to make our test pass (so, in this case, we can verify that our various method on the various collaborators have/have not been called). We are done with our example. As you can see you can experiment a little bit with expectations and implement complex patterns to verify your closure. You can find the complete example discussed above here. Expectation: your true friend for asynchronous code testing :heart:.