ios

Trying iOS 11 with Xamarin

The triathlon season is over. I completed all three, planned races for this year:

  1. Ironman 70.3 Coeur d’Alene
  2. SeaFair Sprint Triathlon (new PR!)
  3. Lake Meridian Olympic Triathlon (new PR!)

I also finished RAMROD (epic Ride Around Mt Rainier in One Day) and Course d’Equipe. The last bike ride for this season is Gran Fondo Whistler in two weeks.

In the meantime…

The Winter is coming!

Apple is cooking for us iOS 11, and I decided to give it a shot! It actually works nice.

  1. Install latest Xcode beta from here
  2. Install latest Xamarin.iOS (all links are here, hint: version is 10.99, not 11 yet)
  3. Set VS for Mac to Xcode-beta (Preferences -> Projects -> SDK Locations -> Apple -> Location)

If you did everything correct you should be able to see new iOS11 simulator:

iOS 11 simulator

I encountered one issue: when deploying to device I got following errors:

Error: unable to find utility “lipo”, not a developer tool or in PATH
Error: Failed to create the a fat library

Solution was to run the following command:

sudo xcode-select --switch /Applications/Xcode-beta.app/Contents/Developer/

Related Xamarin Forums thread.

Summary

So far everything works pretty well. Occasionally when I run VS for Mac it doesn’t detect simulators, but after restart they are back!

Have you tried iOS 11 yet?


iOS for C# Developer – part 4: Xcode

This post is part of the series: iOS for C# Developer. Previous parts:

C# developers works with Visual Studio. Recently, some are trying to switch to SublimeText. However, I will assume that you, as C# Developer are familiar with VS. To write iOS applications, you need Xcode. I haven’t heard about nobody who created an working app in a different editor (more advanced than Hello World).

In this post I would like to provide a few tips that will help you to get started and be productive.

The first thing that is worth to mention is the fact that Xcode is free. You cannot test you apps on the iPhone or iPad before you pay $99 though. You need to be satisfied with simulator.

Key shortcuts

For the beginning, remember three:

  • ⇧ + ⌘ + O – quick open (equivalent to CTRL+, in VS2013 or CTRL+T in ReSharper)
  • ⌥ + click – jump to documentation (when clicked on class/interface)
  • ⌘ + L – jump to specified line of code

This three will definitely help you to get productive at the beginning. You can find more in this cheat-sheet.

Debugging

In order to debug application in VS, you have to run it in debug mode. In Xcode, when you run the app on emulator it is always in debug mode. Thus, you just need to set the break-point (by mouse click on the line number, like in VS, or by ⌘ + \ shortcut) and run the app (⌘ + R). Once break-point is reached you can step over (F6), step into (F7) or step out (F8).

Very useful during debugging is dumping objects into console with NSLog function:

NSLog(jsonString);

This outputs, e.g., JSON string to the console, which allows you to inspect it.

To get more flavor of debugging, check Apple documentation and Brian Moakley’s blog post.

Playgrounds

The latest version of Xcode (v6), which introduce support for Swift language, adds also very handy feature: Playgrounds. It allows you write and test simple Swift programs, without using iOS emulator. Playgrounds are useful especially, when you are testing some complex logic. They are very powerful. You can use them even to test drawing (still without running iOS emulator). To see it in action, check this demo.

Summary

Xcode is very nice IDE. Works very smooth, and breaks very rarely. I wish there was more code snippets (like it is in Visual Studio, especially with ReSharper or WebEssentials). Xcode could also adapt rich debugging experience from VS (e.g., inspecting object variable after moving mouse pointer in top of them). I find it hard to work with this IDE on small screen (like MacBook display). To get comfortable, I need at least 22-24″. But that is just my opinion. What do you think?


iOS for C# Developer – part 3: multithreading

This post is part of the series: iOS for C# Developer. Previous parts:

The most typical scenario to use multithreading is to maintain responsive UI when we do some resource-consuming computation.

C#

Let’s consider simple button click action in C#:

private void Button_Click(object sender, RoutedEventArgs e)
{
    this.status.Content = "Computing...";
    Compute();
    this.status.Content = "Done";
}

private void Compute()
{
    Thread.Sleep(5000);            
}

Method Compute() is a CPU-intensive operation (simulated by Sleep() function).

Above code will block UI during computation. To keep UI responsive, computation has to take place in a separate thread. It can be done easily using async/await keywords:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    this.status.Content = "Computing...";
    await Compute();
    this.status.Content = "Done";
}

private async Task Compute()
{
    await Task.Factory.StartNew(() =>
    {
        Thread.Sleep(5000);
    });
}

iOS

This is equivalent (single-threaded) button click handler in iOS:

- (IBAction)buttonClick:(id)sender
{
    self.status.text = @"Computing...";
    [self compute];
    self.status.text = @"Done";
}

- (void)compute
{
    [NSThread sleepForTimeInterval:5];
}

Multithreaded version is a little bit different. In Objective-C, there is no syntax similar to async/await. Thus, status update has to be invoked by background thread explicitly. Additionally, every UI operation (in this case: label text update) has to be done in the main thread. Below code, use Dispatch Queues, which is the easiest and recommended way for multithreading scenarios:

- (IBAction)buttonClick:(id)sender
{
    self.status.text = @"Computing...";
    [self compute];
}

- (void)compute
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:5];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.status.text = @"Done";
        });
    });
}

This multithreaded code will look pretty similar in Swift.

Summary

Invoking background threads is much easier from developer perspective in C#. Code is concise and more readable. Multithreading in Objective-C introduce some overhead, but it is not very hard to handle.


iOS for C# Developer – part 2: strings

This post is part of the series: iOS for C# Developer. First part can be found here.

String operations in Objective-C are very verbose in comparison to C#.

Let’s assume the following string definition for all below examples:

NSString *str = @"Some string. Another string.";

Concatenation

I think this is the most common operation. In C# it is very simple:

string result += " Appended string.";

* For concatenation in C#, consider using StringBuilder class (if performance matters).

In Objective-C, NSMutableString type has to be used. Thus, if we have NSString created, we have to do the following:

NSMutableString *temp = [[NSMutableString alloc] initWithString:str];
[temp stringByAppendingString:@" Appended string."];
str = temp;

A bit of work, huh?

Substring

To get substring from letter 3 to 7 in C#:

string result = str.Substring(3,5);

In Objective-C:

NSString *result = [str substringWithRange:NSMakeRange(3,5)];

Pretty straightforward.

Split

To split sentences in our sample string in C#, we would do:

string[] result = str.Split(". ");

In Objective-C:

NSArray *result = [str componentsSeparatedByString:@". "];

Also, pretty similar.

Replace

This operation is much more verbose than its equivalent in C#. To replace spaces with underscores, in C# we do:

string result = str.Replace(" ", "_");

In Objective-C:

NSString *result = [str stringByReplacingOccurrencesOfString:@" " withString:@"_"];

Looks pretty the same, but long, custom names preceding actual parameters make code unnecessary long (IMO).

Real-world example

Usually we need a few string operations working together. Let’s apply above operations together. For example: we want to get only the second sentence from our string with underscores instead of spaces.

In C#:

string result = str.Split(new [] {". "}, StringSplitOptions.RemoveEmptyEntries)[1].Replace(' ','_');

In Objective-C:

NSString *result = [[str componentsSeparatedByString:@". "][1] stringByReplacingOccurrencesOfString:@" " withString:@"_"];

Summary

Some of above operations are easier in Swift (e.g., concatenation looks the same like in C#), but some are still very verbose (e.g., substring, replace). However, the syntax is more similar to C#. The message passing syntax is something you need to get use to in Objective-C, not only in case of string operations.


iOS for C# Developer – part 1: Classes and creating objects

In this series I would like to present an overview of differences and similarities in developing iOS and C# apps.

First part is about Object-Oriented features. If you are C# developer and you are starting with Objective-C, Object-Oriented terminology might be confusing.

Interface

In Objective-C, interface is a class declaration (not existing in C#). It is like header file in C++. It has even the same extension: .h. This is sample interface:

@interface Example

+ (void)someStaticMethod;

- (NSInteger)someInstanceMethod:(BOOL)param1 calledWith:(NSInteger)num;

@end

Static (class) methods are distinguished by + sign. Instance method starts with - sign. Return types are in brackets. Parameters (brackets and name) are preceded by custom name. In class implementation only parameter name matters.

Implementation

In addition to interface (equivalent of class declaration), Objective-C classes have also implementation files with .m extension (equivalent of .cpp files in C++). Example implementation for previous interface (class declaration) can look like that:

@implementation Example

+ (void)someStaticMethod
{
  // implementation
}

- (NSInteger)someInstanceMethod:(BOOL)param1 calledWith:(NSInteger)num
{
  if(param1) {
    return num*2;
  } else {
    return num;
  }
}

@end

Protocols

Protocol is equivalent of interface in C#. This is sample protocol definition:

@protocol SampleProtocol
- (void)protocolMethod1;
- (void)protocolMethod2;
@end

To take advantage of this protocol in some class, it has to be stated in the interface, in which this protocol is being used:

@interface Example : NSObject 
+ (void)someStaticMethod;
- (NSInteger)someInstanceMethod:(BOOL)param1 calledWith:(NSInteger)num;
@end

Then, its methods have to be implemented in the implementation file:

@implementation Example 

+ (void)someStaticMethod 
{ 
  // implementation 
} 

- (NSInteger)someInstanceMethod:(BOOL)param1 calledWith:(NSInteger)num 
{ 
  if(param1) { 
    return num*2; 
  } else { 
    return num; 
  } 
} 

- (void)protocolMethod1 
{ 
  // implementation 
} 

- (void)protocolMethod2 
{ 
  // implementation 
} 

@end

There are two types of methods in protocol:

  • required (default)
  • optional

In previous protocol, both methods are required, because it is a default mode. This means, both has to be implemented in the class that use the protocol. In order to make second method optional, keyword @optional has to be used:

@protocol SampleProtocol

- (void)protocolMethod1;

@optional
- (void)protocolMethod2;

@end

All methods declared after @optional keyword are optional. In order to declare required method after that, @required keyword has to be used:

@protocol SampleProtocol

- (void)protocolMethod1;  // required method

@optional
- (void)protocolMethod2;  // optional method
- (void)protocolMethod3;  // optional method

@required
- (void)protocolMethod4;  // required method

@end

Instantiating objects

Creating instance of object has two steps: allocation and initialization. To create instance of Example class defined above, message passing syntax is used:

Example *obj = [[Example alloc] init];

Shortcut for above object creation:

Example *obj = [Example new];

When the class has a constructor with parameters, e.g.:

@interface Example : NSObject {
  NSInteger *sampleProperty;
}
- (id) initWithParam:param;
@end

@implementation Example

- (id) initWithParam:(NSInteger)param
{
  self = [super init];
  if (self) {
    self.sampleProperty = param;
  }
  return self;
}

@end

Initialization looks as follows:

Example *obj = [Example initWithParam:25];

Summary

  • Interface – class declaration
  • Implementation – class body (implementation of declared methods in class interface)
  • Protocol – the same construct as interface in C#
  • Object creation: Example *obj = [[Example alloc] init];