Adonis

Adonis – Power MVC Framework with Authentication and Bootstrap

Node.js Framework Adonis as MVC

Node.js is a common language based on JavaScript. It is well know and popular since with the help of V8 JavaScript can be executed on server side. In the past JavaScript was used in browsers to enrich the client side. This is still the case but still the entrance barrier is quiet easy. This is really good to get more people on the light (development) side of live. But the downside is that JavaScript comes with the feeling it is often not well structured and developed. The same is happening on server side implementation since it is really easy to write dirty code. As well Node.js on server side is quiet new and in comparison other languages like Ruby or Java have a longer lifetime to develop MVC Webframeworks.

That’s why more and more MVC Frameworks taking the chance to proof Node.js a comparison. Adonis not only have a name which leads to the assumption of winning a comparison it also has some nice features why we took the chance to work with.

Installation

See http://adonisjs.com/ for more documentation

$ npm install -g adonis-cli
$ adonis new exampleAdonisProject
$ cd exampleAdonisProject
$ npm start

Alternative you can check out our Adonis template which contains authentication and Bootstrap + LESS + Gulp as well: https://github.com/unicorn-it/adonis-template

$ git clone https://github.com/unicorn-it/adonis-template
$ cd adonis-template
$ npm install
$ bower install
$ gulp

 

Adonis commes with ES6 (ECMAScript 2015) support

We used koa framework in past projects to develop based on our own MVC structure Node.js web applications (https://github.com/unicorn-it/koa-scaffold). We prefered koa over express since it supported ES6 too. We love the flow control of generators. That’s why we love Adonis even more.

Adonis uses Babel to complete the journey to ES6

Adonis is not only using ES6 language support which is included in Node.js so far it also uses Babel to support the hole ES6 language. This is why the code looks even more expressive and meaningful.

class HomeController {
  * index(request, response) {
    const view = yield response.view(‚index‘);
  response.send(view)
  }
}
module.exports = HomeController;

Awesome routing in Adonis

In Adonis we directly loved the routing. In our own MVC we added the routing in the main JavaScript file. So the idea is the same. Having one place where the routing deifinition is placed. This is done in Adonis by defining in meaninful language the routing.

const Route = use(‚Route‘);

Route.get(‚/‘, ‚HomeController.index‘);

Route.get(‚/‘, ‚HomeController.secured‘).middlewares([‚auth‘]);

Adonis comes with nice templating

We used to prefere SWIG as a template engine for Node.js frameworks. Its easy, its next to the syntax of AngularJS and this helps a lot to get frontend developers into it. Adonis comes with a syntax which is next to SWIG. It is called Nunjucks which is inspired by Jinja and closed to SWIG. However it helps us a lot when dealing with html in Adonis.

Very nice MVC project structure

The folder structure of Adonis is really easy to understand. This helped us a lot to understand the structure and parts of the application. It will also help other developers figuring out where to make changes to get the expected result. So switching between projects will become more easy. They will directly find what they are looking for. See the example of our project,

Adonis project structure

What’s missing

But of course Adonis is not perfect and there are many parts missing. Especially for us when we are looking for a project setup to start from scratch really easy and fast. The documentation of Adonis is nice so far but its not easy to get an understanding of how to implement security in Adonis. As well as we love to work with bootstrap based on LESS files. Therefor we need to extend the basic Adonis installation. You can check out our repository and have a look for Adonis.

https://github.com/unicorn-it/adonis-template

Have fun while using Adonis – the powerpack

iOS swift framework

iOS – Developing reusable Views in a Swift Framework

What does „Framework“ mean in iOS?

Usually a Framework is a code library, which defines a structure and offers functions to easily solve complex software and coding issues.
Regarding the iOS development the term „framework“ is a little more universal. An iOS Framework can consist of only a single class or be a complex semi application, which just has to be included and configured to produce a launchable app. Basically it is nothing more then a collection of views, controllers and other classes/files that can be shared along an infinite number of projects.

What do we want to achieve?

In this post, I will create an iOS Framework and include it in a test app project. Doing that, I will focus on the reusability of single components of the Framework.

In short, this post includes:

  • Creating a Framework for iOS-Projects with Swift
  • Including the Framework in an app project
  • Creating a resuable, configurable and extendable View that is connected to Class which defines most of its logic
    • + using that view in our test app project
  • Creating reusable classes
    • + Using those classes in our test app project

To achieve all that, I am going to create a simple Framework, containing a basic login View with a View Class, which will define the behavior of the View and offer some attributes for the possibility to configure the appearance of the View. Afterwards, I will include the Framework in a test app.

So let’s get started

Creating the Framework project is quite simple (Xcode Version 7.2.1): In Xcode, go to File -> New -> Project. Now the templates dialog should be visible.
On the left, choose -> Framework & Library, then click on Cocoa Touch Framework and confirm by clicking „Next“

create ios framework

In the following steps, you define the core data of your project as usual. Make sure you have „Swift“ selected as the project’s language.

Creating the View

So after creating the project, we can directly go to creating our first view. Our primary goal is to make this one reusable, i.e. you should be able to switch the View classes and/or Controller classes at any time.

To achieve that, we do not create that view in our Storyboard but in a seperate .xib file.

To do that, right click on your project folder and choose „New File…“

create iOS file

On the left, choose iOS -> User Interface, click „View“ and then „next“

create iOS view

I named the view „MyLoginView“. When you select it in the navigator, you can define the View the same way, you would do it in the Storyboard.

I just went ahead and created a simple login View, containing fields for username and password, a label to display error messages and a login button.

iOS standalone View

If you have never created a View before, you can learn how to do that in the iOS Documentation

Bringing the View to life

So now that we have the View, we have to take care of defining the behavior of the View. To do that, we will create a View Class, which will take care of loading the .xib file and define the behavior of its elements.

So again, click on your project folder in Xcode and select „New File…“. In the dialog, choose iOS -> Source -> Cocoa Touch Class

create iOS Class define iOS Class

To keep things structured, I gave the file the same name as its view „MyLoginView“
For „Subclass of“ choose „UIView“
and make sure the selected language is „Swift“

Now comes the tricky part. We have to make sure that the View gets properly loaded when this class is used on a Storyboard or as subview. Right now it is not possible to simply attach a file to a view so that it gets automatically assigned when dragged into the storyboard. So we need a little setup code.

I will put all the setup code in a seperate method called „setup()“. This will include the following actions (if you don’t want to know the exact behavior, you can scroll down a little and copy the setup() entirely) :

First of all, define two variables

let nibName:String = „MyLoginView“
var view: UIView!

Now, we have to load our login View and add it as subview to make it visible.

Loading the View can be done by the following one-liner:

self.view = UINib(nibName: self.nibName, bundle: NSBundle(forClass:
self.dynamicType)).instantiateWithOwner(self, options: nil)[0]
as! UIView

This line includes three actions:

  • Loading the current project bundle by creating an instance of NSBundle()
  • Loading the View file by creating an instance of UINib()
  • Creating a UIView instance of our View file with instantiateWithOwner()

The result will be assigned to our view variable, that we declared earlier.

So now that we have loaded the View file, we have to add it as subview and make sure it is properly displayed.
We do that by executing:

self.view.frame = bounds
self.view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.addSubview(self.view)

 

So our setup method looks like this:

func setup() {
self.view = UINib(nibName: self.nibName, bundle:
NSBundle(forClass:self.dynamicType)).instantiateWithOwner(self,
options: nil)[0] as! UIView
self.view.frame = bounds
self.view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.addSubview(self.view)
}

The final step is to call that function from the initializer. The UIView class has two initializers that are of our interest. One is for displaying the View inside the editor and the other one is the important one that allows us to show the view inside the real app.

I will use both:

public override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}

So that’s it, basic work is done. It is a good idea to put that part in a Base Class and let your actual views extend that class so you don’t have to copy that code to every View you create.

Now we want to get some actual logic inside that view.
To recall, we wanted to create a simple Login view and a Class that handles most of the basic work.
So to be able to do anything, we have to get references to the elements inside the view.
The first step to doing that, is setting our View Class as the .xib file’s owner

Select the MyLoginView.xib in the Navigator and then select „File’s Owner“ in the Editor area. Now select the Identity inspector tab in the utilities area and type „MyLoginView“ as Class in the Custom Class area.

set-view-owner

 

This allows us to control-drag elements from the View into our View class, so we’re going to do that.
Simply hold the Ctrl key and drag any element to the class, using the assistant editor.

control drag view element define-element-variable

Go ahead and do that with every element you want to control inside the Class. I’m going to do it with the text fields and the error label.
Additionally I will add an action for the click event that will trigger the actual login.

control drag button define button action

 

Abstraction

The purpose of a Framework is to implement most of the required logics so that you don’t have to repeat the code in the actual project, but of course there are always parts that can not be implemented in a Framework. In our case the login is one of those examples. Each app might have a different server or a different method of authenticating so we have to leave the actual login to the app itself.
How you abstract your code is totally up to you. One possibility is the use of @IBInspectable, which allows you to define properties in your View class that can be directly set in the attributes inspector of the editor.

In our case, I am just going to define a public closure attribute, which is a function that will be called as soon as the user hits the login button. So by setting that attribute in the actual app, the developer is able to implement the login process.

So in my MyLoginView class, I will add a public property

public var loginHandler:((username: String, password: String)
-> Void)?

and add the call of that function to the login action

@IBAction func login(sender: UIButton) {

if(loginHandler == nil) {
print(„No loginHandler defined“)
return
}

loginHandler!(
username: usernameTextfield.text!,
password: passwordTextfield.text!)
}

Using the Framework in an app project

For now, we have a solid Framework for a login view and of course we want to use it in an actual app.
To do that, we first have to build the Framework to create an embeddable .framework file. If you expand the „Products“ group
in the Project navigator on the left, you will see that MyFramework.framework is red. That means that it has not yet been built.
To do that, first set the active scheme to „Generic iOS device“ by selecting it in the scheme selector at the top of Xcode.

 

iOS scheme selector

Now press Cmd + B (or Product -> Build in the menu bar)

After a little bit of building, the MyFramework.framework file should appear black, so we are ready to embed it in an actual project.

Right click on the MyFramework.framework file und select „Show in Finder“.
If you step back one folder, you will see that XCode has created two build folders: Debug-iphoneos and Debug-iphonesimulator

As you may have already suggested, the first folder contains the build result for iPhone devices and the other one is for the simulator.

For simplicity, we are just going to embed the debug build for the simulator.

First we have to create our iOS project. I will name mine „MyFrameworkTest“ and use the single view application template to create it.

There are many ways to get a Framework file embedded in an iOS project, but in our case we have to make sure that the binaries are linked and embedded in our test project.
To tell Xcode to do that all at once, click on the Root node in the Project navigator (MyFrameworkTest), select the one Target under „Targets“ and select the „General“ tab.
Now scroll down to „Embedded libraries“ and click on the plus icon.

add embedded binaries

In the dialog, click „Add other“ and navigate to your .framework file

iOS choose framework

In the options dialog, leave everything as it is and click on „Finish“

Using the Framework

Now we want to use the login View, we created in the framework project.
Go to the Main.storyboard and expand the View Controller Scene and the View Controller. This should have one View and we can use that directly as
our login View.

Select that View and select the Identity Inspector tab in the utilities area on the right. In the Custom Class area type „MyLoginView“ (Xcode should autocomplete it) and type „MyFramework“ as module

iOS embed framework View

Congratulations! You just embedded your first logic containing Framework View in your own app.
But there is one thing left to do: Define the actual behavior for the login button click.

For that, i created the public loginHandler attribute in the MyLoginView class. The only thing
we have to do is initialize it with a function in our app.

First, we are going to need a Controller for this view. When you just created the app, Xcode automatically creates a ViewController. If you don’t have it or don’t want to use it you can just create another one by creating a Cocoa Touch Class and letting it extend UIViewController.

In both cases you have to make sure the controller is assigned in your Main.storyboard

iOS assign controller

Now go to the View Controller and control-drag our login View into the controller.

control-drag-login-viewname-login-view

Now we have the instance of our login View in the controller. You will notice that MyLoginView is underlined and Xcode is telling us that it can’t find that class.
That is because we didn’t include it yet in the View Controller. To do that, just add the following line above the class:

import MyFramework

Now we can define the login function in our View Controller:

func login(username: String, password: String) {
let alert = UIAlertController(title: „Login“, message:“I guess i should log in now“, preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: „OK“, style: .Default) { _ in })

self.presentViewController(alert, animated: true){}
}

and assign it as the login handler in the viewDidLoad function

override func viewDidLoad() {
super.viewDidLoad()

loginView.loginHandler = self.login
}

And that’s it! We can go right ahead and run the app.
When clicking the login button, it should show the alert dialog.

iOS app result

You can checkout the projects from our git repository

Framework project

Test project