Monday, October 12, 2015

Getting the fontNames from Swift with XCode 7.01

func fontForDisplay(atIndexPath indexPath: NSIndexPath) -> UIFont? {
    if indexPath.section == 0 {
        let familyName = familyNames[indexPath.row]
        let fontName = UIFont.fontNamesForFamilyName(familyName).first as String
        return UIFont(name: fontName, size: cellPointSize)
    } else {
        return nil
    }
}


The above snippet of code is from
Beginning iPhone Development with Swift Exploring the iOS SDK
I'm trying this on el capitan and xcode 7.01, which now uses swift 2.0

The first issue is that xcode will warn you that 'String?' is not convertible to 'String'
Adding a ! to force cast and will allow the code to run. (append it to either first! or String!)

The next issue is that this is thrown: EXC_BAD_EXCEPTION
Looking at the trace, we can see

familyName = (String) "Bangla Sangam MN"
fontName = (String!) nil

So it appears that we're trying to get the first element of an empty array. I ended up with this solution:

    let fontArray: String? = UIFont.fontNamesForFamilyName(familyName).first
    let fontName = (fontArray != nil) ? fontArray! : ""


Let me know if there is a more idiomatic way of doing this with Swift 2.0

Thursday, January 8, 2015

golang: Do you need a singleton? Where are my private/public class modifiers?

Intro: Singletons can be useful, but as mentioned in other people's posts they are an anti pattern and can make testing and debugging difficult. A post on stack overflow had this short nonspecific message "Just put your variables and functions at the package level." http://stackoverflow.com/questions/1823286/singleton-in-go I took this as a hint that with a little more knowledge of how go packages work, I could get a single instance of an object and have it abstracted so that modification would be difficult, if not impossible.

Let's start with three files.

src/logger/logger.go
src/chat_server/main.go
src/chat_server/sub/sub.go

logger.go

package logger

import (
     "fmt"
)

type logger struct {
    Timestamp int
}

type Togger struct {
    Timestamp int
}

var log = logger{Timestamp: 12345}
var Tog = Togger{Timestamp: 12345}

func (l *logger)writeInfoFile(s string) {
    fmt.Println(s)
}

func (l *logger)writeErrorFile(s string) {
    fmt.Println(s)
}

func Debug(s string) {
    log.writeInfoFile(s)
    fmt.Println(&log.Timestamp)
}

There is a logger object named log with a single timestamp field. The other thing to note is that the functions, variables and structs (golang's version of a class) can have an upper or lower case first letter.

"if something starts with a capital letter that means other packages (and programs) are able to see it" - http://www.golang-book.com/11/index.htm

For those us who are used to having public and private keywords in our OO language, this capital letter convention is how go restricts access. This means that Togger, Tog, and Debug() can be referred to once logger is imported in another file. While log, loger and write*() can not. This takes a little closer to our goal because we should be able to instantiate an instance of logger, and only allow specific functions to act on it.

main.go

package main

import (
    "logger"
    "chat_server/sub"
    "fmt"
)

func main() {
    logger.Debug("one")
    logger.Debug("two")
   
    sub.CheckingAddress()
   
    isPublic := logger.Togger{Timestamp: 555}
   
    fmt.Println(isPublic.Timestamp)
    fmt.Println(logger.Tog.Timestamp)
   
    // These will cause an error
//    fmt.Println(logger.log.Timestamp)
//    isPublic := logger.logger{Timestamp: 333}
}   

Here are some examples of how this works. Debug is a function that can be accessed after the import. It can refer to var log as it's within the same package. Trying to access logger.log directly is not allowed, while the analagous struct value logger.Tog can be called. Any attempt to init a new 'logger' object also fails.

There is one more quick check that I wanted to verify and that is to confirm the log object continues to be the only instance no matter where it is imported.

sub.go

package sub

import (
    "logger"
)

func CheckingAddress() {
   
    logger.Debug("In SUB")
   
}

Way back in logger.go I print out the memory address of the Timestamp field.

fmt.Println(&log.Timestamp)

After running main, the output is:

one
0x547068
two
0x547068
In SUB
0x547068
555
12345

We get the same address so it's good.

Conclusion: I was able to create a single instance of my logger struct without resorting to a singleton and learned how go packages limit access to vars and and functions.