Developer Manual SEB for macOS

Disclaimer: This page is not yet updated to reflect the current SEB version 2.0. Most of this information is therefore outdated. Please note that the source code of SEB version 2.x is no longer available in the SEB SourceForge SVN repository, but on SourceForge Git.

This manual is providing information about the architecture of Safe Exam Browser for Mac OS X, about getting the SEB (and WebKit) sources, linking the components and how to build SEB.

Contents Hide/Show


SEB for macOS is a modern Mac OS X application, written in Objective-C, using the Cocoa system framework. It has been developed for Mac OS X 10.6 Snow Leopard and updated for OS X 10.7 Lion, we don't intend to support older system versions. SEB for macOS is using the WebKit browser engine, on which Safari on Mac and iOS and some new open source browsers like Google Chrome and Android browsers are based. SEB for macOS embeds a private copy of the WebKit framework, so Apple updates of Safari don't affect the compatibility of SEB with existing quizzes. Please note: This doesn't apply to the Mac App Store version of SEB which is using the system's built-in WebKit framework (due to restrictions of the Mac App Store).

SEB for macOS version 1.3 consists of the classes listed below. The class structure is supposed to change soon, since SEB will go trough major enhancements in the next months. Among others there will be additional preferences panes for more options and SEB will be ported to a document-based architecture to support opening multiple webpages in separate windows and tabs.

List of Classes

As usual for Cocoa applications, you also have to examine the Interface Builder XIB file to understand how SEB GUI elements work, especially Cocoa bindings in the preferences window. At the moment the GUI elements are contained the XIB files MainMenu.xib, PreferencesGeneral.xib. and PreferencesAdvanced.xib.

Getting the SEB code

Add the SEB Sourceforge repository to Xcode. In Xcode 4 you do this in the Organizer windows' Repositories tab (see the Xcode documentation for details). Name it as you like and use the URL below as Location:

Type is Subversion, and you don't need a username or password to check out the code.

You will find the current developer version of SEB for macOS at the path trunk/mac/SafeExamBrowser-src. Checkout this directory to your computer.

Localizing SEB

To translate Interface Builder xib files, you best use the ibtool command-line utility to extract all the strings. Enter in Terminal:

ibtool --generate-strings-file en.lproj/MainMenu.strings en.lproj/MainMenu.xib

The resulting file MainMenu.strings can be given to the translator. Best is to keep it in the UTF-16 text encoding format, for example Apple's TextEdit reads and saves this format correctly.

Below the commands for the other xib files:

ibtool --generate-strings-file en.lproj/PreferencesGeneral.strings en.lproj/PreferencesGeneral.xib

ibtool --generate-strings-file en.lproj/PreferencesBrowser.strings en.lproj/PreferencesBrowser.xib

ibtool --generate-strings-file en.lproj/PreferencesAdvanced.strings en.lproj/PreferencesAdvanced.xib

Afterwards you can generate a new MainMenu.xib file based on the original one and the translated strings file, again using ibtool:

ibtool --strings-file fr.lproj/MainMenu.strings --write fr.lproj/MainMenu.xib en.lproj/MainMenu.xib

Then you need to add the resource file to Xcode. I didn't find a better way in Xcode 4 than clicking on the Resource folder, adding a localisation with the + button in the utility area at the right of the workspace window and then pasting the contents of the strings-file into the new created language/region specific file (I guess there's a bug in Xcode 4, in Xcode 3 it was possible to add the files directly).

Here the commands for the other localized xib files (English to German):

ibtool --strings-file de.lproj/PreferencesGeneral.strings --write de.lproj/PreferencesGeneral.xib en.lproj/PreferencesGeneral.xib

ibtool --strings-file de.lproj/PreferencesBrowser.strings --write de.lproj/PreferencesBrowser.xib en.lproj/PreferencesBrowser.xib

ibtool --strings-file de.lproj/PreferencesAdvanced.strings --write de.lproj/PreferencesAdvanced.xib en.lproj/PreferencesAdvanced.xib

Here the commands for the other localized xib files (English to French):

ibtool --strings-file fr.lproj/PreferencesGeneral.strings --write fr.lproj/PreferencesGeneral.xib en.lproj/PreferencesGeneral.xib

ibtool --strings-file fr.lproj/PreferencesBrowser.strings --write fr.lproj/PreferencesBrowser.xib en.lproj/PreferencesBrowser.xib

ibtool --strings-file fr.lproj/PreferencesAdvanced.strings --write fr.lproj/PreferencesAdvanced.xib en.lproj/PreferencesAdvanced.xib

In the end you should check the GUI in the new localized MainMenu.xib in Xcode/Interface Builder and adjust size and position of text fields according to the length of the localized text.

Localizing String Ressources

Strings placed in the code instead of xib files are even easier to localize. In each .lproj language directory you can find a file Localizable.strings, containing all original and the corresponding localized strings. You just have to use the appropriate string-loading macros in the code (for example NSLocalizedString(@"FirstTimeUserNotice", nil) and then use the genstrings command-line tool to extract those strings and create strings files for you. For example:

genstrings -o en.lproj *.m

This command parses all Objective-C source files in the current directory and puts the resulting strings files in the en.lproj subdirectory. You can then use this English Localizable.strings file to create the according files for other languages, by replacing the English strings with the translated ones, for example:

"FirstTimeUserNotice" = "Bitte benutzen Sie die Fenster-Schliessen-Schaltfläche oder Befehlstaste+Q um SEB zu beenden und (fn+)F3+F6 um die Einstellungen zu öffnen.\n\nDieser Hinweis wird solange angezeigt, bis Sie in den Einstellungen eine Start-URL eingeben. Sie sollten dort ausserdem ein Beenden-Passwort und ein Administrator-Passwort festlegen, um das Beenden von SEB und den Zugang zu den Einstellungen einzuschränken.";

(This is one line of the German localized strings file de.lproj/Localizable.strings)

Preparing a private copy of WebKit for use with SEB

Until version 1.4.1, SEB downloaded from this website contained a private copy of WebKit. From version 1.5 it was omitted, because experiences didn't show any real advantage of using a private WebKit instead of the system's in practice, but there was a lot of additional time and effort needed for every update. Besides that at least some WebKit builds from December 2011 and January 2012 were not working on Mac OS X 10.6.8 anymore (and compiling on Snow Leopard resulted in build errors). But besides you can find how to include your private copy of WebKit if you see an advantage in that:

Check out the WebKit source code in Terminal:

Creating 32/64 bit bundles of the frameworks

For this we need the lipo command in Terminal:

lipo -create WebKitBuild/Release-i386/JavaScriptCore.framework/JavaScriptCore WebKitBuild/Release-x86_64/JavaScriptCore.framework/JavaScriptCore -output WebKitBuild/JavaScriptCore

We can check what the resulting fat framework file contains:

lipo -detailed_info WebKitBuild/JavaScriptCore

Fat header in: /Users/drs/developer/WebKit-src/WebKitBuild/JavaScriptCore
fat_magic 0xcafebabe
nfat_arch 2

architecture i386

cputype CPU_TYPE_I386
cpusubtype CPU_SUBTYPE_I386_ALL
offset 4096
size 2933032
align 2^12 (4096)

architecture x86_64

cputype CPU_TYPE_X86_64
cpusubtype CPU_SUBTYPE_X86_64_ALL
offset 2940928
size 2993520
align 2^12 (4096)

So now we have a framework file with 32 and 64 bit binaries inside!

We have to make the other frameworks fat too:

lipo -create WebKitBuild/Release-i386/JavaScriptGlue.framework/JavaScriptGlue WebKitBuild/Release-x86_64/JavaScriptGlue.framework/JavaScriptGlue -output WebKitBuild/JavaScriptGlue

lipo -create WebKitBuild/Release-i386/WebCore.framework/WebCore WebKitBuild/Release-x86_64/WebCore.framework/WebCore -output WebKitBuild/WebCore

lipo -create WebKitBuild/Release-i386/WebKit.framework/WebKit WebKitBuild/Release-x86_64/WebKit.framework/WebKit -output WebKitBuild/WebKit

In the end we have to copy the newly created fat framework binaries into the .framework bundles. You can first duplicate one of the WebKitBuild/Release directories and rename it WebKitBuild/Release-FAT. Then copy the four fat framework binaries JavaScriptCore, JavaScriptGlue, WebCore and WebKit to the right place in the .framework bundles (overwriting the old framework binaries). Usually the subdirectory xxx.framework/Versions/A/ is the right location for the framework binaries.

Add new versions of the embedded WebKit frameworks

To comply with version control, you first have to delete the old version of the frameworks in Xcode (remove it with the SVN command in terminal or in Xcode):

svn delete --force SafeExamBrowser-src/JavaScriptCore.framework

svn delete --force SafeExamBrowser-src/JavaScriptGlue.framework

svn delete --force SafeExamBrowser-src/WebCore.framework

svn delete --force SafeExamBrowser-src/WebKit.framework

svn commit -m "deleted old WebKit frameworks" SafeExamBrowser-src

Then you have to add the new frameworks to the SafeExamBrowser project in Xcode. Important is to remove the WebCore.framework from the Link Binary With Libraries build phase of the target Safe Exam Browser in Xcode, otherwise building will fail, since WebCore is only linked through its umbrella framework WebKit. The four frameworks also have to be in the Copy Files build phase.

There is a Code Signing build setting in the SafeExamBrowser Xcode project, which you will have to modify, because you don't have the ETH Zurich code signing identity. We will add an explanation about how to code sign the SEB binary to this manual after the implementation of further security measures in SEB based on checking code signatures of running processes.

So when you succeeded to build SEB with a new version of the WebKit frameworks, you can check if it is really used on this page. If it displays Your WebKit version is a nightly build, then SEB is using the private embedded WebKit.

The second target in the Xcode project, Safe Exam Browser App (which is used to build the Mac App Store version of SEB), is using the system's built-in WebKit framework.

Use this page if you want to test the JavaScript popup window opening settings in SEB 1.5.x.