Archivi tag: xcode

How do I specify that a non-generic Swift type should comply to a protocol?

From this Stackoverflow Question

Given this example method in Objective C:

- (void)addFilter:(GPUImageOutput <GPUImageInput>*)newFilter;

How to rewrite it in Swift, saying that the input parameter is of Class GPUImageOutput (or subclass), and, at the same time, conforms to the protocol GPUImageInput ?

In Swift, the solution comes from Generics:

Given these example declarations of protocol, main class and subclass:

protocol ExampleProtocol {
    func printTest() // classes that implements this protocol must have this method
 }
// an empty test class
class ATestClass
{
}
// a child class that implements the protocol
 class ATestClassChild : ATestClass, ExampleProtocol
 {
     func printTest()
     {
         println("hello")
     }
 }

Now, you want to define a method that takes an input parameters of type ATestClass (or a child) that conforms to the protocol ExampleProtocol. Write the method declaration like this:

func addFilter<T where T: ATestClass, T: ExampleProtocol>(newFilter: T)
{
    println(newFilter)
}

The original method, redefined in Swift, should be

func addFilter<T where T:GPUImageOutput, T:GPUImageInput>(newFilter:T!)
{
    // ...
}

A quick tour into Swift Pointers

From: Stackoverflow Question

Swift “hides” pointers, but they still exists under the hood. (because the runtime needs it, and for compatibility reasons with Objc and C)

There are few things to know however, but first how to print the memory address of a Swift String?

var aString : String = "THIS IS A STRING"
 NSLog("%p", aString.core._baseAddress) // _baseAddress is a COpaquePointer
 // example printed address 0x100006db0

This prints the memory address of the string, if you open XCode -> Debug Workflow -> View Memory and go to the printed address, you will see the raw data of the string. Since this is a string literal, this is a memory address inside the storage of the binary (not stack or heap).

However, if you do

var aString : String = "THIS IS A STRING" + "This is another String"
 NSLog("%p", aString.core._baseAddress)
// example printed address 0x103f30020

This will be on the stack, because the string is created at runtime

NOTE: .core._baseAddress is not documented, I found it looking in the variable inspector, and it may be hidden in the future

_baseAddress is not available on all types, here another example with a CInt

var testNumber : CInt = 289
 takesInt(&testNumber)

Where takesInt is a C helper function like this

void takesInt(int *intptr)
 {
    printf("%p", intptr);
 }

On the Swift side, this function is takesInt(intptr: CMutablePointer), so it takes a CMutablePointer to a CInt, and you can obtain it with &varname

The function prints 0x7fff5fbfed98, an at this memory address you will find 289 (in hexadecimal notation). You can change its content with *intptr = 123456

Now, some other things to know.

String, in swift, is a primitive type, not an object.
CInt is a Swift type mapped to the C int Type.
If you want the memory address of an object, you have to do something different.
Swift has some Pointer Types that can be used when interacting with C, and you can read about them here: Swift Pointer Types
Moreover, you can understand more about them exploring their declaration (cmd+click on the type), to understand how to convert a type of pointer into another

var aString : NSString = "This is a string" // create an NSString
 var anUnmanaged = Unmanaged.passUnretained(aString) // take an unmanaged pointer
 var opaque : COpaquePointer = anUnmanaged.toOpaque() // convert it to a COpaquePointer
 var mut : CMutablePointer = &opaque // this is a CMutablePointer
printptr(mut) // pass the pointer to an helper function written in C

printptr is a C helper function I created, with this implementation

void printptr(void ** ptr)
 {
    printf("%p", *ptr);
 }

Again, an example of the address printed: 0x6000000530b0 , and if you go through memory inspector you will find your NSString

One thing you can do with pointers in Swift (this can even be done with inout parameters)

func playWithPointer (stringa :AutoreleasingUnsafePointer)
 {
    stringa.memory = "String Updated";
 }
var testString : NSString = "test string"
println(testString)
playWithPointer(&testString)
println(testString)

Or, interacting with Objc / c

// objc side
 + (void)writeString:(void **)var
 {
    NSMutableString *aString = [[NSMutableString alloc] initWithFormat:@"pippo %@", @"pluto"];
    *var = (void *)CFBridgingRetain(aString); // Retain!
 }
// swift side
 var opaque = COpaquePointer.null() // create a new opaque pointer pointing to null
 TestClass.writeString(&opaque)
 var string = Unmanaged.fromOpaque(opaque).takeRetainedValue()
 println(string)
 // this prints pippo pluto

Subclass UIApplication in Swift

From Stackoverflow

Question:
In Objective C it was simple: it was sufficient to update the main.m file and change the UIApplicationMain() parameters

return UIApplicationMain(argc, argv, NSStringFromClass([CustomUIApplication class]), NSStringFromClass([AppDelegate class]));

But in swift there is no main.m file, since the guide says

“Code written at global scope is used as the entry point for the program, so you don’t need a main function.”

So, how to subclass UIApplication in swift?? Any suggestion?

Answer:

Ok, I’ve found the solution First, I’ve noticed that, at the top of the AppDelegate.swift file, there is this line

@UIApplicationMain

Since this line is outside any scope (it’s at file level), it’s executed immediately, and I assume that the compiler translate it in a standard main function.

So, I did this, starting from a new Swift-Only application:

– commented out @UIApplicationMain
– added a main.swift file like this (FLApplication is my subclass).

IMPORTANT the file MUST BE NAMED main.swift, since top level statements are not supported on other files! You can’t add the UIApplicationMain() call inside any other file, otherwise you’ll receive this error:
“Expressions are not allowed at the top level”

This is the main.swift file .

import Foundation
import UIKit

UIApplicationMain(C_ARGC, C_ARGV, NSStringFromClass(FLApplication), NSStringFromClass(AppDelegate))

create a swift file for the UIApplication subclass, FLApplication.swift, with this code:

import UIKit
import Foundation

class FLApplication: UIApplication
{
    override func sendEvent(event: UIEvent!)
    {
        println("send event") // this is an example
        // ... dispatch the message...
    }
}

now, UIApplication is correctly subclassed and you’ll see the “send event” messages in the log

Q&A – Call a method from a String in Swift (performSelector alternative)

From Stackoverflow

Question:

Calling a method from its name (in a String format) can be sometimes useful.
In Swift it is recomended to change behavior and to use closures to do something “dynamically”, so for example you can have a dictionary of functions, with the name as the key, and the implementation as the value.
However, sometimes you want to simply know “how to do it”, and this is the reason of this question.
So, how to call dynamically a Swift method starting from it’s name as string?

In Objective C it was simple:

[self performSelector:NSSelectorFromString(@”aSelector”)];

But performSelector is banned in Swift
Is there any alternative?

Answer:

In Swift, you should use closures and change your approach. However, if you want to use performSelector to dynamically call a method given only it’s String signature, altough it’s not supported natively, I’ve found how to do it.

It is possible to create a C alternative to performSelector that:

works even on native swift classes (non objective-c)
takes a selector from string
However it’s not so straightforward to implement a complete version of it, and it’s necessary to create the method in C.

in C we have dlsym(), a function that returns a pointer to a function given the char symbol. Well, reading this interesting post: http://www.eswick.com/2014/06/inside-swift/ I’ve learned a lot of interesting things about swift.

Swift instance methods are plain functions with a specific signature, like this

_TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString

where the “self” value is passed as the last parameter

in short you can call it directly from the c side without any kind of bridging, it is sufficient to rebuild the correct function signature. In the signature above, there is the name of the project (FirstSwiftTest) and the lenght (14), the name of the class (ASampleClass) and the lenght (12), the name of the function (aTestFunction) and the lenght (13), then other values as the return type ecc ecc. For other details look at the previous link

The function above, is the representation of this:

class ASampleClass
 {
    func aTestFunction() -> NSString
    {
        println("called correctly")
        return NSString(string: "test")
    }
 }

Well, on the c side, I was able to create this function

#include <stdio.h>
#include <dlfcn.h>

typedef struct objc_object *id;

id _performMethod(id stringMethod, id onObject)
{
    // ...
    // here the code (to be created) to translate stringMethod in _TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString
    // ...

    id (*functionImplementation)(id);
    *(void **) (&functionImplementation) = dlsym(RTLD_DEFAULT, "_TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString");

    char *error;

    if ((error = dlerror()) != NULL)  {
        printf("Method not found \n");
    } else {
        return functionImplementation(onObject); // <--- call the function
    }
    return NULL
}

And then called it on the swift side

let sampleClassInstance = ASampleClass()
println(_performMethod("aTestFunction", sampleClassInstance))

The function resulted in these statement printed on the log:

called correctly
test

So it should be not so difficult to create a _performMethod() alternative in C that:

– creates automatically the function signature (since it seems to have a logic 🙂
– manages different return value types and parameters