Thursday 11 December 2014

Working with ABAddressBook in Swift

ABAddressBook By definition :
The ABAddressBook opaque type (whose instances are known as address books) provides a programming interface to the Address Book—a centralized database used by multiple applications to store personal information about people.


Main points covered :

  • Fetch contacts from AddressBook
  • Insert/Edit new contact to AddressBook
  • Delete contact from AddressBook
  • Register call back to listen changes in AddressBook to our App

Some common steps for all actions:

  • Import  AddressBook
    import AddressBook
  • Get addressBook reference

    let addressBook : ABAddressBookRef? = ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()

  • Get user permission to access AddressBook
    ABAddressBookRequestAccessWithCompletion(addressBook, { (granted : Bool, error: CFError!) -> Void in           if granted == true
         {
               //do stuff here
         }
    })

    once user grants permission to access addressBook, we can move further.
  • Fetch contacts from AddressBook
    let allContacts : NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()
    for contactRef:ABRecordRef in allContacts { // first name if let firstName = ABRecordCopyValue(contactRef, kABPersonFirstNameProperty).takeUnretainedValue() as? NSString { //Use firstName }

    // Similarly all properties with same kind of ABPropertyID can be fetched. i.e kABPersonLastNameProperty, kABPersonMiddleNameProperty etc }

  • Insert / Edit new contact to AddressBook

    - Create new contact reference
    contactRef = ABPersonCreate()?.takeUnretainedValue() as ABRecordRef!


    - Or get contact reference of contact to be edited
    contactRef = ABAddressBookGetPersonWithRecordID(addressBookRef!, CONTACT_UNIQUE_ADDRESSBOOK_ID).takeUnretainedValue() as ABRecordRef!

    - Set properties

    //First Name
    ABRecordSetValue(contactRef, kABPersonFirstNameProperty, "Test FirstName" nil)

    //Last Name
    ABRecordSetValue(contactRef,  kABPersonLastNameProperty, "Test LastName" nil)


    so on for all required properties.

    - Add contact reference to address book and save it
    ABAddressBookAddRecord(addressBookRef!, contactRef, nil); let success = ABAddressBookSave(addressBookRef!, nil);


    // success will be true for successful addition
Delete contact from AddressBook

- Get contact reference of contact to be deleted
contactRef = ABAddressBookGetPersonWithRecordID(addressBookRef!, CONTACT_UNIQUE_ADDRESSBOOK_ID).takeUnretainedValue() as ABRecordRef!


- Delete contact from addressbook and save it

ABAddressBookRemoveRecord(addressBook!, contactRef!, &errorRef)
ABAddressBookSave(addressBook!, &errorRef)
  • Register call back to listen changes in AddressBook to our App

book = ABAddressBookCreateWithOptions(NULL, NULL); ABAddressBookRegisterExternalChangeCallback(book, addressBookChanged, nil);

and,
void addressBookChanged(ABAddressBookRef reference, CFDictionaryRef dictionary, void *context) {
   // handle call back here..
}

Thursday 17 July 2014

Working with UIAlertController in Swift (NS_CLASS_AVAILABLE_IOS(8_0))

A UIAlertController, replaces prior UIActionSheet and UIAlertView classes for displaying alerts from iOS 8.


Declare alert controller:
var alert : UIAlertController?

Initialise alert controller:

  • UIAlertControllerStyleAlert
// UIAlertController Initializer
alert = UIAlertController(title: "Your Title", message: "Your Message", preferredStyle: .Alert)

//UIAlertController with UIAlertActions
alert = UIAlertController(title: "Your Title", message: "Your Message", preferredStyle: .Alert)

let
Yes = UIAlertAction(title: "Yes", style: .Default, handler: {(alertAction: UIAlertAction!) in self.alert!.dismissModalViewControllerAnimated(true)})

let
No = UIAlertAction(title: "No", style: .Default, handler:{(alertAction: UIAlertAction!) in self.alert!.dismissModalViewControllerAnimated(true)})

alert!.addAction(Yes)
alert!.addAction(No)

//UIAlertController with UIAlertActions & Input Textfields
alert = UIAlertController(title: "Your Title", message: "Your Message", preferredStyle: .Alert)

let Yes = UIAlertAction(title: "Yes", style: .Default, handler: {(alertAction: UIAlertAction!) in self.alert!.dismissModalViewControllerAnimated(true)})

let No = UIAlertAction(title: "No", style: .Default, handler:{(alertAction: UIAlertAction!) in self.alert!.dismissModalViewControllerAnimated(true)})

alert!.addAction(Yes)
alert!.addAction(No)

alert!.addTextFieldWithConfigurationHandler({(textField: UITextField!) in textField.placeholder = "UserName"})

alert!.addTextFieldWithConfigurationHandler({(textField: UITextField!) in textField.placeholder = "Password"; textField.secureTextEntry = true})


  • UIAlertControllerStyleActionSheet
//UIAlertController with ActionSheet
alert = UIAlertController(title: "Your Title", message: "Your Message", preferredStyle: .ActionSheet)

let
Yes = UIAlertAction(title: "Yes", style: .Default, handler: {(alertAction: UIAlertAction!) in self.alert!.dismissModalViewControllerAnimated(true)})


let
No = UIAlertAction(title: "No", style: .Default, handler:{(alertAction: UIAlertAction!) in self.alert!.dismissModalViewControllerAnimated(true)})

alert!.addAction(Yes)
alert!.addAction(No)

Present alert controller:
self.presentViewController(alert!, animated: true, completion: nil)

Reference: https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIAlertController_class/index.html

GitHub:
https://github.com/bhvk121/UIAlertController_iOS8

Thursday 19 June 2014

Export Text As Audio File in MAC OS

1) Find Automator from spotlight and run it. Then Select new service template



2) Add new action "Text to Audio File" in workflow by drag & drop
3) Adjust / Customise options as required 



4) Run Workflow
5) Save Service with appropriate name




  • To use this service and export an audio file, openup any application on your Mac and select the text you would like to be converted to Audio.

  • With the text selected, click on the application name in the menu bar.

  • Select the name of the service that you just saved in Automator from underneath the Services menu listing.

  • After clicking on the service, a new audio file will appear on your destination given in service while setup, after a few seconds.

  • This file will read aloud the text you selected in the application.




Monday 9 June 2014

Introducing Swift programming language

Swift, Programming language  without the constraints of C compatibility,  Introduced by at WWDC 2014 keynote. Which has been met with a positive & exciting response from the whole apple and apple developers community.

So far Apple’s default development environment for iOS, Xcode, has been using the language Objective-C since iOS release; It was highly adopted by Apple, and has written Cocoa /  Cocoa -Touch  framework APIs with Objective-C.


Swift uses the same LLVM compiler and runtime as Apple’s Objective-C implementation, so Swift and Objective-C code can live side-by-side in the same application. The language provides access to all of the Cocoa and Cocoa Touch features developers are currently used to from Objective-C.

Xcode 6 comes with deeply integrated Swift support.It will feature an interactive “Playground” that allows you to edit your code and watch how your changes influence your app in real-time. Xcode’s debugging console now also supports Swift syntax natively.As per Greg Federighi, Apple senior vice president for software engineering,

"Swift is fast, it is modern, it is designed for safety, and it enables a level of interactivity and development that you've never seen before on the platform"The main concept behind Swift existence is to remove overhead caused by C language dependancy and keep Apple's adopted Objective-C language feel as it is.

Swift features such capabilities as,


  • Closures (similar to blocks in C and Objective-C) unified with function pointers
  • Tuples and multiple return values
  • Generics
  • Fast and concise iteration over a range or collection
  • Structs that support methods, extensions, protocols.
  • Functional programming patterns, e.g.: map and filter

Some swift code snippet :


  • //let keyword to make a constant, var keyword to make a variable
    var variable = 90
    variable = 67
    let constant = 88
    
    //create array using square brackets []
    var languageList = ["C", "Objective C", "JAVA"]
    languageList[1] = "Swift"
    

Apple states by introducing swift : "Swift is an innovative new programming language for Cocoa and Cocoa Touch. Writing code is interactive and fun, the syntax is concise yet expressive, and apps run lightning-fast. Swift is ready for your next iOS and OS X project — or for addition into your current app — because Swift code works side-by-side with Objective-C."

Developers can start development with Swift to implement new application features or enhance existing features. Apps built with swift can be submitted
 to the App Store and Mac App Store when iOS 8 and OS X Yosemite are released this fall.

Reference / More Info :
https://developer.apple.com/swift/
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/

Thursday 22 May 2014

Introducing UIKit Dynamics

Concern : As animation is so important and allows to represent things in more realistic manner, iOS 7 came with new catalog UIKit Dynamics. lets adopt it!

Outcome : Idea & understanding of UIKit Dynamics and concern things.

Description :

  • UIKit Dynamics which has been introduced from iOS 7, facilitate typical UIViews which conforms to   UIDynamicItem  protocol to behave more lively.
  • New framework allow us to relate our UIKit views with real life factors like gravity, resistance, friction, collision and so on.
  • Dynamics on views can be achieved by directly adding primitive behaviour and also by adding custom behaviour which may be combination of primitive behaviours.

Main Roles:     

  • Two components playing main or say major roles to dynamics let happen, which are :
  1. UIDynamicAnimator  :
    - Acts as UIKit physics engine.
    - Takes reference of  UIView which aspire to adopt dynamics.
    - Accepts various UIDynamicBehaviours and make referenced view to act accordingly.
  2. UIDynamicBehaviour :
- Allows to configure view behaviour in physics (real) world.
- Inherited by primitive dynamic behaviours which are,

UIGravityBehavior,
To make our dynamic view real and alive, we can apply gravity on it by this behaviour which makes view to fall within referenced view as if it is in real world.

     
UIAttachmentBehavior,
As name suggest, this behaviour allows view to act as if it attached to some point in referenced view and also with other dynamic item.

UICollisionBehavior,
When our views move there is a chance of collision between them or with the boundaries of the referenced view.

By using this behaviour this kind of collision can be handled in more subtle way. Boundaries for the collision can be defined as bound of referenced view or any other boundary defined by lines or Bezier path. 

      
UIPushBehavior
,
Simulates effect of pushing dynamic items in specific direction with defined force.

Two kind of forces : 

Instantaneous:
 acts as sudden strong push at once, which will result in quick velocity gain at start, which gradually lose momentum and eventually stops.

Continuous:  is applied continuously on dynamic item causing gradual acceleration. 


UISnapBehavior,

Allows to add snap behaviour on view, by which view behaves as if it is pulled suddenly and will stop at given point by completing oscillation specified in form damping.


UIDynamicItemBehavior,
Allows to add additional properties like density, friction, rotation etc to dynamic items which will affect primitive behaviours and hence dynamic item behaviour.

     - can be inherited by custom class to achieve more custom behaviour.

Lets see how to achieve this by code,
    Configure UIDynamicBehaviours
  • // get UIGravityBehavior instance
    UIGravityBehavior *gravityBehavior =
    [[UIGravityBehavior alloc]initWithItems:@[view1, view2, ...]];
    
    // set gravity direction
    CGVector vector = CGVectorMake(0.5, 0.5);
    [gravityBehavior setGravityDirection:vector];
    
    // For customised gravity behaviour set Angle,magnitude
    gravityBehavior.angle = DEGREES_TO_RADIANS(45);
    gravityBehavior.magnitude = 2.0f;
    
    

  • BreakPoint :
    • The default value for the gravity vector is (0.0, 1.0)
    • The acceleration for a dynamic item subject to a (0.0, 1.0) gravity vector is downwards at 1000 points per second²
    • magnitude of 2.0 represents an acceleration of 2000 points / second²

    - UICollisionBehavior
  • //collision behaviour between view1 and view2, which results in real time collision between these views and based on their characteristics like angle,magnitude etc. physics engine will apply effect on views as per physics law.
    
    UICollisionBehavior *collisionBehaviour =
    [[UICollisionBehavior alloc] initWithItems:@[view1, view2]];
    
    
    //convert referenced view bound as collision boundary, which will stop views to go out of the screen bound.
    collisionBehaviour.translatesReferenceBoundsIntoBoundary = YES;
    
    //set boundary other than referenced view bounds, by setting insets
    collisionBehaviour.setTranslatesReferenceBoundsIntoBoundaryWithInsets:UIEdgeInsetsMake(20.0f, 20.0f, 20.0f, 20.0f);
    
    

  • Some variant of collision modes,  
  • collisionBehaviour.collisionMode = UICollisionBehaviorModeItems;
    
  • (saying that collision will occur only with views involved in collision behaviour, no collision with boundary)

  • collisionBehaviour.collisionMode = UICollisionBehaviorModeBoundaries;
    
    
  • (saying that views will not collide internally, only collision with boundary)

  • collisionBehaviour.collisionMode = UICollisionBehaviorModeEverything;
    
  • (saying that collision will occur with views internally as well as with boundary, this is DEFAULT mode if we do not specify externally)

    - Fortunately UICollisionBehavior comes with UICollisionBehaviorDelegate, which allows to get notifications on each collision to perform customised actions on views.

  • // implement delegate 
    @interface ViewController () <UICollisionBehaviorDelegate>
     
    @end
    
    
    //set delegate collisionBehaviour collisionBehaviour.collisionDelegate = self;
    // implement following methods depending on case - (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem >)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p; - (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem >)item1 withItem:(id<UIDynamicItem>)item2; // The identifier of a boundary created with translatesReferenceBoundsIntoBoundary or setTranslatesReferenceBoundsIntoBoundaryWithInsets is nil - (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier atPoint:(CGPoint)p; - (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier;
    // Ex. removing items on collision - (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p{ [(UIView *)item1 removeFromSuperview]; [(UIView *)item2 removeFromSuperview]; }

  • - UIAttachmentBehavior
  • UIAttachmentBehavior *attachmentBehaviour = [[UIAttachmentBehavior alloc] initWithItem:view1 attachedToItem:view2];
    
  • (Saying that view1 is attached to view2, considering no offset from center of views i.e centre point of views are taken as base)

  • CGPoint anchorpoint = CGPointMake(500, 500);
    UIAttachmentBehavior  *attachmentBehaviour = [[UIAttachmentBehavior alloc] initWithItem:view1
    attachedToAnchor:anchorpoint];
    [attachmentBehaviour setFrequency:5.0];
    [attachmentBehaviour setDamping:0.5];
    
  • (Saying that view1 is attached to point (500, 500) of referenced view, with considering centre of view1 as base)

    BreakPoint :


  • CGPoint anchorpoint = CGPointMake(500, 500);
    UIOffset offset = UIOffsetMake(40, 40);
    UIAttachmentBehavior *attachmentBehaviour = [[UIAttachmentBehavior alloc] initWithItem:view1
    offsetFromCenter:offset attachedToAnchor:anchorpoint];
    
  • (Saying that view1 is attached to point (500,500) of referenced view with considering point calculated by offset for centre point)

    - UISnapBehavior

  • CGPoint point = CGPointMake(100, 100);
    
    UISnapBehavior *snapBehaviour =
    [[UISnapBehavior alloc]initWithItem:view1 snapToPoint:point];
    
    snapBehaviour.damping = 1.0;
    
    
  • (Saying that view1 is to be snapped to point (100,100) )

    BreakPoint :
    • value of damping ranges between 0.0 to 1.0, 1.0 results in maximum oscillation

    - UIPushBehavior


  • UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[view1] mode:UIPushBehaviorModeInstantaneous];
    
    or
    
    UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[view1] mode:UIPushBehaviorModeContinuous];
    
    pushBehavior.magnitude = 5.0f;
    
    CGVector vector = CGVectorMake(0.2, 0.2);
    
    pushBehavior.pushDirection = vector;
    
    
  • (Saying that view1 is liable for instantaneous or continuous force at specified vector & magnitude applied)

    BreakPoint :
    • By default push is applied to centre of dynamic item unless offset of attachment is set.
    • default magnitude is nil equivalent to no force.
    • A continuous force vector with a magnitude of 1.0, applied to a 100 point x 100 point view whose density value is 1.0, results in view acceleration of 100 points / second² in the direction indicated by the angle or pushDirection property.
    • The default x and y values of the push direction vector are each 0.0. A value for either component of 1.0, applied to a 100 point x 100 point view, whose density value is 1.0,results in view acceleration of 100 points / second² in the positive direction for the component.

    - UIDynamicItemBehavior


  • //intiate instance with referenced view
    UIDynamicItemBehavior *dynamicBehavior = [[UIDynamicItemBehavior alloc]
    initWithItems:@[view1, view2, ...]];
    
    //set elasticity, higher elasticity makes item more bouncy
    dynamicBehavior.elasticity = 0.2;
    
    //set overall resistance, greater resistance yields sooner animation / effect stop
    dynamicBehavior.resistance = 0.5;
    
    //set friction, resistance when item collides with other items
    dynamicBehavior.friction = 0.5;
    
    //set density, mass of item - higher mass makes hard to accelerate and decelerate item
    dynamicBehavior.density = 1.0;
    
    // allow rotation, flag to enable/disable rotation
    dynamicBehavior.allowsRotation = TRUE;
    
    //set angularResistence,resistance for rotation - higher value makes rotation to stop sooner
    dynamicBehavior.angularResistance = 0.5;
    
    //add angular velocity, increase or decrease angular velocity of view by positive or negative value respectively measured in radian per second
    [dynamicBehavior addAngularVelocity:10.0 forItem:view1];
    
    //add linear velocity, increase or decrease angular velocity of view by positive or negative value respectively measured in points per second
    [dynamicBehavior addLinearVelocity:CGPointMake(150, 150) forItem:view1];
    
    

  • - Combination of behaviours
  • // Create multiple behavior objects here
    
    UIDynamicBehavior *combinedBehavior = [[UIDynamicBehavior alloc]init];
    
    [combinedBehavior addChildBehavior:gravityBehavior];
    [combinedBehavior addChildBehavior:collisionBehaviour];
    [combinedBehavior addChildBehavior:attachmentBehaviour];
    [combinedBehavior addChildBehavior:snapBehaviour];
    
    
    //add / remove item from behaviour
    [gravityBehavior addItem:view3];
    [attachmentBehaviour removeItem:view1];
    
    

  • Configure UIDynamicAnimator
  • @property (strong, nonatomic) UIDynamicAnimator *animator;
    
    _animator = [[UIDynamicAnimator alloc] 
    initWithReferenceView:self.view];
    
    // add behaviours to animator to make it live
    [_animator addBehavior: gravityBehavior];
    [_animator addBehavior: collisionBehaviour];
    [_animator addBehavior: attachmentBehaviour];
    [_animator addBehavior: snapBehaviour];
    [_animator addBehavior: combinedBehavior];
    

Conclusion : UIKit Dynamics is amazing new feature which can add life to application, by adding real world like effects and animations.

Taking imagination to next level !

Thursday 8 May 2014

Create custom code snippet in Xcode

Concern:

Xcode comes with inbuilt code snippet library to provide code skeleton to implement repeatedly used code quickly.

Fortunately we can update this list of snippets in library and add our own custom snippet which we need most of the time in our life!

 

Outcome: 

Our own custom snippet to save implementation time.
 

Description: 

we have been using many of the snippet in Xcode which makes it easier to implement code like for, while, switch and most used init code snippet.
 

Let's add our own custom code snippet, by taking example NSString method -  
+ (instancetype)stringWithFormat:(NSString *)format;

for example, with out code snippet we have to type all the syntax every time we want to implement this method, [NSString stringWithFormat:@"%@",];

Now lets add snippet for this,
  • Type statement which you want to come up automatically on calling snippet.
         [NSString stringWithFormat:@"", ];
  • Select and Add this code to snippet library.
Select code and drag it to snippet library, which can be activated by  View > Utilizes > Show Code Snippet Library or press control + option + cmd + 2 in Xcode.
On success, we will find New snippet added in library named "My Code Snippet".
  • Edit snippet
Click newly added snippet to activate snippet summery pop up.
Click on edit, which will allow to modify snippet more specifically.
  1. Title, is a snippet name by which that snippet will be called
  2. Summery, which shows brief function of snippet
  3. Platform, allows to select platform OS X or iOS or Both
  4. Language, allows to specify language snippet belongs to
  5. Completion Shortcut, allows to set shortcut for snippet
  6. Completion Scope, allows to set scope, where snippet will be available
  • For our example,


Title : strWithFormate

Summary : snippet for stringWithFormat
Platform : All
Language : Objective C

Completion Shortcut : strWithFormate
Completion Scope : All
  • Add bubble to accept values
edit snippet code by,
[NSString stringWithFormat:@"<#type#>", <#expression#>];
which adds bubble to accept values for data type and expression we are going to log.
  • Done!
    Now if we type strWithFormate and hit enter, we will get
     [NSString stringWithFormat:@"<#type#>", <#expression#>];
    and by pressing TAB, we will able to assign values to pre populated bubbles.


Conclusion:

Before: 
 



After:


 

Comments / Suggestions are welcomed!
        

Wednesday 23 April 2014

Capture & Customize Screenshots on MAC OS

In addition to large number of cool features, mac os provides convenient way to take screen shots of your screen, part of screen, active part of screen etc.

Here is how to get it:

Capture:

1) Capture part of a screen: Press Command+Shift+4, as soon cursor get changed you can start dragging mouse to select part to capture, once whole portion selected just release mouse. (it can be cancelled meantime by pressing Esc to re correct selection) On successful node you will hear typical camera shutter sound!





2) Capture Entire Screen: Press Command+Shift+3, it will capture your entire visible screen, so make sure that all content you needed in snap is visible on screen.

Notice: Above two actions saves captured screenshots on desktop by default, we will see later on how to change that default location.

3) Capture individual window: Press Command+Shift+4 then press Space, in (1)st action if you press space after updated icon, cursor will turn to camera icon which let you select individual window to capture. just click after selecting particular window to capture.


4) Capture & Copy: Press
 Command+Control+Shift+4, behaves same as (1)st action, but instead save snap directly to desktop it keeps copy to clipboard, which can be pasted to desired doc or emails.

Command+Control+Shift+3, behaves same as (2)nd action with copy to clipboard functionality.-Command+Control+Shift+4 then Space, behaves same as (3)rd action with copy to clipboard functionality.



Customize:

After changing each of below property, we need to restart SystemUIServer for the changes to take effect by firing below command:



cmd : killall SystemUIServer



  • Change type of captured image:
            cmd : defaults write com.apple.screencapture type 'type'
             (possible types are png, jpg, gif etc)



  • Change name prefix of captured image:

cmd : defaults write com.apple.screencapture name 'name'


 


  • Change default path:
       - Create New folder at desired path to save captured screen shots

        cmd : defaults write com.apple.screencapture location 'path to created new folder'




Now onwards your captured screen shots will be saved in folder you have specified.

Any suggestions / comments / queries appreciated!