Sunday, June 28, 2015

Posting score to Game Kit Leader board using swift

As you might already know, I recently started exploring Swift language and now I am trying out GameKit framework. While I have some experience in working with GameKit using Objective C. I wanted to do the same thing using swift. As such there are no API changes while using GameKit with Swift or Objective C. However there are some syntax change.

In this post, I will show how to Authenticate local player using GameKit framework and post score to LeaderBoard defined in iTune Connect Application setting.

Following is code snippet that shows how to Authenticate Local player. This function takes ViewController as argument. Login dialog will be displayed using this View controller. Rest will be taken care by GameKit framework.
func authenticateLocalPlayer(viewController: UIViewController) {
    let localPlayer: GKLocalPlayer = GKLocalPlayer.localPlayer()
    
    localPlayer.authenticateHandler = {(ViewController, error) -> Void in
        if((ViewController) != nil) {
            // 1 Show login if player is not logged in
            viewController.presentViewController(ViewController, animated: true, completion: nil)
        } else if (localPlayer.authenticated) {
            // 2 Player is already euthenticated & logged in, load game center
            self.isGameCenterEnabld = true                
        } else {
            // 3 Game center is not enabled on the users device
            self.isGameCenterEnabld = false
            println("Local player could not be authenticated, disabling game center")
            println(error)
        }
        
    }
    
}
Now we have authenticated local player. So when we are ready to post score to Leader Board. We can use below function. Here we are posting score to "defaultLeaderBoard". Which is identifier of Leader board defined in iTune connect App setting.

func submitScore( score: Int) {
    if( !isGameCenterEnabld ) {
        return;
    }
    
    var sScore = GKScore(leaderboardIdentifier: defaultLeaderBoard)
    sScore.value = Int64(score)
    
    let localPlayer: GKLocalPlayer = GKLocalPlayer.localPlayer()
    
    GKScore.reportScores([sScore], withCompletionHandler: { (error: NSError!) -> Void in
        if error != nil {
            println(error.localizedDescription)
        } else {
            println("Score submitted")
            
        }
    })
}
That's it. Hope this will be useful.

Saturday, June 27, 2015

Using NSNotificationCenter in Swift

NSNotificationCenter is a convenient method to implement Observer pattern in iOS, something similar to what we say Signal/Slot in Qt framework.

To register one self as observer to some event, you can use addObserver method form NSNotificationCenter. In below code you are adding self as observer, selector is method which will be called when event is triggered, name is name of event or notification in which we are interested in, and object is object from which we want to receive event from, nil means we are ready to receive event from any object.
NSNotificationCenter.defaultCenter().addObserver(
    self, 
    selector: "gameViewClosed", 
    name: "gameViewClosed", 
    object: nil);
Now to trigger the notification, you can use postNotificationName method from NSNotificationCenter. Following code shows the same. Here we are sending notification for "gameViewClosed" event, object nil mean deliver event to all interested objects.
NSNotificationCenter.defaultCenter().postNotificationName(
    "gameViewClosed", 
    object: nil);
That's it, thanks for reading.

Thursday, June 25, 2015

Playing sound using Swift

Posting small code snippet to that shows how to play sound using Swift in iOS.

First we need to import AVFoundation.
import AVFoundation
Then we need to create instance of AVAudioPlayer. I created a small utility function like below for the same.

private static func createAudioPlayer
( sound: String, type: String ) -> AVAudioPlayer {

    var error:NSError?;
    let soundUrl = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(sound, ofType: type)!);
    println(soundUrl)
    
    var player = AVAudioPlayer(contentsOfURL: soundUrl, error: &error);
    player.prepareToPlay();
    return player;
}

And this function can be used like below.
public init() {
    // Removed deprecated use of AVAudioSessionDelegate protocol
    AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil);
    AVAudioSession.sharedInstance().setActive(true, error: nil);
    
    correctAns = MusicHelper.createAudioPlayer("correctAns", type: "wav");
    wrongAns = MusicHelper.createAudioPlayer("wrongAns",type: "wav");
}
Now we can use AVAudioPlayer's play API to play the sound. Like below.

public func playCorrectAnsSound() {
    correctAns.play();
}

public func playWrongAnsSound() {
    wrongAns.play();
}

That's it, thanks for reading.

Sunday, June 7, 2015

Performing Segue and Passing data in iOS

I was trying to learn how to perform view switching using Segue for UI created by StoryBoard. Using Segue is quite easy and convenient. You can create Segue from Interface Builder, which associate action to view. Like if you click some button then you can associate this click action with view switch and you can select which view to switch to. This all is quite simple and can be done using simple drag and drop.

In case you want to perform view switch manually without any user interaction, you can call "performSegueWithIdentifier", like below. Here once my game is finished, I am calling "GameOverSegue", which will switch view to GameOver view.
self.performSegueWithIdentifier("GameOverSegue", sender: self)
If you want to pass some data while performing Segue, your calling ViewController needs to override "prepareForSegue" function. In this function you can set data to called view. Like below, I want to pass score to my GameOver view.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if( segue.identifier == "GameOverSegue") {
        let gameOverVC: GameOverViewController = 
            segue.destinationViewController as! GameOverViewController;
        gameOverVC.setScore(self.score)
    }
}
Thanks, hope this will be helpful.

Saturday, June 6, 2015

Drawing round border around UIView in iOS

I wanted to create a subview UIView with round border in iOS. I found following code works very well to draw round border around UIView. While this code is written swift you can easily write similar code in Objective C as well.

Following is the code. As you can see, I selected subview UIView and made is IBOutlet using Interface Builder. Once that is done you can see round border around view.

@IBOutlet weak var contentView: UIView?
    
override func viewDidLoad() {
    super.viewDidLoad();
        
    contentView?.layer.borderWidth = 3.0
    contentView?.layer.borderColor = UIColor(red:102/255,green:102/225,blue:102/225, alpha:1).CGColor
    contentView?.layer.cornerRadius = 14
}
    
And following how it looks.

Friday, June 5, 2015

Hiding status bar in iOS8 using Swift

I recently started learning swift, while learning I started to create simple game. I wanted to make my game full screen, but I was unable to hide top status bar from Interface builder. No matter what I change that status bar was always visible.

Buf I found following code snippet, if you add this code in your View Controller file, you can easily hide status bar.
override func prefersStatusBarHidden() -> Bool {
    return true;
}
Following how my ViewController file looks after adding this code.
class ViewController: UIViewController {
        
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    override func prefersStatusBarHidden() -> Bool {
        return true;
    }
}
That's it. Hope this will be hopeful.