Skip to content

Using the SDK

Nick Gerard edited this page Nov 20, 2015 · 11 revisions

Using the SDK

After installing the SDK, the simplest way to get started is to run one of the included samples. We recommend starting with the WOCCatalog sample app, which demonstrates an assortment of iOS and XAML UI controls.

To run the sample:

  1. Navigate to winobjc/samples/WOCCatalog
  2. Double-click on WOCCatalog-WinStore10.sln to open in VS2015
  3. In VS2015, right-click on the WOCCatalog (Universal Windows) project
  4. Select "Set as start up project"
  5. Use Ctrl-F5 to build and run the app

Looking beyond the samples, there are two ways to use the SDK. The first is to [[use the vsimporter tool|Using-vsimporter]] to import your existing Xcode project into a Visual Studio solution and the second is to instead add Objective-C functionality to a new or existing Visual Studio project.

Visual Studio project properties

With the correct .targets file loaded, the Properties panel for your project (in Visual Studio) presents you with several new categories of options. Some key options are listed below.

Item type

Right click on a file in the Visual Studio solutions explorer, and click on Properties. Under the General section, you should see a field called Item Type.

FileProperties

This field tells Visual Studio about the type of each file in a project. By default, Visual Studio should automatically set .m and .mm files to be of type Clang source (this ensures that they are built with the correct compiler – clang rather than cl). Similarly, c++/cx files (.cpp extension) should continue to be set as C/C++ compiler type.

Another important item type is Starboard Resource. Items set to this type are copied into the app package, which is useful for application assets.

These types should be set automatically, but you can use the menu to override the default behavior or correct any issues.

Clang

In the Visual Studio solution explorer, right-click on your project and click Properties. You should a set of properties under Clang.

ProjectProperties

This process can be used to see/edit properties related to building .m and .mm files. For example, you can see whether or not ARC is enabled or specify the #include paths that are relevant to building these files.

Using Windows APIs from Objective-C

There are a few different ways to leverage Windows APIs from your Objective-C app. Specifically, you can either add .cpp files to your project and, from there, leverage c++/cx or you can alternatively use Windows APIs directly from Objective-C.

To support direct usage of Windows APIs, the include/Platform/Windows 8.1/UWP directory contains a set of header files, each of which maps to a Windows namespace. For example, WSystem.h maps to the Windows::System namespace and this header file contains an Objective-C projection of the APIs in that namespace. Similarly, classes are prefixed with the letters that constitute their containing namespace, so Windows::System::Launcher is presented as an Objective-C @interface named WSLauncher.

The underlying implementations for these Objective-C projections use the Windows Runtime Library and are located in the libraries in lib/Windows 8.1/x86.

To see a detailed example of directly calling Windows APIs in Objective-C, take a look at our WOCCatalog sample app.

Add *.cpp and use cx/Windows APIs

If you want to call Windows APIs in .cpp, you should set the proper pages same as ConsumeRuntimeComponent.cpp.

Right click the *.cpp and choose Properties and set the pages:

  1. Item Type: C/C++ compiler
  2. Code Generation->Runtime Library: Multi-threaded Debug DLL (/MDd)
  3. Precompiled Headers-> Precompiled Header: Not Using Precompiled Headers
  4. Command Line -> Additional Options: "$(AdditionalOptions) -D_WOC_APP"

Then you can use c++/cx or Windows APIs.

Async APIs

Asynchronous operations are supported through Objective-C via callbacks to blocks. For example, the Objective-C signature for launchUriAsync is:

+ (void)launchUriAsync:(WFUri *)uri success:(void (^)(BOOL))success failure:(void (^)(NSError*))failure;

The important parts are the success: and failure: parameters, these blocks are invoked with the given parameters when the async operation succeeds or fails respectively. All async APIs are exposed to Objective-C using this same pattern.

Constructors

Looking at the async example again, you can see that it requires a WFUri. This is defined in WFoundation.h and you can create one using the following method in WFUri:

+ (WFUri *)createUri:(NSString *)uri;

In c++ the Uri class has a normal constructor of Uri(String^ uri). However, in Objective-C constructors are mapped to static create methods. When constructors take multiple parameters, the parameter names are hard-coded into the Objective-C function signature:

+ (WFUri *)createWithRelativeUri:(NSString *)baseUri relativeUri:(NSString *)relativeUri;

Type interoperability

Looking again at the createUri constructor, notice that it takes an NSString as a parameter. This usage is possible, because the interop layer allows you treat HSTRINGs as NSStrings and vice versa.

Similarly, looking at the Windows::Networking::Connectivity::ProxyConfiguration class in c++, you can see the ProxyUris property:

property IVectorView<Uri^>^ ProxyUris {
    IVectorView<Uri^>^ get();}

This property is used to access a list (an IVectorView) of ProxyUris. When projected into Objective-C, the property appears as follows:

@property (readonly) NSArray * /*WFUri*/ proxyUris;

The IVectorView is mapped into an NSArray and, therefore, this API may be used from Objective-C by using the built in NSArray type.

Interoperability for other types (enumerators, maps, etc.) is still under development.

Event registration

Similarly to async functionality, event handlers can be provided using Objective-C blocks. For an example of this, see winobjc/samples/WOCCatalog:

[xamlWebView addLoadCompletedEvent: ^void(RTObject * sender, WUXNNavigationEventArgs * e)
{
    _welcomeLabel.text = e.uri.rawUri;
}];

XAML interoperability

Even though your app might be using UIKit, WinObjC uses the XAML compositor to manage your views and perform animations on them. This functionality is implemented by tying CALayers to XAML elements. For most standard use cases, such as getting your iOS/UIKit/OpenGL app running, this implementation detail doesn't really matter. You can continue to use UIKit and CoreAnimation as you’re used to.

However, when combined with Windows API interoperability, this approach makes certain use cases, such as mixing-and-matching UIKit and XAML components, simple and straight forward. You can, for example, create a XAML webview and place it in your UIKit based application:

// Create the Windows::Xaml::Control::WebView and set the destination URL
WXCWebView *xamlWebView = [WXCWebView create];
[xamlWebView navigate: [WFUri createUri: @"http://www.bing.ca"]];

// Create a CALayer and add the Xaml control to that layer
CALayer *nativeLayer = [CALayer new];
nativeLayer.masksToBounds = TRUE;
[nativeLayer setBackgroundColor: [UIColor greenColor]];
[nativeLayer setFrame: CGRectMake(80, 200, 450, 250)];

//  Set contents of the CALayer to be a native Xaml Element
[nativeLayer setContentsElement: xamlWebView];

xamlWebView.Width = 850;
xamlWebView.Height = 550;

// Add the layer to the containing window
[[_mainWindow layer] addSublayer: nativeLayer];

See winobjc/samples/WOCCatalog for more extensive use of this functionality.

##Modifying an iOS app for Windows While the Windows Bridge for iOS provides support for Objective-C within a UWP app, there are some differences between the iOS and Windows platform that might necessitate code modifications or additions.

###Screen size and resolution Windows supports a wide variety of form factors and screen sizes. For a good user experience, your app should be aware of and respond to the configuration on which it's run. That means, at startup your app needs to specify:

  • How large (width/height) it should be
  • What magnification it should render at
  • How window resize should be handled

To specify these behaviors, simply create a Category for your UIApplication in your AppDelegate called UIApplicationInitialStartupMode

@interface UIApplication(UIApplicationInitialStartupMode)

You can then add a method setStartupDisplayMode that is called at startup and define the appropriate settings using a WOCDisplayMode object.

+(void) setStartupDisplayMode: (WOCDisplayMode*) mode { ... }

There are a number of properties exposed by the WOCDisplayMode object, but for simplicity the DisplayPreset property can be used to set behavior to several predefined configurations.

  • WOCDisplayPresetPhone320x480: Configures a phone app with 320x480 resolution
  • WOCDisplayPresetTablet768x1024: Configures a tablet app at 768x1024
  • WOCDisplayPresetNative: Configures app to use the size and aspect ratio of the containing window
  • WOCDisplayPresetNative2x: Configures app to use the size and aspect ratio of the containing window, as well as apply a 2x magnification

If you'd like to instead manually configure properties of the WOCDisplayMode object, the following are available.

  • autoMagnification: This property can be used, along with a fixedWidth and fixedHeight, to handle window size changes by simply "zooming" in/out. The pixel width/height of your app will remain constant (as specified below) but the magnification will change with window size.

  • sizeUIWindowToFit: This property resizes the application windows along with the containing window. If this is set to FALSE then the application will remain at the specified (original) size irrespective of its containing window.

  • fixedWidth: This property specifies the width, in pixels, of the application. If set to "0" then the width of the application will follow the width of the containing window.

  • fixedHeight: This property specifies the height, in pixels, of the application. If set to "0" then the height of the application will follow the height of the containing window.

  • fixedAspectRatio: If this property is set to 0 then the app has no fixed aspect ratio. However, if it has a non-zero value, then the provided aspect ratio will be maintained throughout any resizing operations.

  • magnification: If this property is set to 0 then the application may zoom in/out as the window is resized. However, if set to a non-zero value then the magnification is fixed and this may be used to increase app size on high resolution displays.

For a detailed walkthrough of handling screen resolution, take a look at DisplayModeViewController.m and AppDelegate.m in the WOCCatalog sample. To see the complete interface, you can view include/UIKit/UIApplication.h.