The Interface Builder editor within Xcode makes it simple to design a full user interface without writing any code. Simply drag and drop windows, buttons, text fields, and other objects onto the design canvas to create a functioning user interface.
Version 1.0.0 available for Mac OS X, Windows, and Linux Storyboarder makes it easy to visualize a story as fast you can draw stick figures. Quickly draw to test if a story idea works. I'm trying to implement a sidebar like the one used in the macOS Notes app. I've got the storyboard and sidebar working. But how can I implement the content window / detail view on the right? I want to show something based on the selection made in the sidebar. I tried doing it by hiding stuff in one view but it gets messy real quick. Modifying an iOS app to run on macOS is fairly easy. It mostly involves a target-build configuration. There are, however, a couple of caveats that need to be taken into account. So far, I have not been able to port an app that uses Storyboards and Nibs. This is because Xcode will refuse to compile iOS Storyboards and Nibs when targeting macOS.
Because Cocoa and Cocoa Touch are built using the Model-View-Controller pattern, it is easy to independently design your interfaces, separate from their implementations. User interfaces are actually archived Cocoa or Cocoa Touch objects (saved as .nib files), and macOS and iOS will dynamically create the connection between UI and code when the app is run.
Storyboards
A complete iOS app is composed of multiple views through which the user navigates. The relationships between these views are defined by storyboards, which show a complete view of your app’s flow. Interface Builder’s storyboard designer makes it easy to create and design new views, and chain them together to create a complete user interface that’s ready for your custom code.
Xcode includes storyboard controllers for:
Assistant
Open the Assistant when editing your Storyboard or .xib file to quickly connect UI controls to the code that implements their behavior. If you don’t have the code written yet, Xcode will offer to create the stub for the action (method to launch) or outlet (variable to hold data) that will provide the logic for your interface.
Auto Layout
Both iOS and macOS include a powerful layout system called Auto Layout, with excellent support built in to Interface Builder. Auto Layout is based on the idea that each object in your interface can define a constraint to control how it reacts to the parent view and other interface controls. For example, you can prioritize whether a button stays a specific size or expands to accommodate larger text when displaying a different language.
Interface Builder can automatically create all your constraints for you, ensuring a set of compatible rules. You can also take direct control of constraints to define the exact priority of each, defining how your app will work on different screen sizes, when rotated, or when run in new locales.
Preview
Use the Preview mode to quickly view your interface in a variety of situations without having to run your app, dramatically speeding up the iterative design process. You can view your app in portrait or landscape format, on a previous version of iOS, on different screen sizes, and more.
Home | Articles | Talks 15 Oct 2018
————————————————————————————————————————————--
A build system, despite its scary-sounding name, is just a regular program, which knows how to build other programs. As an iOS developer, you’re certainly familiar with how to build a project using Xcode. You go to the
Product menu and select Build , or you use the ⌘B keyboard shortcut.
You may have also heard about Xcode Command Line Tools. It’s a set of tools which allows you to build Xcode projects directly from the terminal using the
xcodebuild https://yellowpro737.weebly.com/blog/gas-buddy-app-mac. command. A very convenient thing for automating your processes, for example on your CI.
No matter how you’ve initiated it, the building itself is orchestrated by Xcode’s build system.
Can we replicate the building process and build the app “manually”, without Xcode’s build system?
Is it possible to sign the resulting app? Or even deploy it to an actual iOS device?
⚠️ Disclaimer 1 ⚠️
What is this post about:
Writing a non-reusable script that builds one concrete iOS project the simplest way possible.
What is this post NOT about:
Writing a complex and universal build system.
ContentThe App We’re About to Build
I let Xcode 10.0 generate a new project using the
Single View App template, and named it “ExampleApp”. This is going to be the reference app we will try to build “manually”. The only adjustment to the project I made was adding a UILabel with ? to the main (and only) ViewController .
I also created the
build.bash file in the root folder of the project. We’re going use this file for the actual build script.
Don’t forget to make the file executable by running the following in the terminal: How to see all of your apps on mac.
Step 1: Prepare Working Folders
⚠️ Disclaimer 2 ⚠️
The complete “recipe” of how the app should be built is contained in its
xcodeproj file. This article is not about how to parse and retrieve this information from it.
We will ignore the project file for the sake of this article. To make our life easier, we will hard-code all the details like the project name, source files, or build settings, directly into the build script.
Let’s start with some housekeeping. We need to define and create a set of folders we will be using during the building process.
When you run the script, your terminal should like this:
Notice, that the script created two folders:
Step 2: Compile Swift Files
Did you know you can call the Swift compiler directly from the terminal using
swiftc ?
With the correct flags, compiling all
.swift source files is quite a straightforward operation.
I’d like to talk a little bit about the
-emit-executable flag. According to the documentation, when this flag is used, the compiler “emits a linked executable”. When you run swiftc in the verbose mode (-v ), you can actually see, what’s happening under the hood. The compiler creates .o object for every .swift file, and then calls ld to link them into the final executable file.
Notice, that we set output (
-o ) to ExampleApp.app/ExampleApp . That’s the resulting executable file from the compilation process.
Run the script and you should see the following:
You can also check, that the resulting executable was created inside the
ExampleApp.app bundle:
Step 3: Compile Storyboards
Source code files are not the only files which need to be compiled. We also need to compile all
.storyboard files. The compiler for storyboards (and all the other interface builder files) is called ibtool . The resulting files from the process have the extension .storyboardc .
Fun fact
Macos App Without Storyboard Creatorstoryboardc files are file bundles. When you inspect the content of the bundle, you will see, that a compiled storyboard is actually just a bunch of nib files.
ibtool doesn’t accept more than one file at a time. We need to use a for loop to iterate over all storyboards.
Let’s run the script and verify the content of
ExampleApp.app :
Step 4: Process and Copy Info.plist
A valid app bundle has to contain
Info.plist . Unfortunately, we can’t simply copy the one from the project directory. This raw file contains several variables which we need to replace with the actual values.
To deal easily with
plist files, Apple provides us with a tool called PlistBuddy. Because we don’t want to modify the original plist we first create a temporary copy in the _BuildTemp folder, and modify it there. Finally, we copy the processed plist to the app bundle.
Let’s run the script:
We should also verify that the processed
plist file is there, and its content is correct:
Running ExampleApp in the Simulator
At this point, we should have a valid
.app bundle. At least for running it in the iOS simulator. You can open the simulator directly from the terminal window:
To interact with iOS simulators, Apple created a tool named
simctl . Here’s how you can install the ExampleApp app bundle to the currently running simulator. The second command starts the installed app.
I must admit I was extremely surprised when I saw the app was working!
The truth is, I thought one more step would be needed. Swift doesn’t have a stable binary interface yet and Swift runtime is not included in iOS. Thus every app has to have its own copy of the Swift runtime libraries included in the bundle.
We haven’t copied the runtime libraries into the bundle but the app works!
When compiling Swift files using
swiftc , you can specify a dylib runtime search folder using -Xlinker -rpath flags. By doing so, you’re letting the linker know where to search for dynamic libraries, like the Swift-runtime ones. It turns out if you don’t specify them as I did, the search path defaults to:
This is exactly the place where the Swift runtime libraries are stored on your computer!
The iOS simulator is not sandboxed and has access to all your files. It means it can easily load the runtime libraries from any arbitrary place. I had no idea about this. Overflow app for mac.
As long as you target the iOS simulator, you can create a valid, fully functional, Swift iOS app without including the Swift runtime libs in the bundle.
Building for Device
As you can see, building for Simulator is quite forgiving. We don’t need to include the runtime libraries in the bundle. We also don’t need to sign it and deal with provisioning.
Changing the build script so it can produce a valid app bundle, which can be executed on an iOS device, is another level of fun.
Firstly, we need to let the script know when to build for device.
Let’s use the
--device flag to signal the script the desired target architecture. We update the code from step 1:
Secondly, we need to update the code from step 2:![]()
Changes we made:
Finally:
Because all the next steps will be needed only for device builds, if we build for simulator, we can exit the build script right after step 4.
Let’s add this to the end of the script:
Step 5: Copy Swift Runtime Libraries
I already mentioned, when building for device, we need to include the Swift runtime libraries in the app bundle. Fortunately, no magic is required here. We can just simply copy the libraries to the bundle.
Let’s run the script and verify the result. Don’t forget to use
--device .
Step 6: Code Signing
I spent over 20 hours trying to figure out all the steps needed to successfully build the app for device. A half of this time I spent on this one step.
Before we start, here’s a nice picture of kittens for you.
6.1 Provisioning Profile
All your installed provisioning profiles are stored in
~/Library/MobileDevice/Provisioning Profiles/ . The first challenge is to find the correct one to use for this app.
I’d strongly recommend to figure everything out in Xcode, first. If I’m not mistaken, with the free Apple dev account, you can’t even create a new provisioning profile using the web portal. You have to use Xcode for that.
Once you have the code signing working there, make a note of which provisioning profile and signing identity were used.
For the app bundle to be valid, it has to contain a file named
embedded.mobileprovision in its root. Let’s copy the correct provisioning profile to the app bundle, and rename it:
6.2 Signing Entitlements
Another file needed to successfully sign the bundle is the
.xcent file. This file is just another plist , created by merging project’s Entitlements file with additional signing information.
There’s no
Entitlements file in our project, so this part of merging is done ?.
The additional signing information, I was referring to, is the Apple dev team ID. This ID has to be the one from the signing identity you are about to use in the next step.
Let’s create the
.xcent file and set the required values:
6.3 Signing
Now, when we have all the required pieces in place, we perform the actual signing. The tool which will help us with this is called
codesign .
You need to specify which identity should be used for signing. You can list all available identities in the terminal using:
For the app bundle to be valid, we need to sign all dynamic libraries in the
Frameworks folder, and then the bundle itself. We use the xcent file only for the final signing. Let’s finish this!
Celebrate!
The last part of the script we need to write is the final message:
You can now run the script, sit back, and enjoy your victory:
Installing to an iOS DeviceMacos App Without Storyboard Software
Unfortunately, installing the app to a connected iOS device is not at all that straightforward as it was for the simulator. Luckily, there are 3rd party tools which make the task much more pleasant.
I’m using ios-deploy.
You can list all connected devices using
-c and then copy the identifier of the device.
Finally, you install the app bundle to the device using:
Next Steps
Here’s the GitHub repo with the final version of the script.
I learned a lot when writing this article. I don’t personally plan to work on this script anymore. However, if someone is interested in improving it, here are some ideas:
Storyboard App For Pc
Special thanks to Harlan Haskins for helping me with the article by answering my questions.
Do you see a typo or have a comment? PRs and issues appreciated!
Recent PostsComments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |