Swift in five minutes

In this post, I’ll show the fundamentals of the Swift language. It’s the first of a series where I’ll show how to build a chat app using Swift and SwiftUI.

Let’s start with the simpler things, comments, variables and constants:

// It's a line comment

/*
   This is a multiline
   comment
*/

// Variable definition:
// var varname: Type = Initial value

var name: String = "Nicola"

The variables are defined using the “var” keyword, a name, after the “:” we must write the type of the variable (String, Double, Float, Array, Set,..)

The variable can be also declared shortly, omitting the type and setting directly the value, in this case, the variable gets the type of the value.

// declaring an int variable omitting the type
var age: 10 // age is an integer

The constants are declared in the same way, apart from using the “let” keyword and that they can get only a value that can be changed.

let pi = 3.14

pi = 4 // Error can't change costant value

In Swift we can declare a variable as optional, the variable can assume every value of the type defined and the “null” value. In this way, the nulla value became a possible value for that variable. An optional variable is defined appending the “?” to the type:

var myOpt: Int?
myOpt = 3

// to get the myOpt value
if let value = myOpt { 
    print("Value \(value)")
} else {
    print("null")
}

// it's equivalent to
if myOpt != nul {
  var value = myOpt!
  print("Value \(value)")
} else {
  print("null")
}

Note the “!” after myOpt, using the “!” we force to get the value of myOpt. Use it only when you are sure that the variable is not null, otherwise you can have some crash due to null pointer exception.

About the conditional statement, you find the classic:

if condtion {
} else if condition {
} else {
}

// Locic operator
// && for a and b
// || for a or b
// == for a equal b
// != for b not equal b

In swift the “condition” not need to have enclosed in () how in other languages (i.e. C).

See other types: Array, Tuple and Set.

// Array declaration
// var name: Array<Type>

// Example
var numbers: Array<Int> // at this moment the numbers is nill

// To be able to make operation on the array we must initialize

numbers = Array<Int>() // now we have an empty array

numbers.append(3) // add the number 3
numbers.append(1) // add the number 1

To iterate the elements of the array (or other collections) we need the control flow, in this case, the for loop.

for i in 0..<numbers.count { // from zero to 1
    print("numbers[\(i)] = \(numbers[i])")
}

In the previous code we iterate the numbers vector operating on a sequence in the range 0..<numbers.count . In this case 0..<2, mean that i can assume the value 0,1.

A range can be defined in this way:

var firstTenA = 0...10 // all the number from 0 to 10
var firstTenB = 0..<11 // all the number from 0 to 10
// with the < we exclude the value on the right
// Other version of the for loop see before
for i in 0...(numbers.count - 1) { // from zero to 1
    print("numbers[\(i)] = \(numbers[i])")
}

Note if you want to iterate in reverse order, you must use the reverse method :

for i in (0..<numbers.count).reversed() { 
    print("numbers[\(i)] = \(numbers[i])")
}

It possible also iterate directly on the vector:

for elem in numbers {
    print(elem)
}

About the iteration, look at the String, we can’t iterate the string with int index but using the indices.

var name: String = "Bob"
// write every single character of the string
for i in name.indices {
    print(name[i])
}

Other controls flow: while and repeat while

var counter = 10
while counter > 0 {
    print(counter)
    counter = counter - 1
}

repeat {
    print(counter)
    counter = counter + 1
} while counter < 10


How in other programming languages the code in the while is executed until the condition is true, instead of with the repeat while, the code is executed at least one time.

Another collection type is the dictionary, it’s a list of pair key and value.

var dict: [Int: String] = [Int: String]()
dict[404] = "Not found"

for key in dict.keys {
    print(key)
}

for value in dict.values {
    print(value)
}


In the code, we see the declaration of a dictionary where the key is an Int and the value is a String. It’s possible to access the element using the key in [], instead, it’s possible to iterate the key and the values using the methods keys and values.

The next step is to see how to declare and use the functions.

func nameLastName(name a: String, lastname b: String ) {
    print("Name \(a) Lastname \(b)")
}

The function is declared using the keyword func, the parameters are passed indicating a label, a name of the parameter and the type.

You can see the label as a help for the programmer, it explains what the parameter means, instead the name is used in the body of the function. To invoke that function:

nameLastName(name: "Bob", lastname: "Rossi")

It’s possible to declare also the function without the labels:

func nameLastName(a: String, b: String ) {
    print("Name \(a) Lastname \(b)")
}

// In this case the function is called in this way
nameLastName(a: "Bob", b: "Rossi")

In the end, it’s possible to declare the function to avoid the use of the name in the call.

func nameLastName(_ a: String, b: String ) {
    print("Name \(a) Lastname \(b)")
}

// In this case the function is called in this way
nameLastName("Bob", b: "Rossi")

The function can return also a value:

// Function that returns an Int
func squareRect(width: Int, height: Int) -> Int {
    let sup = width * height
    return sup
}

print(squareRect(width: 4, height: 5))

The type returned is indicated by the symbol “->”.

In Swift the parameter are passed for value, it means that we can’t change the value of the parameters in the body of the function, to make it we have to use the keyword inout in this way:

// Swap the value of two element
func swap(a: inout Int, b: inout Int) {
    let dum = a
    a = b
    b = dum
}

var first = 3
var second = 4

// Call the functions using "&" near the parameters
swap(a: &first, b: &second)

A type a bit different from other languages is the Enum. Here an example:

enum Polar: Int {
    case north = 1
    case sud, west, est
    func description() -> String{
        switch self {
        case .north:
            return "North"
        case .est:
            return "Est"
        case .west:
            return "West"
        case .sud:
            return "Sud"
        }
    }
}

The enum can have also a type (Int in the example), it’s possible to assign a specified value at every element of the enum. The big difference in Swift is that it’s possible to declare also e function in an Enum and invoke it.

var sanFrancisco = Polar.west

print(sanFrancisco.description()) // print "West"

Now see the data structure, the first one is the struct.

struct Coordinate {
    var lat: Double
    var long: Double
    
    func xy() {
       print("Lat = \(lat) and Long = \(long)")
    }
}

How in the example the struct is a data structure that can contain properties (variables, constants) and methods (function).

Very similar is also the declaration of the class:

class ClassCoordinate {
    var lat: Double
    var lon: Double
    init(lat: Double, lon: Double) {
        self.lat = lat
        self.lon = lon
    }
    
    func invert() {
        let dum = lat
        lat = lon
        lon = dum
    }
    
    func coord() -> String {
        return ("(\(lat),\(lon))")
    }
}

The big difference between class and the structures is that the struct is a value type, so if we have two variables of the same structure type, and assign the second to one, in the first is copied the value of the second.

var coordA = Coordinate(lat: 37.3382, long: 121.8863)
var coordB = Coordinate(lat: 37.3382, long: 121.8864)
var coordC = Coordinate(lat: 37.3382, long: 121.8865)

print("Point A \(coordA) Point B \(coordB)")
coordA = coordB
print("Point A \(coordA) Point B \(coordB)")
coordB = coordC
print("Point A \(coordA) Point B \(coordB)")

/*
Produce this output
Point A Coordinate(lat: 37.3382, long: 121.8863) Point B Coordinate(lat: 37.3382, long: 121.8864)
Point A Coordinate(lat: 37.3382, long: 121.8864) Point B Coordinate(lat: 37.3382, long: 121.8864)
Point A Coordinate(lat: 37.3382, long: 121.8864) Point B Coordinate(lat: 37.3382, long: 121.8865)
*/

With the class it’s is different, the class is a reference type, so when a second class is assigned to the first class, is not copied the value but the reference, so they are the same object. If you change one, change the values of the other.

var coordClassA = ClassCoordinate(lat: 37.3382, lon: 121.8863)
var coordClassB = ClassCoordinate(lat: 37.3382, lon: 121.8864)

print("Point A \(coordClassA.coord()) Point B \(coordClassB.coord())")
coordClassA = coordClassB
print("Point A \(coordClassA.coord()) Point B \(coordClassB.coord())")
coordClassB.lat = 1
coordClassB.lon = 2
print("Point A \(coordClassA.coord()) Point B \(coordClassB.coord())")

/*
The output is
Point A Coordinate(lat: 37.3382, long: 121.8863) Point B Coordinate(lat: 37.3382, long: 121.8864)
Point A Coordinate(lat: 37.3382, long: 121.8864) Point B Coordinate(lat: 37.3382, long: 121.8864)
Point A Coordinate(lat: 37.3382, long: 121.8864) Point B Coordinate(lat: 37.3382, long: 121.8865)
Point A (37.3382,121.8863) Point B (37.3382,121.8864)
Point A (37.3382,121.8864) Point B (37.3382,121.8864)
Point A (1.0,2.0) Point B (1.0,2.0)
*/

When to use the struct and when to use the class? When the data struct is big is better to use a class because the reference doesn’t duplicate data (and consuming memory) but the reference requires more attention.

To conclude I introduce the protocol, it’s defined in the Swift documentation as: “A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality”. If a class have to conform to a protocol it must implement the function and property request from the protocol.

protocol PrintProtocol {
    var simpleLabel: String {get}
    mutating func translate()
}

class CoordinateClass: PrintProtocol {
    var lat: Double
    var lon: Double
    var simpleLabel: String = ""
    
    init(a: Double, b: Double)
    {
        self.lat = a
        self.lon = b
    }
    func translate() {
        self.lat = self.lat * 2
        self.lon = self.lon * 2
    }
}

In this case, the PrintProtocol requires that a class that using it, have to declare a variable simpleLabel (get, it possible read the value) and implement a function translate. This function is mutating, it can modify the property of the class.

In the next post, I’ll start to talk about SwiftUI. This post is not frozen, I’ll change it to improve or add important things that I skipped for now.

Note: English is not my native language, so I’m sorry for some errors. I appreciate it if your correct me.

SwiftUI and Shake Gesture

There isn’t a way to catch the shake gesture only using SwiftUI, so it’s necessary use these frameworks: Uikit and Combine.

Combine is very helpful in this case because how is wrote in the Apple documentation: “Combine declares publishers to expose values that can change over time, and subscribers to receive those values from the publishers.”

In the example, the goal is catch the Shake gesture with the UiKit, with the Combine framework we publish this event and get the combine published info in the SwiftUI view that is a subscriber. Let’s start.

We must create a Swift file, ShakeGestureManager.swift

import Foundation
import SwiftUI
import Combine
let messagePublisher = PassthroughSubject<Void, Never>()
class ShakeViewController: UIViewController {
override func motionBegan(_ motion: UIEvent.EventSubtype,
                              with event: UIEvent?) {
        guard motion == .motionShake else { return }
        messagePublisher.send()
    }
}
struct ShakeViewRepresentable: UIViewControllerRepresentable {
    
    func makeUIViewController(context: Context) ->
        ShakeViewController {
            ShakeViewController()
    }
func updateUIViewController(_ uiViewController: ShakeViewController,
                                context: Context) {
        
    }
}



Where the PassthroughSubject is a “A subject that broadcasts elements to downstream subscribers.” (from the Apple documentation). We need it to communicate with the SwiftUI View.

The ShakeViewController is a simple UIViewController that catches the shake Gesture. Like in the case of the Map, it’s not possible to use the UIViewController in the SwiftUI so we must create a struct that implement the UIViewControllerRepresentable that we can use in the SwiftUI View.

Now see the SwiftUI view:

import SwiftUI
struct ContentView: View {
    @State var shaked = false
    
    var body: some View {
        NavigationView {
            VStack{
                ZStack {
                    ShakeViewRepresentable()
                                .allowsHitTesting(false)
                    VStack {
                        Text("Shake device to change view!")
                    }
                    
                }.onReceive(messagePublisher) { _ in
                    self.shaked = true
                }
                NavigationLink(destination: SecondView(), isActive: $shaked) {
                    EmptyView()
                }
            }
        }
    }
}



The state variable shaked it used to store the shaked event. In the navigationview there is a ZStack, where at the bottom (first element) there is the ShakeViewRepresentable that can’t get touch event from the user because allowsHitTesting is false, on the top there is a simple Text message.

When the ZStack receives the messagePublisher, the shaked variable become true and the NavigationLink become active so the view navigates to the SecondView (that you can create how you want). Note the use of the EmptyView from the NavigationLink, it used to show nothing but to have a working link.

That’s all. I hope that it can be helpful. You can get the code here.

Golang MongoDb raw pagination

I’m writing a complex query (for a beginner user) for mongodb using the golang official driver, i’d like share my code to help other user.

I’ll use an aggragate to do the complex query, we need to step the first one to count the records of the query, the second step to get the elements at the request page.

var basePipeline = mongo.Pipeline{
 {{“$lookup”, bson.D{
 {“from”, “makers”},
 {“localField”, “maker”},
 {“foreignField”, “username”},
 {“as”, “makerinfo”},
 }}}}



The first piece fo the pipeline is the lookup, a similar left-join, we want join from the collection of products the makers. With the subpipeline we specify the conditions of the query:

var countPipeline mongo.Pipeline
var productsPipeline mongo.Pipeline
subpipeline := bson.D{
 {“$match”, bson.D{{“$and”,
 bson.A{
 bson.D{{“name”, bson.M{“$regex”: “.*” + initial + “.*”, “$options”: “-i”}}},
 bson.D{{“makers”, maker}},
 }}



I use two different pipeline, the countPipeline to count of the products, the second to gets the products. To have the count we must add other pipeline:

var countPipeline mongo.Pipeline
var productsPipeline mongo.Pipeline
subpipeline := bson.D{
        {"$match", bson.D{{"$and",
            bson.A{
                bson.D{{"name", bson.M{"$regex": ".*" + initial + ".*", "$options": "-i"}}},
                bson.D{{"makers", maker}},
        }}
countPipeline = append(basePipeline, subpipeline)
countCondition := bson.D{{"$count", "numberOfProduct"}}
countPipeline = append(countPipeline, countCondition)
productsPipeline = append(basePipeline, subpipeline)
 
cur, err = GetDB().Collection("products").Aggregate(GetCtx(), countPipeline)
// number of elements
var total int
if err != nil {
  fmt.Printf("[Debug] decode error %s", err)
  panic(err)
 } else {
  for cur.Next(GetCtx()) {
   dum := bson.M{"np": 0}
   if err = cur.Decode(&dum); err != nil {
    fmt.Printf("[Debug] decode error %s", err)
   }
   total = int(dum["numberOfProduct"].(int32))
  }
 }


Verify the page is in the range of the pages

// number of page
pages := total / 10
if (total % 10) > 0 {
  pages++
}
jumpPage, conError := strconv.Atoi(page)
if pages == 0 || conError != nil || jumpPage > pages {
  finalResult := bson.M{"products": result, "productsCount": 0, "pages": 0}
  return finalResult
}



Finally to gets the elements of the page:

result := []bson.M{}
var nProducts = 0
// get elements
jumpPagePipeline := bson.D{{"$skip", jumpPage}}
limitPipeline := bson.D{{"$limit", 10}}
productsPipeline = append(productsPipeline, jumpPagePipeline)
productsPipeline = append(productsPipeline, limitPipeline)
cur, err = GetDB().Collection("products").Aggregate(GetCtx(), productsPipeline)
// number of elements
if err != nil {
  fmt.Printf("[Debug] decode error %s", err)
  panic(err)
 } else {
  for cur.Next(GetCtx()) {
   dum := bson.M{}
   //var resultDecode bson.M
   if err = cur.Decode(&dum); err != nil {
    fmt.Printf("[Debug] decode error %s", err)
   }
   result = append(result, dum)
   nProducts++
  }
 }
finalResult := bson.M{"products": result, "productsCount": nProducts}



I used jumpedPipeline to jump to the page and limit to get only 10 elemets for page.

This example is not the better way to do the pagination, but it can be helpful to understand how build complex query.


For some better code you can see:

https://github.com/gobeam/mongo-go-pagination (it’s not my code)

Elm upgrade package

I start with my conclusion: use elm-json for the elm packages. Now, my story:

Yesterday, a member of my team joined to my elm project to learn the project and help me, but…. when i started the elm make command, surprise, problem with the dependencies! The problem was this package:

"Skinney/murmur3": "2.0.8"



The author removed the source (or it moved), the simple solutions is copy my package directory and give it to my collegue, but it’s no final solution.

The accused package is used from

"rtfeldman/elm-css": "15.1.0"


The last version of elm-css (16.1.0) don’t depende from murmu3 so the solution is upgrade the elm-css.

I tryed it, removing from the elm.json and run

elm install rtfeldman/elm-css


I have always an dependecies error. So, i chat on slack with the community and they suggested me to use elm-json. With elm-json i try to uninstall

elm-json uninstall rtfeldman/elm-css


but I see an message error, there are other package stephenreddek/elm-range-slider that depends from this elm-css in version 15.1.0, so at the end there are my steps:

npm -g install elm-json
elm-json uninstall rtfeldman/elm-css
elm-json install rtfeldman/elm-css@16.1.0
elm-json uninstall stephenreddek/elm-range-slider
elm-json install rtfeldman/elm-css@16.1.0

Conclusion: use elm-json for the elm packages.

QML vs SwiftUI (Part 3)

In this article we’ll see the different use of the lists that is a very most used components in the mobile apps. We starting with SwiftUI, code the example show how create a simple list and the right swipe action to delete a row.

struct ContentView: View {
    @State var names = ["Albert", "Tom", "Jeff", "Jennifer", "Steve", "Bob"]
    var body: some View {
        List {
            ForEach(names.indices, id: \.self) { index in
                Text(self.names[index]) // Delegate
            }
            .onDelete { (indexSet) in
                self.names.remove(atOffsets: indexSet)
            }
        }
    }
}



The list is created with the keyword List, with For each for every elements of the array names is created an object Text that show the single name. If the model is more complex that a simple list of name and we have to show also an image we can add in the For each block the Image object.

The instruction “id: .self” is necessary to identify every single row in unique way, in this case this identifier is the index of the array. Other important keyword is “@State” with this we say to SwiftUi to monitoring the variable names and update the ui when it changes.

In the on Delete function we do the action the we want doing the right swipe, in this case delete the element. Before to switch to QML, we see an example a bit more complex:

struct People: Identifiable {
    var id = UUID()
    var name: String
    var image: String
}struct ContentView: View {
    @State var peoples = [People(name:"Albert", image: "albert.png"), People(name: "Tom", image: "tom.png"),People(name: "Jeff", image:"jeff.png"),People(name: "Jennifer",image: "jennifer.png"), People(name: "Steve", image: "steve.png"), People(name: "Bob", image: "bob.png")]
    var body: some View {
        List {
            ForEach(peoples, id: \.id) { people in
                HStack {
                    Text(people.name)
                    Image(people.image)
                }
            }
            .onDelete { (indexSet) in
                self.peoples.remove(atOffsets: indexSet)
            }
        }
    }
}



In this case we have the struct People that implements the protocol Identifiable, so we have am unique identifier for any instance of the struct. In the ForEach we now use it do identify the row also added a horizonthal stack to create a row with text and image. Now see that same example in QML:

ListView {
    id: listView
    anchors.fill: parent
    model: ListModel {
        ListElement { img: "bob.png"; name: "Bob" }
        ListElement { img: "jennifer.png"; name: "Jennifer" }
        ListElement { img: "tom.png"; name: "Tom" }
        ListElement { img: "denise.png"; name: "Denise" }
    }
    delegate: SwipeDelegate {
        id: swipeDelegate
        text: model.name
        width: parent.width
        
        ListView.onRemove: SequentialAnimation {
            PropertyAction {
                target: swipeDelegate
                property: "ListView.delayRemove"
                value: true
            }
            NumberAnimation {
                target: swipeDelegate
                property: "height"
                to: 0
                easing.type: Easing.InOutQuad
            }
            PropertyAction {
                target: swipeDelegate
                property: "ListView.delayRemove"
                value: false
            }
        }
        
        contentItem: Item {
            RowLayout {
                Text {
                    text: swipeDelegate.text
                    font: swipeDelegate.font
                    elide: Text.ElideRight
                    visible: swipeDelegate.text
                    horizontalAlignment: Text.AlignLeft
                    verticalAlignment: Text.AlignVCenter
                }
                Image {
                    source: model.img
                    visible: swipeDelegate.text
                    horizontalAlignment: Text.AlignLeft
                    verticalAlignment: Text.AlignVCenter
                }
            }
        }
        
        swipe.right: Label {
            id: deleteLabel
            text: qsTr("Delete")
            color: "white"
            verticalAlignment: Label.AlignVCenter
            padding: 12
            height: parent.height
            anchors.right: parent.right
            
            SwipeDelegate.onClicked: listView.model.remove(index)
            
            background: Rectangle {
                color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
            }
        }
    }
}



In this case the QML is a bit more complex because we have to customize the label to have the same look & feel of iOS but in QML we don’t need to use any “@State” keyword to force the gui update.

At the end I think that it’s simple for QML developer to use SwiftUI, a lot of things are similar and both the languages ​​are declaratives. Instead I think that for iOS developer is not simple to use both, is necessary more experience in the declarative world.