My podcast selection

I’m writing this lines from Hue, in Vietnam. I’m on a three week vacation trip, we started a week ago in the north of the country and we’re slowly heading south. We don’t have anything planned, this gives us the flexibility to do whatever we feel like doing (as long as we are able to take our fight back of course). 

We do a lot of traveling by night bus, this give us more day time to visit, as a plus this has given me the opportunity to catch up with many of my favorite podcasts. In case you’re interested, in no particular order, they are:

1. Accidental Tech Podcast 

http://atp.fm

2. Core Intuition

http://www.coreint.org

3. Dan Carlin Hardcore History

DC Homepage

4. Debug

http://m.imore.com/debug

5. Common Sense with Dan Carlin

DC Homepage

6. Internet History Podcast 

Home

7. The iPhreaks Show

https://devchat.tv/iphreaks/

Suggestions on what to listen, disagree? Let me know on Twitter @MarcMasVi

Dates & Components in Swift 2.0

Another topic that has been changed in Swift 2.0 is how to work with dates.

I’m digging into this topic for my upcoming app and I’ve found that most documentation on the web refers to Swift 1.2. So here are some snippets to create dates using components:

//CreateDateFromComponents (1st January 2016)

       var newDate = NSDate()

       let newDateComponents: NSDateComponents = NSDateComponents()

       newDateComponents.setValue(1, forComponent: NSCalendarUnit.Day)

       newDateComponents.setValue(1, forComponent: NSCalendarUnit.Month)

       newDateComponents.setValue(2016, forComponent: NSCalendarUnit.Year)

       newDate = NSCalendar.currentCalendar().dateFromComponents(newDateComponents)!

 

//AddToDateFromComponents (1 day, 1 month and 1 year to today)

 

        var newDate = NSDate()

        let newDateComponentsWhereQueryShouldBegin: NSDateComponents = NSDateComponents()

        newDateComponents.setValue(1, forComponent: NSCalendarUnit.Day)

        newDateComponents.setValue(1, forComponent: NSCalendarUnit.Month)

        newDateComponents.setValue(1, forComponent: NSCalendarUnit.Year)

        newDate = NSCalendar.currentCalendar().dateByAddingComponents(newDateComponents, toDate: newDate, options: NSCalendarOptions(rawValue: 0))! 

 

Hope this proves useful. If you would have any suggestions on how to improve you know where to reach me, @MarcMasVi in Twitter.

 

Marc

 

Evaluate string width and return CGFloat (Swift, OSX)

This morning I’ve been working in a Swift function to detect the width of a given text and return a CGFloat. 

I’ve not found that many examples on the web for OSX, so here you have what I’ve done in all of its glory:

func evaluateStringWidth (textToEvaluate: String) -> CGFloat{

    letfont = NSFont.userFontOfSize(NSFont.systemFontSize())

    let attributes = NSDictionary(object: font!, forKey:NSFontAttributeName)

    let sizeOfText = textToEvaluate.sizeWithAttributes((attributes as! [String : AnyObject]))

    

    return sizeOfText.width

}

 

If you would have any suggestions on how to improve you know where to reach me, @MarcMasVi in Twitter.

CSV Parser Swift 2

One of the features I’m adding to an upcoming app is the ability to import CSV files. For that purpose I looked around for code already available (and found several options, see below), however none of them compelled me enough so I decided to create my own. 

The main objective was to make it as simple as possible and, of course, coded in Swift 2. Note however that I’m still learning so if you would have any suggestions / feedback send them my way! Here it is in all of its glory:

//

//  CSVImporter.swift

//  Controller

//

//  Created by Marc on 5/8/15.

//  Copyright (c) 2015 MMV Solucions S.L. All rights reserved.

//

 

import Cocoa

 

class CSVImporter: NSObject {

 

    var columnDelimiter = “,”

    var textDelimiter = “\””

    var rowDelimiter = “\n”

    var doesItHaveHeader = true

    var rowsFromString : Array<String> = []

    var finalParsedCsv : Array<Array<String>> = []

    

    

 

    

    func retrieveCsvFileAndReturnRows(path path: String ) -> Array<Array<String>>? { //Main

        

        let stringToParse: String?

        do{

            stringToParse = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)

        } catch _ {

            stringToParse = nil

        }

        var unwrappedStringToParse=“”

        

        if (stringToParse == nil) { return nil } else {

            unwrappedStringToParse = stringToParse! }

        

        //Cleaning string

        unwrappedStringToParse = stringToParse!.stringByReplacingOccurrencesOfString(“\r”, withString: “\n”)

        unwrappedStringToParse = unwrappedStringToParse.stringByReplacingOccurrencesOfString(“\n\n”, withString: “\n”)

        

        //Storing by rows

        rowsFromString = unwrappedStringToParse.componentsSeparatedByString(rowDelimiter)

        

        //Removing header

        if (doesItHaveHeader == true){

            rowsFromString.removeAtIndex(0)

        }

        

        //Converting and adding rows

        for iteratorString in rowsFromString {

            

            if(iteratorString.rangeOfString(textDelimiter) != nil){ //We have detected double quotes

                let arrayContainingDoubleQuotes = iteratorString.componentsSeparatedByString(columnDelimiter)

                var newArrayAccountingForQuotes : Array <String> = []

                var tempArrayContainingNewWord : Array <String> = []

                var inDoubleQuoteLoop = false

                var newStringFromSplittedWord = “”

                for stringToTestForDoublequotes in arrayContainingDoubleQuotes{

                    if stringToTestForDoublequotes.rangeOfString(textDelimiter) != nil || inDoubleQuoteLoop == true {

                        if stringToTestForDoublequotes.rangeOfString(textDelimiter) != nil && inDoubleQuoteLoop == false {

                            tempArrayContainingNewWord.append(stringToTestForDoublequotes)

                            inDoubleQuoteLoop = true

                        }else{

                            tempArrayContainingNewWord.append(stringToTestForDoublequotes)

                            newStringFromSplittedWord = “”.join(tempArrayContainingNewWord)

                            newArrayAccountingForQuotes.append(newStringFromSplittedWord)

                            //Maybe add here option to remove “

                            inDoubleQuoteLoop = false

                        }

 

                    }else{ //No double quotes found and not in the middle of text, add to new array

                     newArrayAccountingForQuotes.append(stringToTestForDoublequotes)

                    }

                }

                finalParsedCsv.append(newArrayAccountingForQuotes)

            }else{

                finalParsedCsv.append(iteratorString.componentsSeparatedByString(columnDelimiter))

            }

            

        }

        

        //Final cleaning

        var row = 0

        for iteratorForFinalCleaning in finalParsedCsv{

            var column = 0

            for _ in iteratorForFinalCleaning{

                //Get the text of these coordinates

                var tempStringToRemoveCommas = finalParsedCsv[row][column]

                if (tempStringToRemoveCommas.rangeOfString(textDelimiter) != nil){

                //Do the needed changes into the text

                tempStringToRemoveCommas = tempStringToRemoveCommas.stringByReplacingOccurrencesOfString(textDelimiter, withString: “”)

                //Add result back to the arrayOfParsedContent

                finalParsedCsv[row].insert(tempStringToRemoveCommas, atIndex: column)

                }

                column++

            }

            row++

        }

        

        returnfinalParsedCsv

    }

    

 

}

 

 

Remember I’m still on my Swift beginnings, if you want other options check out SwiftCSV or this post

Android & Security

Great post from a long time Android user & security journalist. Worth a read:

Goodbye, Android: http://t.co/p4QwqSx75P http://t.co/uiQ2lWiTeD

Frankly I hope Google would change his ways on this.

 

Marc

Compatibility updates

Today both Excelling and Notio have been received a compatibility update to ensure they work great under iOS9. Provided that Apple approves them both should be available for users in about a week. 

And now back to focusing on the new app. 

 

Marc

It’s out and just ordered one!

So today the Apple went on sale on a few more countries in Europe. Being in one of them I ordered one and will receive it in about 3 weeks. 

Will report my impressions once I’ve had some time with it, certenly excited about it and about developing apps for it. 

 

Marc

Starting working on a new app

Late last week I was posting to announce that Notio would be discontinued. Today it’s time to announce some more positive news. 

After much research and discussions with trusted friends, today I’m kicking off the design phase of my new app. And, for me, this is one of the most fun phases. 

I love spending time getting every feature how I think works best, asking for feedback & iterating once you realize your idea didn’t quite work. 

I’m really excited about it, will share more about the app as soon as I can. The thing I can already say, it’s going to be a Mac app. 

Now to work! 

Marc

Discontinuing app Notio

After WWDC15, having thought long and hard, I’ve taken the decision to discontinue one of my Products: Notio.

It’s an app I started with the idea of giving a new spin on notes, treating them like ideas, so that you could add multiple information to them.

Although I had high hopes, initial reception of the app was not as great. I did have a significant amount of downloads but very few of them upgraded to the paid product. 

Now, with the new iOS9 Notes app covering many of the features I include, or was planning to include, I think it’s time to focus on new products.

For me its the first app that I’m discontinuing, and it’s hard…. But seeing the new Notes app and the current amount of money Notio was generationg I believe is the right move. Time will be better spent in other apps.

It’s hard… Has to be done…

Marc