Saturday 24 October 2015

Exploring newly released Apple tvOS - Sept' 2015

On 9th September 2015, Apple has revealed anticipating new Apple tv with tvOS and access to developers with tvOS SDK.

It's been expected to have not very differences between iOS sdk and tvOS sdk, so iOS developers likely to start with tvOS sdk development right away.

Here are some more brief details:


New Apple tv known as Apple TV 4th generation comes with,

  • tvOS 9
  • 64-bit A8 processor
  • 32GB or 64GB of storage
  • 2GB of RAM
  • 10/100Mbps Ethernet
  • WiFi 802.11a/b/g/n/ac
  • 1080p resolution
  • HDMI
  • TV remote

For tvOS SDK development, OS X 10.10.4 & above and Xcode 7.1 & above which comes with apple tv / remote simulator inbuilt.

There are two possible ways to develop app for tvOS:
  1. Traditional / Custom Apps 
  2. Client-server / TVML Apps


Traditional / Custom Apps

  • Very much similar to iOS app development
  • Involves similar UIControls as of iOS sdk, like UITableView, UICollectionView
  • Supports Storyboard/Xib with Autolayout.

Client-server / TVML Apps

  • Includes new tvOS frameworks
  • Use of newly add languages kits, 
  1. TVML - (Television Markup Language)
  2. TVJS - Similar to traditional javascript, which will work with TVML to feed.
  3. TVMLkit - Provides a way to incorporate JavaScript and TVML elements 
 Reference:
https://developer.apple.com/library/prerelease/tvos/documentation/LanguagesUtilities/Conceptual/ATV_Template_Guide/TextboxTemplate.html#//apple_ref/doc/uid/TP40015064-CH2-SW8

Apple provides well number of predefined templates for TVML,

Reference : https://developer.apple.com/library/prerelease/tvos/documentation/LanguagesUtilities/Conceptual/ATV_Template_Guide/index.html#//apple_ref/doc/uid/TP40015064-CH41-SW1


Some new interesting elements to look are,

  • Top Shelf - For each tvOS app, Top Shelf is to be bind to highlight content of app which will be displayed on Top area of Apple TV.
  • Parallax Images - As there is no human finger touch possible, there is a way to highlight current active item with animation which will be know as Focus item. To allow this focus event parallax image is to be used which is also supported by UIImageView natively.

Similar to iOS development there are Human guidelines for tvOS, listed some of them here:

  • Single user access to app is now changed to shared experience, as multiple users going to watch same app same time. Keep this is consideration.
  • Users going to be at more far distance than iOS apps, so font sizes/color should be taken care.
  • TV remote comes with predefined buttons and touch area, so bother to use them all.

    so on. well explained here:
Reference : https://developer.apple.com/tvos/human-interface-guidelines/


Resource Limitation

There are some limitation to keep in consideration like:

  • Maximum size of an Apple TV app is limited to 200MB. So if app is expected to go beyond this limit App slicing, On demand resources will be there to cure. 
  • No persistent local cache available, so data is to be stored on backend side, iCloud or using cloudKit depending on requirement.

This's it for now. There is going to be lot more changes & updates over future of Television and tvOS.

Stay updated with Reference link:


























 

Sunday 13 September 2015

MKMapview : get radius of map in Swift

Referring : http://jslim.net/blog/2013/07/02/ios-get-the-radius-of-mkmapview/

Here is Swift conversion of getRadius(),

// get center coordinate
let centerCoor = self.mapView.centerCoordinate
let centerLocation = CLLocation(latitude: centerCoor.latitude, longitude: centerCoor.longitude)

// get top left coordinate
let topLeftCoor = self.mapView.convertPoint(CGPointMake(0,0), toCoordinateFromView: self.mapView)
let topLeftLocation =  CLLocation(latitude: topLeftCoor.latitude, longitude: topLeftCoor.longitude)

 // get top right coordinate
 let topRightCoor = self.mapView.convertPoint(CGPointMake(self.mapView.frame.size.width,0), toCoordinateFromView: self.mapView)
 let topRightLocation = CLLocation(latitude: topRightCoor.latitude, longitude: topRightCoor.longitude)

// the distance from center to top left
let hypotenuse:CLLocationDistance = centerLocation.distanceFromLocation(topLeftLocation)

// half of the distance from top left to top right
let x:CLLocationDistance = topLeftLocation.distanceFromLocation(topRightLocation)/2.0

// what we want is this
let y:CLLocationDistance = sqrt(pow(hypotenuse, 2.0) - pow(x, 2.0)) //meter

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 !