• Compare NSDate instance with ease in Swift

    To make it easy comparing two NSDate instances in Swift we can overload <=, >=, >, < and == operators with NSDate types on left and right hand sides of overloading functions. timeIntervalSince1970 is a safe measure for comparing most dates. I used timeIntervalSince1970 to make the decision if two dates are equal, less or greater.

    func <=(lhs: NSDate, rhs: NSDate) -> Bool {
        return lhs.timeIntervalSince1970 <= rhs.timeIntervalSince1970
    }
    func >=(lhs: NSDate, rhs: NSDate) -> Bool {
        return lhs.timeIntervalSince1970 >= rhs.timeIntervalSince1970
    }
    func >(lhs: NSDate, rhs: NSDate) -> Bool {
        return lhs.timeIntervalSince1970 > rhs.timeIntervalSince1970
    }
    func <(lhs: NSDate, rhs: NSDate) -> Bool {
        return lhs.timeIntervalSince1970 < rhs.timeIntervalSince1970
    }
    func ==(lhs: NSDate, rhs: NSDate) -> Bool {
        return lhs.timeIntervalSince1970 == rhs.timeIntervalSince1970
    }

    Note that operator overloading declarations should be placed in global context. I highly recommend documenting this behavior in your developer guide documents.

    With those operator overloading declarations in place, now we can compare dates with ease:

    let date0 = NSDate(timeIntervalSince1970: 0)
    let date1 = NSDate(timeIntervalSince1970: 0)
    let date2 = NSDate(timeIntervalSince1970: 1839203982)
    let date3 = NSDate(timeIntervalSince1970: 1339203982)
    
    date1 < date2 // true
    date0 == date1 // true
    date3 > date2 // false
  • Get QuickLook Preview of Swift objects in XCode

    When setting breakpoints in XCode, it’s quite hard to see what exactly is inside an object. All XCode give you is memory address of that object. In XCode 6 it’s possible to overcome this by implementing debugQuickLookObject method in your object. This function will be called when program is stopped by a breakpoint and you hover over the object and select the little eye icon.

    For example, in my File class, I’ve implemented this method in my class. As you can see the output is very useful and handy for debugging. It works great for NSManagedObjects too!

    Quick look of an object in XCode

    class File: NSManagedObject {
        @NSManaged var id: NSNumber
        @NSManaged var parent_id: NSNumber
        @NSManaged var name: String!
        @NSManaged var content_type: String!
    
        func init(json:NSDictionary){ /* ... */
        }
    
        func debugQuickLookObject() -> AnyObject? {
            return "\(name)\ntype:\(content_type)"
        }
    }

    debugQuickLookObject can return almost anything. From a string to image to sounds. It should return one of the cases of QuickLookObject which is listed here:

    enum QuickLookObject {
        case Text(String)
        case Int(Int64)
        case UInt(UInt64)
        case Float(Double)
        case Image(Any)
        case Sound(Any)
        case Color(Any)
        case BezierPath(Any)
        case AttributedString(Any)
        case Rectangle(Double, Double, Double, Double)
        case Point(Double, Double)
        case Size(Double, Double)
        case Logical(Bool)
        case Range(UInt64, UInt64)
        case View(Any)
        case Sprite(Any)
        case URL(String)
    }
  • How to kill child processes that spawn their own child processes in Node.js

    If a child process in Node.js spawn their own child processes, kill() method will not kill the child process’s own child processes. For example, if I start a process that starts it’s own child processes via child_process module, killing that child process will not make my program to quit.

    var spawn = require('child_process').spawn;
    
    var child = spawn('my-command');
    
    child.kill();

    The program above will not quit if my-command spins up some more processes.

    PID range hack

    We can start child processes with {detached: true} option so those processes will not be attached to main process but they will go to a new group of processes. Then using process.kill(-pid) method on main process we can kill all processes that are in the same group of a child process with the same pid group. In my case, I only have one processes in this group.

    var spawn = require('child_process').spawn;
    
    var child = spawn('my-command', {detached: true});
    
    process.kill(-child.pid);

    Please note - before pid. This converts a pid to a group of pids for process kill() method.

  • You don't have to ask developers to install Bower and Grunt to start your app

    It’s very common in font-end applications to have Bower dependencies and use Grunt (or Gulp) for their build system. Usually in README document it’s stated that you need to install Bower and Grunt globally before you can start the project.

    npm install -g bower grunt-cli
    git clone git://myapp.git
    cd my app
    npm install
    bower install
    grunt serve

    In Swagger Editor project, I made this process as simple as git clone and then npm start.

    git clone git@github.com:swagger-api/swagger-editor.git
    cd swagger-editor
    npm start

    No need for installing Bower or Grunt. It also works in Windows.

    npm scripts to rescue!

    With npm scripts we can remove dependencies to global installation of Bower and Grunt and also install npm and Bower packages automatically. First of all we need to install Bower and Grunt as developer dependencies of our app.

    npm install --save-dev bower grunt-cli

    Now, using npm scripts fields we can define start script to trigger npm install, bower install and then grunt serve.

    "scripts": {
      "start": "npm install; ./node_modules/bower/bin/bower install; grunt; ./node_modules/grunt-cli/bin/grunt serve"
    }

    Now, git clone and then npm start will do everything you need. This will work perfectly in Linux and OS X because "start" is simply a Bash script. But Windows doesn’t have Bash and there is going to be some problems in Windows.

    To solve Windows issues, we can put all of the start tasks into a JavaScript file, then inside start script in package.json we simply execute it with global node executable. Since command for executing Node.js files is the same in Windows and Unix, it will work across platforms.
    We will need to use programmatic interfaces of npm, Bower and Grunt in our JavaScript script. In my case, I named this script, start.js and placed in root of my app directory.

    start.js

    For installing Node modules, we can use prestart script. npm always calls prestart before calling start script. It’s a good opportunity to install node dependencies there.

    "scripts": {
        "prestart": "npm install",
        "start": "node start.js"
      }

    Now we can use npm start across platforms and don’t ask developers to install Bower or Grunt globally!

    Pro tip: If you name your script, server.js you don’t even have to have a start field in scritps of your package.json, npm will automatically run node server.js for npm start command

subscribe via RSS