Monday, May 30, 2016

Store data in plist with NSFileManager

This example is written in Swift 2.2 with Xcode 7.3.1.

For an iOS app, permanent data may be stored in CoreData, in a simple text file, or in a plist file. This example stores information in a plist file. The steps

1. Add a new property list file:


2. Edit the key, type and value of the plist as below:



3. Modify ViewController.swift as below:

import UIKit

class ViewController: UIViewController {

    var num   : Int = 0
    var label : UILabel!
    
    let path = NSHomeDirectory()+"/Documents/Storage.plist"
    var dictionary : NSMutableDictionary!
    let fileManager = NSFileManager.defaultManager()
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        checkFile()
        
        dictionary = NSMutableDictionary(contentsOfFile: path)
        
        let button = UIButton(frame: CGRectMake(0,0,100,30))
        button.center = view.center
        button.setTitle("Generate", forState: UIControlState.Normal)
        button.addTarget(self, action: #selector(btnGenerate), forControlEvents: UIControlEvents.TouchUpInside)
        button.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        button.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
        view.addSubview(button)
        
        label = UILabel(frame: CGRectMake(0,0,100,30))
        label.center = CGPointMake(view.center.x, view.center.y-50)
        label.textAlignment = NSTextAlignment.Center
        label.text = "\(num)"
        view.addSubview(label)
        
        read()
        
        let buttonDel = UIButton(frame: CGRectMake(0,0,100,30))
        buttonDel.center = CGPointMake(view.center.x, view.center.y+50)
        buttonDel.setTitle("Delete plist", forState: UIControlState.Normal)
        buttonDel.addTarget(self, action: #selector(btnDel), forControlEvents: UIControlEvents.TouchUpInside)
        buttonDel.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        buttonDel.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
        view.addSubview(buttonDel)
    }
    
    func btnGenerate() {
        num = Int(arc4random()%100)
        label.text = "\(num)"
        write()
        
        dictionary = NSMutableDictionary(contentsOfFile: path)
    }
    
    func btnDel() {
        print("btnDel")
        label.text = "0"
        do {
            try fileManager.removeItemAtPath(path)
        } catch {
            print("Unable to delete the plist file")
        }
    }
    
    func checkFile() {
        
        if !fileManager.fileExistsAtPath(path) {
            print("File not exist!")
            
            let srcPath = NSBundle.mainBundle().pathForResource("Storage", ofType: "plist")
            
            do {
                //Copy the project plist file to the documents directory.
                try fileManager.copyItemAtPath(srcPath!, toPath: path)
            } catch {
                print("File copy error!")
            }
        }
    }
    
    func read() {
        label.text = "\(dictionary!.objectForKey("Num")!)"
        print(dictionary!.objectForKey("Num")!)
    }
    
    func write() {
        dictionary.setValue(num, forKey: "Num")
        dictionary.writeToFile(path, atomically: true)
        print("write")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


Related Information:

NSSearchPathForDirectoriesInDomains - Read/Write a file in an iOS app

Sunday, May 29, 2016

Play a sound file with AVAudioPlayer

The example below plays an audio file in Swift 2.2 with Xcode 7.3.1.

1. Drag and add the example.mp3 sound file to the project.

2. Modify ViewController.swift as:


import UIKit
import AVFoundation

class ViewController: UIViewController {
    
    var button : UIButton!
    var buttonStop : UIButton!
    
    var player : AVAudioPlayer!
    let url = NSBundle.mainBundle().URLForResource("example", withExtension: "mp3")!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Play/Pause button
        button = UIButton(frame: CGRectMake(0, 0, 200, 30))
        button.center = view.center
        button.setTitle("Play", forState: UIControlState.Normal)
        button.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        button.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
        button.addTarget(self, action: #selector(buttonPressed), forControlEvents: UIControlEvents.TouchUpInside)
        view.addSubview(button)
        
        //Stop button
        buttonStop = UIButton(frame: CGRectMake(0, 0, 200, 30))
        buttonStop.center = CGPointMake(view.center.x, view.center.y+100)
        buttonStop.setTitle("Stop", forState: UIControlState.Normal)
        buttonStop.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        buttonStop.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
        buttonStop.addTarget(self, action: #selector(buttonStopPressed), forControlEvents: UIControlEvents.TouchUpInside)
        buttonStop.hidden = true
        view.addSubview(buttonStop)
        
        do {
            player = try AVAudioPlayer(contentsOfURL: url)
        } catch {
            print("Error!")
        }
    }
    
    func buttonPressed() {
        if player.playing {
            player.pause()
            button.setTitle("Play", forState: UIControlState.Normal)
        } else {
            player.play()
            button.setTitle("Pause", forState: UIControlState.Normal)
            buttonStop.hidden = false
        }
    }
    
    func buttonStopPressed() {
        player.stop()
        player.currentTime = 0 //rewind
        buttonStop.hidden = true
        button.setTitle("Play", forState: UIControlState.Normal)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

Friday, May 27, 2016

Mac Technique: Two Fingers with TrackPad - Right-Click and Scrolling

Right-Click

To perform the behavior of a right-click without a mouse, tap the TrackPad of a Mac with two fingers.

Scroll

To perform the behavior of the scroll wheel without a mouse, move two fingers on the TrackPad.



Apple's Official Information:

Use Multi-Touch gestures on your Mac

Tuesday, May 24, 2016

Create a UISwitch programmatically

Update: July 8, 2017 (Swift 3.1 + Xcode 8.3.3)
Original Post: May 24, 2016 (Swift 2.2 + Xcode 7.3.1)

The code below shows how to create a UISwitch programmatically with various colors.

Modify ViewController.swift as:

Update: July 8, 2017 (Swift 3.1 + Xcode 8.3.3)


import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let mySwitch = UISwitch()
        mySwitch.center = view.center
        mySwitch.setOn(false, animated: false)
        mySwitch.tintColor = UIColor.blue
        mySwitch.onTintColor = UIColor.cyan
        mySwitch.thumbTintColor = UIColor.red
        mySwitch.backgroundColor = UIColor.yellow
        mySwitch.addTarget(self, action: #selector(switchChanged(sender:)), for: UIControlEvents.valueChanged)
        view.addSubview(mySwitch)
    }
    
    func switchChanged(sender: UISwitch!) {
        print("Switch value is \(sender.isOn)")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

Original Post: May 24, 2016 (Swift 2.2 + Xcode 7.3.1)

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let mySwitch = UISwitch()
        mySwitch.center = view.center
        mySwitch.setOn(false, animated: false)
        mySwitch.tintColor = UIColor.blueColor()
        mySwitch.onTintColor = UIColor.cyanColor()
        mySwitch.thumbTintColor = UIColor.redColor()
        mySwitch.backgroundColor = UIColor.yellowColor()
        mySwitch.addTarget(self, action: #selector(switchChanged(_:)), forControlEvents: UIControlEvents.ValueChanged)
        view.addSubview(mySwitch)
    }
    
    func switchChanged(sender: UISwitch!) {
        print("Switch value is \(sender.on)")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

Result:



Thursday, May 19, 2016

Horizontal Adjustment for Table Separator Lines

This example uses Xcode 7.3.1 (Swift 2.2) and iOS 9.3 simulator.

The default separator line in a tableView is like this:


Gaps exist at the left of the separator lines, white the right side of the horizontal lines touch the screen edge.

To eliminate the gaps at the left, add these lines:


tableView.separatorInset = UIEdgeInsetsZero

tableView.layoutMargins = UIEdgeInsetsZero

and this:


cell.layoutMargins = UIEdgeInsetsZero

Result:




To add gaps to the right of separators, simply add this line:


tableView.separatorInset.right = tableView.separatorInset.left

Result:



The separator lines are now centered.

Related Information:

White space before separator line into my TableView

iOS 8 UITableView separator inset 0 not working

Draw UITableView programmatically (without using the Storyboard)

Monday, May 16, 2016

Enumerations

The code below is tested with IBM Swift Sandbox (version 3.0-dev).

enum Numbers: Int {
    case zero, one, two, three, four, five
}

//show string
print(Numbers.one)
print(Numbers.three)
print(Numbers.five)
print("\n")

//show value
print(Numbers.one.rawValue)
print(Numbers.three.rawValue)
print(Numbers.five.rawValue)
print("\n")

//value to string
print(Numbers(rawValue: 3)!)
print(Numbers(rawValue: 4)!)
print(Numbers(rawValue: 5)!)
print("\n")

//Without the Int type
enum Names {
    case Tom, Jerry, Mickey, Donald
}

print(Names.Tom)
print(Names.Jerry)
print("\n")

//enumeration with function
func showName(name: Names) {
    print("I like \(name).")
}

showName(Names.Mickey)
showName(Names.Donald)

Console output:

one
three
five

1
3
5

three
four
five

Tom
Jerry

I like Mickey.
I like Donald.

Friday, May 13, 2016

Xcode Tip: Comment Hotkey/Shortcut

To put comment characters // in front of multiple lines in Xcode, highlight the area required and press:

[command ⌘] + [/]



This technique also works with IBM Swift Sandbox.

Related Information:

Xcode Tip: Hotkeys/Shortcuts to move multiple lines horizontally
Xcode Tip: Hotkey/Shortcut to format the indentation of multiple lines

Thursday, May 12, 2016

Swift Tip: Prevent code execution using #if false and #endif

To disable several lines of code in Swift, a useful method alternative to comment characters /* and */ is to use the # (number/hash/pound) sign plus if false and endif as below:

#if false
...
....code to be disabled....
... 
#endif

For example:

print("123")
#if false
print("456")
#endif

Result:

123

Tuesday, May 10, 2016

How to call functions in a separate Swift file

Update - May 22, 2017. The code below still works with Xcode 8.3.1 (Swift 3.1).

The code below shows how to call functions in a separate Swift file. Xcode 7.3 (Swift 2.2) is used. Two examples are shown in the following steps:

1. Create a new Swift file with any name such as MyFile.swift.

2. Modify the file as:


import Foundation

//Example 1
class MyClass {
    func myFun() {
        print("myFun!!")
    }
    static let myInstance = MyClass()
}

//Example 2
class AnotherClass {
    class func anotherFun() {
        print("anotherFun!!")
    }
}

3. Modify ViewController.swift as:


import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        MyClass.myInstance.myFun()
        
        AnotherClass.anotherFun()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

Result of Debug Console:


myFun!!

anotherFun!!

Wednesday, May 4, 2016

Xcode Tip: Hotkeys/Shortcuts to move multiple lines horizontally

I tried to move/shift multiple lines horizontally in Xcode, but the tab key did not work. The solution is to select the lines to be moved and hit the following keys:

(command ⌘) + ( ] ) => Right / Indent

(command ⌘) + ( [ ) => Left / Un-indent



To indent a section automatically with a single (control) + (i) short cut, see Xcode Tip: A powerful hotkey/shortcut to format the indentation of multiple lines.




Related Information:

How can I indent multiple lines in xcode?
Xcode Tip: A powerful hotkey/shortcut to format the indentation of multiple lines (control) + (i)
Xcode Tip: Comment Hotkey/Shortcut