Building and distributing iOS Layouts with EverLayout by@greatirl

Building and distributing iOS Layouts with EverLayout

image
Dale Webster HackerNoon profile picture

Dale Webster

Note — The bridge can also serve images to the app by routing GET requests to an Images folder. However we don’t need to bother with this as our example will download the images instead.

  • Run ever-layout-bridge in your project directory to start the server. It will by default look for a layouts directory ‘Layouts’ on port 3000, but these options can be configured with arguments: ever-layout-bridge --layouts="MyLayouts” --port=”1234”
  • The server is now monitoring our layouts and waiting for our connection, which we should initiate in our AppDelegate.
import UIKit
import EverLayout
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
#if DEBUG
EverLayoutBridge.connectToLayoutServer()
#endif
return true
}
  • Here I am importing the EverLayout library and initialising a connection under applicationDidLoad.

Note — It only really makes sense to connect to the bridge in DEBUG mode, this isn’t something you want in production.

Double Note — Your HTTP server likely isn’t using an SSL certificate, which means we need to allow arbitrary connections for this to work. If you are unsure on how to do this, see this StackOverflow answer.

  • Compile the app, and if all has gone to plan we should see a connected message in both the Xcode console, and the terminal window.

Loading the layout

Now that our app is talking to the server, we want to load a layout in our ViewController. I know we haven’t actually written a layout yet, but that is the whole purpose of the bridge — we can run this blank app and build its layout at runtime!

  • Create a ViewController.json file in the Layouts directory.
{
"name":"ViewController"
}
  • It’s important that this file contains a name property as this is used to route layout updates.
  • Open your controller file and load the layout like so:
import UIKit
import EverLayout
class ViewController: UIViewController {
private var layout : EverLayout?
override func viewDidLoad() {
super.viewDidLoad()
let layoutData = NSData(contentsOfFile: Bundle.main.path(forResource: "ViewController", ofType: "json", inDirectory: "Layouts")!)
self.layout = EverLayout(layoutData: layoutData as! Data)
self.layout?.buildLayout(onView: self.view, viewEnvironment: self)
}
}
  • In the buildLayout call we are choosing to build the layout on the controller’s view, but using self as a view environment. This is because the controller itself will contain properties that we will reference in our layout file.
  • Compile! If all goes well, this won’t crash

Writing a layout

If your app is running and you’ve seen the connected message, we can run a quick test to see if the layout updates are working.

  • Update your ViewController.json to look like the following and hit save.
{
"name":"ViewController",
"root":{
"properties":{
"backgroundColor":"orange"
}
}
}

This basic layout is applying an orange backgroundColor to its root , which in our case in the controller’s view. Your app should look like this:

Now, let’s create a real layout:

  • Go back to your controller and add these 4 properties
public let inputUsername : UITextField = UITextField()
public let inputPassword : UITextField = UITextField()
public let buttonRegister : UIButton = UIButton()
public let buttonLogin : UIButton = UIButton()

These properties are required for our login logic, the rest we can build with JSON.

  • Copy the JSON layout from here, and paste it into your layout file. Hit save and boom… we have an app!

EverLayout has found the text input and button views in the controller and applied a set a properties and layout constraints to them. However we didn’t have to create properties for the logo or even the input labels — they were described in the layout and EverLayout created them on the fly! We’re not likely going to need these properties for any logic, so why should we see them in our controller?

  • The only thing left for our login page is to wire up our buttons:

That’s All

So that’s how EverLayout works! As a note, it’s not good practice to download your app’s logo as you launch, but I just thought it made for a neat demonstration of how powerful this can be.

EverLayout is still a work in progress and very much an experiment, if you’re interesting in learning more about the project you can check out its GitHub, and the Docs.

Thanks for reading!

Tags