Windows Bridge for iOS: Customizing the Surface Dial Experience

In part one of the Windows Bridge for iOS series, we created a simple to-do list app in Xcode and used the iOS bridge to bring it over to Windows 10. In part two of the series, we went on a tour of Visual Studio for iOS developers. In part three, we used the Windows Bridge for iOS to convert an iOS calculator app created using Storyboards and Auto Layout to a Universal Windows Platform app that adjusts to various form factors on Windows 10. In part four, we discussed how to mix and match UIKit with XAML controls in a bridged UWP app.

Today, we explain how to customize the Surface Dial Experience for bridged UWP apps using Objective-C projections.

Getting Started

For today’s tutorial, you will need:

If you don’t have a Windows 10 PC, you can download one of our pre-built evaluation virtual machines from the Windows Bridge for iOS website. Download the package for your preferred virtualization environment and you’ll be up and running in no time.

Understanding the Project Structure

With the radial control sample initial code downloaded and unzipped on your Mac development environment, open the Xcode project and briefly explore the application. The application consists of:

  • AppDelegate – contains the UIApplicationInitialStartupMode Category that ensures the app scales properly on Windows 10 for a variety of form factors.
  • ViewController – provides the view management infrastructure for the app’s user interface, which consists of a slider, a label that is updated with the value of the slider and a switch.

Build and run the application in the simulator and move the slider to make sure everything is properly set up.

Using vsimporter

You are now ready to run the app through the vsimporter tool. To do so, you’ll need to copy your Xcode project files to your Windows Machine (or VM). With the files copied, follow the steps under the Using vsimporter section of part three of the blog series. Once you’re done, return to your radial control project directory, which should now contain a brand new Visual Studio solution file.

Open the Visual Studio solution by double-clicking on the RadialControlSample-WinStore10.sln file and build and run the application on your local machine by clicking on the Run button on the top menu. You’ll notice the same UI we saw running in the Xcode Simulator — you now have a native iOS app running on Windows. Try moving the slider and you’ll see its value label change.

Adding a New Menu Item to the Radial Controller Tool

You will now update this app to add a custom menu item to the radial controller tool that will respond to rotate and click actions by changing the slider value and toggling the switch.

To implement radial controller features in your app, you will need the public headers for the relevant UWP frameworks. In the bridge SDK you downloaded, go to the includePlatformUniversal WindowsUWP directory and take a look at what you find. Each header file represents a different namespace within the Windows Runtime APIs. For our purposes, you will need APIs from Windows.UI.Input since the radial controller is an input device and all of its classes are contained in that namespace.

To include this framework – and make sure it’s only included when the code is being run on Windows – start by adding an #ifdef and the #import macros to the top of the view controller implementation file:

#import "ViewController.h"
  
  #ifdef WINOBJC
  #import <UWP/WindowsUIInput.h>
  #endif

To interact with the radial controller, you will need to add a property to the view controller of your app that will allow you to access it. In C++, wheel input devices are represented by the RadialController class. However, as you build using Objective-C projections, you will notice that the standard naming scheme for these objects has been modified to match Objective-C conventions, where classes are prefixed with the letters that constitute their containing namespace:

  • Windows.UI.Input.RadialController becomes WUIRadialController

As a result, add a WUIRadialController property to the @interface section of the view controller implementation file:

 @interface ViewController()

  @property UILabel *demoTitle;
  @property UILabel *demoInfo;
  @property UISlider *slider;
  @property UILabel *sliderLabel;
  @property UISwitch *switchControl;

  #ifdef WINOBJC
  @property WUIRadialController* radialController;
  #endif

  @end

Next, you need to get a reference to the WUIRadialController object with the CreateForCurrentView method as explained in the RadialController class documentation. Looking at the WindowsUIInput.h header you’ll find the equivalent Objective-C projection under the WUIRadialController class interface:

  @interface WUIRadialController : RTObject
  [...]
  + (WUIRadialController*)createForCurrentView;

Call this method at the end of the viewDidLoad method of the view controller file to instantiate the WUIRadialController property:

- (void)viewDidLoad {
    [...]

  #ifdef WINOBJC    
    // Create a reference to the radial controller
    self.radialController = [WUIRadialController createForCurrentView];
  #endif
  }

Now you need to get a reference to the radial controller menu and its items. This is done via the Menu property of the RadialController class that returns a RadialControllerMenu object. Looking back at the  WindowsUIInput.h header, you’ll find the equivalent Objective-C property under the WUIRadialController class interface that returns a WUIRadialControllerMenu object:

@interface WUIRadialController : RTObject
  [...]
  @property (readonly) WUIRadialControllerMenu* menu;

Call this property to get a reference to the radial controller menu:

- (void)viewDidLoad {
    [...]

  #ifdef WINOBJC    
    // Create a reference to the radial controller
    self.radialController = [WUIRadialController createForCurrentView];

    // Get the radial controller menu
    WUIRadialControllerMenu* menu = self.radialController.menu; 
  #endif
  }

The menu items are accessible via the Items property of the RadialControllerMenu class. As before, the interface of the WUIRadialControllerMenu class in the WindowsUIInput.h header gives you the equivalent Objective-C property:

  @interface WUIRadialControllerMenu : RTObject
  [...]
  @property (readonly) NSMutableArray* /* WUIRadialControllerMenuItem* */ items;

Call this property to get a reference to the menu items:

  - (void)viewDidLoad {
    [...]

    // Get the radial controller menu
    WUIRadialControllerMenu* menu = self.radialController.menu;

    // Get the menu items
    NSMutableArray* menuItems = menu.items;
  #endif
  }

Next, you need to create a new RadialControllerMenuItem object to add to the menu with the projection of the CreateFromKnownIcon class method:

@interface WUIRadialControllerMenuItem : RTObject
  + (WUIRadialControllerMenuItem*)createFromIcon:(NSString *)displayText icon:(WSSRandomAccessStreamReference*)icon;

Call this method to create the new menu item:

- (void)viewDidLoad {
    [...]

    // Get the menu items
    NSMutableArray* menuItems = menu.items;

    // Create a new menu item
    // To use your own custom icon for the menu item, use the createFromIcon method instead
    WUIRadialControllerMenuItem* newMenuItem = [WUIRadialControllerMenuItem createFromKnownIcon:@"Custom Tool" value:WUIRadialControllerMenuKnownIconRuler];
  #endif
  }

Note that we reused an existing icon for our tool from the RadialControllerMenuKnownIcon enumeration, but you can create your own and use the CreateFromIcon method instead.

Finally, add your new menu item to the menu items array:

  - (void)viewDidLoad {
    [...]

    // Create a new menu item
    // To use your own custom icon for the menu item, use the createFromIcon method instead
    WUIRadialControllerMenuItem* newMenuItem = [WUIRadialControllerMenuItem createFromKnownIcon:@"Custom Tool" value:WUIRadialControllerMenuKnownIconRuler];
  #endif

    // Add a new menu item
    [menuItems addObject:newMenuItem];
  }

That’s it! Now build and run your application and press and hold the Surface Dial to see the new menu item appear.

Adding a Handler for Click Input

In this section, you will add a handler for click input that will toggle the application switch control if the radial controller is clicked when the new tool you added to the menu is selected. Taking a look at the WindowsUIInput.h header, you’ll see you need the addButtonClickedEvent: method:

@interface WUIRadialController : RTObject
   [...]
   - (EventRegistrationToken)addButtonClickedEvent:(void(^)(WUIRadialController*, WUIRadialControllerButtonClickedEventArgs

Since the callback relies on Objective-C blocks, you need to mark the self reference with the __block keyword before using it to access the switch to avoid creating a retain cycle. Add the following code at the end of the viewDidLoad method to do this:

  - (void)viewDidLoad {
    [...]

    // Add a new menu item
    [menuItems addObject:newMenuItem];

    __weak ViewController* weakSelf = self; // Ensures self will not be retained
  }

Now you can safely toggle the switch in the radial controller click callback:

 - (void)viewDidLoad {
    [...]

    __weak ViewController* weakSelf = self; // Ensures self will not be retained

    // Add a handler for click input from the radial controller
    [self.radialController addButtonClickedEvent:^(WUIRadialController* controller, WUIRadialControllerButtonClickedEventArgs* args)
     {
         [weakSelf.switchControl setOn:!(weakSelf.switchControl.on) animated:YES];
     }];
  }

You can now build and run your application, select the new menu item, and click on the radial controller to see the switch toggle.

Adding a Handler for Rotation Input

In this section, you will add a handler for rotation input that will move the application slider control if the radial controller is rotated when the new tool you added to the menu is selected. Taking a look at the WindowsUIInput.h header, you’ll see that you need the addRotationChangedEvent: method:

  @interface WUIRadialController : RTObject
   [...]
   - (EventRegistrationToken)addRotationChangedEvent:(void(^)(WUIRadialController*, WUIRadialControllerRotationChangedEventArgs

As for the click event handler, simply call the method and update the slider value in the callback block:

  - (void)viewDidLoad {
    [...]

    __weak ViewController* weakSelf = self; // Ensures self will not be retained

    [...]

    // Add a handler for rotation input from the radial controller
    [self.radialController addRotationChangedEvent:^(WUIRadialController* controller, WUIRadialControllerRotationChangedEventArgs* args)
     {
         [weakSelf.slider setValue:(weakSelf.slider.value + ([args rotationDeltaInDegrees]/360.0f)) animated:YES];
     }];
  }

That’s it! Now build and run your application, select the new menu item and rotate the radial controller to see the slider value change.

Wrapping Up

Thanks for following along! You can download the complete Radial Control sample for the final project. Take a look at the following resources for more information:

Also, be sure to check out the other posts in our series:

4670K/4690K/4770K/4790K

As per title I’m looking for a the following.

i5 or i7 LGA 1150 Unlocked/K CPU.
i5 4670K/4690K or i7 4770K/4790K.

Location:
London, NW9

______________________________________________________
This message is automatically inserted in all classifieds forum threads.
By replying to this thread you agree to abide by the trading rules detailed here.
Please be advised, all buyers and sellers should satisfy…

4670K/4690K/4770K/4790K

Monitor 12v 5A power supplyMonitor 12v 5A power supply

Does anyone one cheaply for sale, just need it for a hour to test something please.

Location: dorset

______________________________________________________
This message is automatically inserted in all classifieds forum threads.
By replying to this thread you agree to abide by the trading rules detailed here.
Please be advised, all buyers and sellers should satisfy themselves that the other party is…

Monitor 12v 5A power supplyMonitor 12v 5A power supply

SOLD Asus P8Z68-V Gen3 / i5 2500K / STD Cooler Bundle

Having a change around, so selling…….

Asus P8Z68-V Gen3 motherboard with box and i/o shield and 4 new sealed SATA cables, fitted with an Intel Core i5 2500k. Includes Windows 10 pro 64bit activation key embedded in BIOS chip. Also includes Standard Intel cpu cooler.
Works great, but can be fussy about which memory you use. £120 inc del SOLD to kinnsy £110 inc del.

For Pic’s See Post 47 Page 2

SOLD

EVGA GTX 780 SC 3Gb graphics card, works…

SOLD Asus P8Z68-V Gen3 / i5 2500K / STD Cooler Bundle

Big Backup Drives and RAID Enclosure

I’m after a RAID enclosure and some large drives suited for backups.
After either individual 4TB and 6TB Drives or complete 8 or 12TB enclosures with two drives, like the WD MyBook Duo.

May consider a full on NAS if it’s powerful enough for 1080p Plex Streaming and cheap enough.

Anything 4TB and over, hit me up!

Location: Rochester, Kent

______________________________________________________
This message is automatically inserted in all classifieds forum…

Big Backup Drives and RAID Enclosure

Mac Mini + LED Cinema Display etc

I have for sale my Late 2012 Mac Mini 2.5 i5 with 16gb ram and 256gb SSD currently running macOS Sierra with no problems and super quick, this is the last of the upgradeable Mac minis, the package also come with a 2 battery wireless Apple Keyboard, Apple Magic Mouse and 24″ LED Apple Cinema Display which has no dead pixels that I can see and works perfectly.
All the above are in perfect condition that I can see. Happy to demo to anyone first, but bear in mind I will format and re install…

Mac Mini + LED Cinema Display etc

AdDuplex – your one stop shop for Windows app and game marketing and monetization

From the early days of the Windows Phone 7 Marketplace to the modern days of Windows Store, AdDuplex was and is committed to providing top-notch advertising solutions for app and game developers, publishers and advertisers.

Premier cross-promotion network

Back in 2011, AdDuplex launched the first cross-promotion network for Windows Phone 7 apps and empowered thousands of independent developers to advertise their apps for free by helping fellow app and game creators. Apps that got initial attention in the early days of the ecosystem received an overall boost and enjoyed the early exposure for years to come. AdDuplex helped such apps by utilizing their ad space before they had reached a level of popularity that made monetization efforts worthwhile.

AdDuplex cross-promotion network works as an enabler of advertising exchange between participating apps and games. Developers place a line of code into their apps and start promoting other apps on the network. Those other apps return the favor. The exchange ratio is 10:8, meaning that for every 10 ad impressions your app shows, you are advertised eight times in other apps. The remaining two impressions are used by AdDuplex to help commercial advertisers reach their potential users and support future development of the platform.

Since 2011, more than 10,000 apps joined AdDuplex and use it to accelerate and amend their growth efforts.

User acquisition on Windows

Free cross-promotion is great, but it limits the velocity of your growth to a pretty linear scale. What if you want to grow faster and have a budget for that? AdDuplex provides an opportunity for app and game publishers to reach more users faster via paid advertising campaigns.

Publishers from all over the world use AdDuplex to both jumpstart their new apps and games, and acquire new users for their other apps and games.

Windows 10 era

The day after the initial public Windows 10 launch, AdDuplex was ready with an SDK for UWP apps. It lets developers use the same SDK and even the same ad units across desktop and mobile, and is now ready for your apps on Xbox One.

App developers and advertisers can target various versions of Windows Phone and Windows across all main device families and reach exactly the users they are looking for through either banner or full-screen ads.

Make money with your Windows apps and AdDuplex

The most recent development was a launch of ad monetization part of AdDuplex. While still in invite-only mode, every app and game developer is welcome to apply for and participate in a revenue-sharing scheme in which developers get 70 percent of the money that advertisers pay AdDuplex. And even when there are no paid campaigns to show, your ad space is not wasted – AdDuplex cross-promotion network kicks in and generates free advertising for your app or game.

Getting started with AdDuplex

Whether you are an independent app developer or an advertiser in search of scale, benefitting from AdDuplex services is really easy. Here are the basics you’ll need to get started (plus some nice extras):