I’m very happy to be on open source movement, and it ‘ll be great to hear about what people have achieved

And also mentioned in Writing Xcode plugin in Swift

Attribution

Writing this was much simpler because I was able to look at other people plugins, mostly those related to console, without them being open sourcing it would be more work to figure this stuff out with hopper.

Open source helps us move forward, learn and share together

The dark side of the Force

Luke: Is the dark side stronger?

Yoda: No, no, no. Quicker, easier, more seductive.

It’s a pain to see plagiarism around

Open source softwares are in fact intellectual properties, and the authors should get acknowledgement for the work that they do.

It’s not fair to take the credit of other’s work and not giving any attribution

By its nature, open source software has a unique relationship with intellectual property rights

One thing that’s not up for debate in most circles is that it’s dishonest and disingenuous to take someone else’s project, modify it slightly, and call it your own.

Further, regardless of whether or not a project crosses that line, it must (by the terms of most open source licenses) acknowledge the original work/author.

And the reaction

  • Attribute Original Author
  • DMCA takedown on repos that rip off Async

It’s always sad to see blatant plagiarism, and I think it really hurts the community more than the author itself. It gives people a good reason to keep the sources private.

Being nice

I often hear people say that

It is easier to find good developer than developer with good attitude

Github also states that

We understand and agree that copying others’ work without permission goes against the spirit of the open source community

Do the right things

Is it MIT ‘s fault? Definitely no

False choice. Giving up freedom does not lead to more security, just less freedom.

Takeaways

  • Don’t take things personally
  • It’s hard to be perfect, but we can learn to do the right things
  • We may do the wrong things, but don’t worry, there ‘ll be help via Issues and Pull Requests

Comments

The idea of Signal may originate from Elm Reactivity, and it has now been widely adopted in iOS

I once asked What are examples of hot and cold signal in ReactiveCocoa?

Whether it is hot vs cold, Signal vs Signal Producer, Observable vs Enumerable, … it’s good to understand how it gets implemented, so that to have a good sense of how they work

Monad

  • Understanding Monad

Basically, Signal and its Result are just monads, which are thing that can be mapped and chained.

Signal makes use of deferred execution callback blocks, and push vs pull is just how the Signal updates its value and the order the callbacks are called

Execution callback block is that we pass a function to another function, and it will get called when appropriated

Sync vs Async

Monad can be in either sync or async mode. Sync is easier to understand, but async is somewhat you’re already familiar and used in practice

Basically,

  • Sync: you get the returned value right away via return
  • Aync: you get the returned value via callback block

Here is an example of a simple function

1
2
3
4
5
6
7
8
9
10
11
12
// Sync
func sum(a: Int, b: Int) -> Int {
return a + b
}

// Async
func sum(a: Int, b: Int, completion: Int -> Void) {
// Assumed it is a very long task to get the result
let result = a + b

completion(result)
}

Here is an example of Event

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Sync
public func map(@noescape f: T -> U) -> Event {
switch self {
case let .Next(value):
return .Next(value: f(value))
case let .Failed(error):
return .Failed(error: error)
}
}

// Async
public func map(f: (T, U -> Void) -> Void) -> ((Event -> Void) -> Void) {
return { g in // g: Event -> Void
switch self {
case let .Next(value):
f(value) { transformedValue in // transformedValue: U
g(.Next(value: transformedValue))
}
case let .Failed(error):
g(.Failed(error: error))
}
}
}

Push Signal

  • Signal.swift

Take a look at my Push Signal, called Signal, it is like how Promise A+ Then works

Implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public final class Signal {
var event: Event?
var callbacks: [Event -> Void] = []

func notify() {
guard let event = event else {
return
}

callbacks.forEach { callback in
callback(event)
}
}

func update(event event: Event) {
dispatch_sync(lockQueue) {
self.event = event
}

notify()
}

public func subscribe(f: Event -> Void) -> Signal {
// Callback
if let event = event {
f(event)
}

callbacks.append(f)

return self
}

public func map(f: T -> U) -> Signal {
let signal = Signal()

subscribe { event in
signal.update(event: event.map(f))
}

return signal
}
}

Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
let signal = Signal()

signal.map { value in
return value.characters.count
}.subscribe { event in
if case let .Next(value) = event {
XCTAssert(value == 4)
} else {
XCTAssert(false)
}
}

signal.sendNext("test")

Callbacks

Given a chained signals like this

A -(map)-> B -(flatMap)-> C -(flatMap)-> D -(subscribe)

  • The idea is we send event to the source signal, and it propagates events through via callbacks.
  • Triggered by sending event to the source signal.
  • We must keep A as it keeps the others around
  • We subscribe the last D
  • We send event to the first A
  • A ‘s callback gets called, it it in turn calls callback of B with the result of A ‘s map, then B ‘s callback calls C ‘s callback with the result of B
    ‘s flatMap, …

Pull Signal

  • Future.swift

Take a look at my Pull Signal, called Future

Implementation

Here operation is a task, when called and completed, will notify its completion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public struct Future {
let operation: (Event -> Void) -> Void

public init(operation: (Event -> Void) -> Void) {
self.operation = operation
}

public func start(completion: Event -> Void) {
operation() { event in
completion(event)
}
}

public func map(f: T -> U) -> Future {
return Future { completion in
self.start { event in
completion(event.map(f))
}
}
}
}

Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
let _ = Future { completion in
// There is some work here
completion(Event(value: "test"))
}
.map { value in
value.characters.count
}.start { event in
if case let .Next(value) = event {
XCTAssert(value == 4)
} else {
XCTAssert(false)
}
}

Callbacks

Given a chained signals like this

A -(map)-> B -(flatMap)-> C -(flatMap)-> D -(subscribe)

  • The idea is we subscribe to the final signal D, and it cause the previous signals to action.
  • Triggered by subscribing to the final signal.
  • We must keep D as it keeps the others around
  • We subscribe the last D
  • D ‘s operation actions, and it cause C ‘s operation to action, … then A ‘s operation actions. It is in A that the task is performed (like fetching network, retrieving database, file access, heavy computation, …) to get the result, and A ‘s completion gets called. Then A’s completion calls B ‘s completion with the result mapped by B ‘s map, … all the way to the subscriber ‘s completion block

Comments

Haskell is notorious for currying, and Swift has currying, too

I love ReactiveCocoa, RxSwift and I always take time to dig into it. The other day, I was practise making Signal based on this talk

Take a look at my repo Signal

filter

I was making a filter for a Signal. The idea of filter is that we should update signal if the Event is Next with right filtered value

Signal.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
public func filter(f: T -> Bool) -> Signal{
let signal = Signal()
subscribe { result in
switch(result) {
case let .Success(value):
if f(value) {
signal.update(result)
}
case let .Error(error): signal.update(.Error(error))
}
}
return signal
}

2 params

But having Event as another monad, I think it should be more encapsulated if that switching logic gets moved into the Event. Here the filter takes 2 params

Event.swift

1
2
3
4
5
6
7
8
9
10
func filter(f: T -> Bool, callback: (Event -> Void)) {
switch self {
case let .Next(value) where f(value):
callback(self)
case .Failed:
callback(self)
default:
break
}
}

Signal.swift

1
2
3
4
5
6
7
8
9
public func filter(f: T -> Bool) -> Signal {
let signal = Signal()

subscribe { event in
event.filter(f, callback: signal.update)
}

return signal
}

Currying

With currying, we can make filter a more abstract function, and defer the decision to pass the callback param. It is a little carried away but I find it helpful this way

Now filter accepts 1 param, and it returns a function that takes callback as its param

Event.swift

1
2
3
4
5
6
7
8
9
10
11
12
func filter(f: T -> Bool) -> ((Event -> Void) -> Void) {
return { g in
switch self {
case let .Next(value) where f(value):
g(self)
case .Failed:
g(self)
default:
break
}
}
}

Signal.swift

1
2
3
4
5
6
7
8
9
public func filter(f: T -> Bool) -> Signal {
let signal = Signal()

subscribe { event in
event.filter(f)(signal.update)
}

return signal
}

Curry syntax in Swift 2

Swift 2 supports curry syntax function

1
2
3
4
5
6
7

func sum(a: Int)(b: Int) -> Int {
return a + b
}

let sumWith5 = sum(5)
let result = sumWith5(b: 10)

No more curry syntax in Swift 3

You may want to find out

Reference

Comments

NSNotificationCenter is like central hub where notifications are posted and received by any parts of the app

Registering

Registering for notification n times, you get notified n times

debugDescription

As of iOS 9+,

NSNotificationCenter and NSDistributedNotificationCenter will now provide a debug description when printing from the debugger that will list all registered observers including references that have been zeroed out for aiding in debugging notification registrations. This data is only valid per the duration of the breakpoint since the underlying store must account for multithreaded environments. Wildcard registrations for notifications where the name or object that was passed to the addObserver method family was null will be printed in the debug description as *.

1
print(NSNotificationCenter.defaultCenter().debugDescription)

Observer

addObserver(_:selector:name:object:)

Adds an entry to the receiver’s dispatch table with an observer, a notification selector and optional criteria: notification name and sender.

1
2
3
4
5
6
7
8
9
10
override func viewDidLoad() {
super.viewDidLoad()

NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerDidReachEndNotificationHandler:", name: AVPlayerItemDidPlayToEndTimeNotification, object: player.currentItem)
}

func playerDidReachEndNotificationHandler(notification: NSNotification) {
guard let playerItem = notification.object as? AVPlayerItem else { return }
playerItem.seekToTime(kCMTimeZero)
}
  • NSNotificationCenter holds weak reference to its observer
  • Regular notification centers deliver notifications on the thread in which the notification was posted

addObserverForName(_:object:queue:usingBlock:)

Adds an entry to the receiver’s dispatch table with a notification queue and a block to add to the queue, and optional criteria: notification name and sender.

1
2
3
observer = NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: player.currentItem, queue: NSOperationQueue.mainQueue()) { [weak self] notification in
self?.playerDidReachEndNotificationHandler(notification)
}

When to unregister ?

The idea is to unregister as soon as we don’t need to receive notifications. Most of the time, it is our deinit

1
2
3
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}

See Unregistering an Observer

Before an object that is observing notifications is deallocated, it must tell the notification center to stop sending it notifications. Otherwise, the next notification gets sent to a nonexistent object and the program crashes

iOS 9+

See OS X 10.11 and iOS 9 Release Notes
Cocoa Foundation Framework

In OS X 10.11 and iOS 9.0 NSNotificationCenter and NSDistributedNotificationCenter will no longer send notifications to registered observers that may be deallocated

This means that observers are not required to un-register in their deallocation method

However,

Block based observers via the -[NSNotificationCenter addObserverForName:object:queue:usingBlock] method still need to be un-registered when no longer in use since the system still holds a strong reference to these observers

So we must call removeObserver on the returned observer object

1
2
3
deinit {
NSNotificationCenter.defaultCenter().removeObserver(observer)
}

Synchrony

A notification center delivers notifications to observers synchronously. In other words, when posting a notification, control does not return to the poster until all observers have received and processed the notification

If you have performance problem of posting notifications to large number of observers, consider using

  • dispatch_after
  • Many NSNotificationCenter
  • NSNotificationQueue

NSNotificationQueue

  • Enqueuing methods return immediately
  • Associated with the run loop modes
  • There ‘s defaultQueue for the current thread
1
2
3
let queue = NSNotificationQueue(notificationCenter: NSNotificationCenter.defaultCenter())
let notification = NSNotification(name: "CacheDidUpdateNotification", object: self)
queue.enqueueNotification(notification, postingStyle: .PostASAP)

Reference

Comments

Christmas is when we I have the most special feeling. The cool air, the snow, the reunion, the church bell ringing, …


(From google)

It ‘s beginning to look a lot like Christmas. First with Xcode

Xmas

Xmas is an Xcode plugin that shows Xmas picture along with wishing message whenever a build succeeds

How it works

Swift

  • Try to do much of the job in Swift as possible

DVTKit

  • Xcode uses DVTBezelAlertPanel to display alert. So we swizzle its initWithIcon:message:parentWindow:duration:
  • DVTBezelAlertPanel is from DVTKit. I thought about importing run time header and just extension it. But I find swizzling in Objective C a much more easier solution

NSVisualEffectView

  • It seems that NSImage added to the panel ‘s NSVisualEffectView had it template set to YES again, hence causing the image into template color with the panel background color
  • This happens in the init method. So we must change template back to NO after init happens
1
2
3
4
5
6
7
8
9
10
- (id)xmas_initWithIcon:(id)icon
message:(NSString *)message
parentWindow:(id)parentWindow
duration:(double)duration {
[self xmas_initWithIcon:image message:gift.message parentWindow:parentWindow duration:duration];

image.template = NO;

return self;
}

And, Merry Christmas to you and your family

Reference

Comments

The Marvel world

Ant Man

We know Ant Man is Hank Pym

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct AntManSuit {
let name: String
}

struct HankPym {
let suit = AntManSuit(name: "Ant Man ID #101")

func fight() {
print("Fighting with the suit named " + suit.name)
}
}

let hankPym = HankPym()
hankPym.fight()

Everytime HankPym is created, he always uses the Ant Man suit. This time he is so coupled to the role Ant Man

More suits

Well, he does not have to be too dependent on the Ant Man suit. We know Hank Pym is a genius scientist, he has more suits to use. Let’s make it decoupled

Using Dependency Injection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protocol Suit {
var name: String { get }
}

struct AntManSuit: Suit {
let name: String
}

struct YellowJacketSuit: Suit {
let name: String
}

struct HankPym {
let suit: Suit

func fight() {
print("Fighting with the suit named " + suit.name)
}
}

let suit = YellowJacketSuit(name: "Yellow Jacket ID #33")
let hankPym = HankPym(suit: suit)
hankPym.fight()

Now Hank Pym can be more flexible on which suit to use.

Dependency Injection

The technique we just saw is called Dependency Injection, in which Hank Pym does not need to create the Suit, it will be provided through constructor or property.

Dependency Inversion Principle

In the first example, Hank Pym is dependent on the concrete implementation of the Suit

In the second example, both Hank Pym and the suits are dependent on the Suit protocol. This way Hank Pym only knows about the Suit protocol, and future suits must be crafted to that it conforms to the Suit protocol

This way the dependency is inverted

High level modules should not depend upon low level modules. Both should depend upon abstractions.

What is the high level policy? It is the abstractions that underlie the application, the
truths that do not vary when the details are changed

Inversion of Control Container

You may ask yourself Why is Inversion of Control named that way?

Framework vs library

People said “the framework calls you but you call the library”

Command line vs GUI

See What is Inversion of Control?

For example, in an old school menu, you might have:

1
2
3
4
5
6
print "enter your name"
read name
print "enter your address"
read address
etc...
store in database

thereby controlling the flow of user interaction.

In a GUI program or some such, instead we say

1
2
3
when the user types in field a, store it in NAME
when the user types in field b, store it in ADDRESS
when the user clicks the save button, call StoreInDatabase

You how have a brief understanding of how IoC means

IoC container

In the 2nd example of the Suit protocol, you can see how there is a inversion of control. What if there is a container that contains all the Suit conformances?

Let’s use my Resolver

1
2
3
4
5
6
7
let resolver = Resolver()
resolver.register {
YellowJacketSuit(name: "YellowJacket ID #404") as Suit
}

let suit = try! resolver.resolve() as Suit
let hankPym = HankPym(suit: suit)

Quite helpful, right? :]

Features

Actually, IoC container helps you more than that.

  • Circular Dependency Injection
  • Auto Injection
  • Object Scope

There are some IoC containers in Swift

Swinject

1
2
3
4
5
let container = Container()
container.register(AnimalType.self) { _ in Cat(name: "Mimi") }
container.register(PersonType.self) { r in
PetOwner(pet: r.resolve(AnimalType.self)!)
}

Swinject requires explicit type declaration. It has SwinjectStoryboard, which helps configuring the dependency for your view controller

Dip

Dip leverages generic and encourage protocols

1
2
container.register { ServiceImp() as Service }
let service = try! container.resolve() as Service

You ‘ll learn a lot just by reading Dip source code, on how factory and factory type are stored and checked using generic

1
2
3
4
5
6
7
8
9
10
11
public func resolve(tag tag: Tag? = nil, builder: F->T) throws -> T {
let key = DefinitionKey(protocolType: T.self, factoryType: F.self, associatedTag: tag)
let nilTagKey = tag.map { _ in DefinitionKey(protocolType: T.self, factoryType: F.self, associatedTag: nil) }

guard let definition = (self.definitions[key] ?? self.definitions[nilTagKey]) as? DefinitionOf<T, F> else {
throw DipError.DefinitionNotFound(key)
}

let usingKey: DefinitionKey? = definition.scope == .ObjectGraph ? key : nil
return _resolve(tag, key: usingKey, definition: definition, builder: builder)
}

Build your own simple IoC container

You may have discovered, that the idea of all those framework is to use closure as factory method

1
2
3
4
5
let factory = {
YellowJacketSuit(name: "YellowJacket ID #007") as Suit
}

let suit = factory()

All we have to do is to store these factories closure

Take a look at my gist SimpleResolver.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class SimpleResolver {
var factories = [String: Any]()

func factory(factory: () -> T) {
let key = String(T.self)
factories[key] = factory
}

func resolve() -> T {
let key = String(T.self)
if let factory = factories[key] as? () -> T {
return factory()
} else {
fatalError("Registration not found")
}
}
}

let resolver = SimpleResolver()

resolver.factory {
YellowJacketSuit(name: "YellowJacket IS #009") as Suit
}

let suit = resolver.resolve() as Suit
print(suit.name)

Reference

Comments

Here are some of my notes when diving into Swift

Default parameter reorder

If a function arguments have default values, you can reorder them at call site.

1
2
3
4
5
func sum(num1 num1: Int = 1, num2: Int = 2) -> Int {
return num1 + num2
}

let s = sum(num2: 10, num1: 20) // 30

Note that the first parameter num1 must have external name

Tuple shuffle

See Tuple shuffle in Swift

1
2
3
4
var a = "one", b = "two"
(a, b) = (b, a)
print(a) // "two"
print(b) // "one"

Be careful with generic

Here is when I’m trying to do a Resolver

1
2
3
4
5
6
7
8
9
func registerSingleton(singleton: T) {
register {
singleton
}
}

func register(factory: () -> T) {
print(factory.dynamicType)
}

Here I mistakenly use it, because generic can accept any type, even closure

1
2
3
registerSingleton {
"onmyway133"
}

And now factory.dynamicType is of type () -> () -> String, not what I expect () -> String

Short notation works for any static member

1
2
3
4
5
6
7
extension CAMediaTimingFunction {
static var EaseInEaseOut: CAMediaTimingFunction {
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
}
}

let function: CAMediaTimingFunction = .EaseInEaseOut

We can also .init because the type of the property is already specified

1
2
3
4
5
extension CAMediaTimingFunction {
static var EaseInEaseOut: CAMediaTimingFunction {
return .init(name: kCAMediaTimingFunctionEaseInEaseOut)
}
}

Resolving generic type

Supposed we have contrived method like this, which does not accept any parameter

1
2
3
4
5
6
7
func resolve() -> T {
if String(T) == "String" {
return "onmyway133" as! T
} else {
fatalError()
}
}

We can use as to resolve the type, or specify the type

1
2
let a = resolve() as String // "onmyway133"
let b: String = resolve() // "onmyway133"

You can learn more when reading Dip

Reference instance method

Supposed we have

1
2
3
4
5
6
7
8
9
class Cat {
init() {

}

func meo() {
print("meo meo")
}
}

We can make a reference to that instance method

1
2
3
let cat = Cat()
let ref = Cat.meo
ref(cat)()

We can see that ref is of type Cat -> () -> ()

precondition

Check for a condition, works even in release mode.

1
2
3
4
func hello(name: String) {
precondition(!name.isEmpty, "Name must not be empty")
print("hello " + name)
}

strideof

In C, the sizeof operator returns the size of any variable or data type. In Swift, you use the sizeof function to get the size of a given type, or the sizeofValue function to get the size of the type of a given value

1
print(strideof(timeval)) // "16"

Arguments are tuple

  • Tuple as Function arguments

  • Tuple elements must be the same number, of the same types, and have the same external parameter name as in function

1
2
3
4
5
6
7
func greet(name: String, age: Int) {
print("Hello, this is " + name + ", \(age) years old")
}

let params = ("Luke", age: 17)

greet(params)

Comments

Swift is open source, here at swift and Swift.org. And for now it uses Apache license

There is a joke on this pull request I think we should use GPL v3 instead, it’s the future of open source.

When developing iOS apps, most of the libraries I use are on MIT licenses, a permissive license, which is good :]

MIT vs GPL vs Apache

These have many things in common

  • Commercial Use: This software and derivatives may be used for commercial purposes.
  • Distribution: You may distribute this software.
  • Modification: This software may be modified.
  • Private use: You may use and modify the software without distributing it.
  • License and copyright notice: Include a copy of the license and copyright notice with the code.

But

GPL is Disclose Source: copyleft license that requires anyone who distributes your code or a derivative work to make the source available under the same terms.

Apache is Patent Grant and State Changes: Indicate significant changes made to the code

MIT is simple, permissive. You can do anything you like

Reference

Comments