Monday, March 28, 2016

A Day with "Google Analytics"


Hey Folks,

Today got a chance to work on with Google Analytics.
Amazing...
Loved playing with it.

Presenting basic info so that you guys can start playing with it too within your iOS Apps :)

Let's Start..


A) Accounts & Guides

  • Sign up with an email id
  • Provide an Account name & App name that you want to work with
  • Agree with terms & conditions and you will be provided a TRACKING ID
  • Get your iOS Starting Guide that will help you in adding analytics to your app and screens : “https://developers.google.com/analytics/devguides/collection/ios/v3/"
  • You get a sample app to to start with





B) App Info

  • Analytics uses CocoaPods to install and manage dependencies.
  • Remember to Choose between Objective-C or Swift
  • Create / Choose App Name
  • Download googleServices-info.plist file and drag into your root folder

 
C) CocoaPods 
  • Create a text file named as podfile with following content :
platform :ios, ‘9.1’ 
use_frameworks! 

target ‘PullToRefresh’ 
   do  pod 'Google/Analytics' // you can mention all dependencies here
 end
  • Open Terminal and write pod install
  • If you prefer not to use CocoaPods to manage library dependencies, you can download and directly use the Google Analytics Services SDK.


D) Project

  • Add Analytics inside AppDelegate #import <Google/Analytics.h>
  • Then, override the didFinishLaunchingWithOptions method to configure GGLContext
  • Here you’ll send a named screen view to Analytics whenever the user opens or changes screens on your app. Open a View Controller that you'd like to track, or if this is a new application, open the default view controller.

- (void)viewWillAppear:(BOOL)animated
{
    id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];
    [tracker set:kGAIScreenName value:@"MAIN SCREEN"];
    [tracker send:[[GAIDictionaryBuilder createScreenView] build]];
}


Note: You can add tracking code to every UIViewController that represents a screen, whether shown to your user imperatively (via code) or via storyboard. Set a name inside everyUIViewController if you want to differentiate between screen views for your app in Analytics. All activity recorded on the shared tracker sends the most recent screen name until replaced or cleared (set to nil).


E) View the Status in dashboard











Hope it helps :)





Tuesday, March 8, 2016

Error : "Cannot Connect to iTunes Store"


Hi All,


Many a times its seen that on iPod / iPhone / iPad users see an error
"Cannot Connect to iTunes Store".





Found some workarounds that may prove helpful in fixing this issue...

1) Check your internet connection : This may be the basic cause behind the issue

2) Firewall Security : Cross check your firewall security as this may also lead to this issue

3) Preference Changes :

   a) Connect your device with a MAC.
   b) Open Preferences from Top menu /  [cmd + ,]



   c) Click on Parental Control Preferences
   d) Disable iTunes Store [allow access to iTunes U]
   e) Click on OK



   f) Now Enable iTunes Store [allow access to iTunes U]
   g) Click on OK



Friday, October 23, 2015

Socialize through iOS Apps


Hi all,

Almost every app these days wants to socialize through Twitter, Facebook etc. and share there experience or contents of the apps.

With every changing iOS the process of Integration keeps on changing.
From Basic Authentication to Graph API to SLComposeViewController

Since iOS 8.0 we are using SLComposeViewController as Twitter and Facebook accounts are by default added with OS & you just need to setup the account.

So let's start...

1) Start by creating a single view based sample app


2) Name project as



3) Project navigator will look like this after adding Social .framework



4) Add following components in your storyboard file. 
A text field that takes input from user and buttons to share via Facebook and Twitter 




5) Now lets dig in some code by importing the social framework


6) Add text field and connect IBOutlet



7) Sending tweet on button click



How it works : 
 a) First of all we check the availability of twitter account on the device/simulator
 b) Create object of SLComposeViewController for service type Twitter
 c) Text to be shared : setInitialText method
 d) URL to be shared : addURL
 e) Image to be shared : addImage
 f) After setting required values we present the view controller


8) Sharing on facebook on button click




How it works :
 a) First of all we check the availability of facebook account on the device/simulator
 b) Create object of SLComposeViewController for service type Facebook
 c) Text to be shared : setInitialText method
 d) Image to be shared : addImage
 e) After setting required values we present the view controller

Now try this and see the result 
:)


Thursday, September 24, 2015

Jenkins on Mac...


Hi Guys,

Now a days Continuous Integration [CI] has become an eternal part of software development.
This allows user to :
a) Integrate and share their code in a repository
b) Make error checks in builds
c) Automatic generation of builds [includes packaging and signing]
d) Generating artifacts

To enjoy the prospects of CI we are going to use a tool named JENKINS.
Jenkins is a server based system which provide CI services

SCM tools with which Jenkins can be integrated with are:
Git, Mercurial, SVN, CVS etc..


Lets first start with configuring Jenkins on MAC machine.
You can use OSX installer with nice GUI or go ahead with Homebrew

I will prefer to go ahead with Homebrew so here we go

1) Open Terminal and go ahead with below mentioned commands

********** HOMEBREW SETUP **********



swati:~ admin$ 
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/universal-darwin14/rbconfig.rb:213: warning: Insecure world writable dir /usr in PATH, mode 040777

==> This script will install:
/usr/local/bin/brew
/usr/local/Library/...
/usr/local/share/man/man1/brew.1

Press RETURN to continue or any other key to abort
==> /usr/bin/sudo /bin/mkdir /Library/Caches/Homebrew

WARNING: Improper use of the sudo command could lead to data loss
or the deletion of important system files. Please double-check your
typing when using sudo. Type "man sudo" for more information.

To proceed, enter your password, or type Ctrl-C to abort.

Password:
==> /usr/bin/sudo /bin/chmod g+rwx /Library/Caches/Homebrew

==> Downloading and installing Homebrew...
remote: Counting objects: 3744, done.
remote: Compressing objects: 100% (3579/3579), done.
remote: Total 3744 (delta 40), reused 567 (delta 28), pack-reused 0
Receiving objects: 100% (3744/3744), 3.14 MiB | 240.00 KiB/s, done.
Resolving deltas: 100% (40/40), done.
From https://github.com/Homebrew/homebrew
 * [new branch]      master     -> origin/master
HEAD is now at 98c28ae gst-plugins-bad: can optionally use srtp

==> Installation successful!

==> Next steps
Run `brew help` to get started

********** JENKINS DOWNLOAD **********


swati:~ admin$ brew install jenkins

After installing Jenkins Homebrew provides you some useful tips as well

==> Downloading https://homebrew.bintray.com/bottles/jenkins-1.629.yosemite.bottle.tar.gz
######################################################################## 100.0%

==> Pouring jenkins-1.629.yosemite.bottle.tar.gz
==> Caveats
Note: When using launchctl the port will be 8080.

To have launchd start jenkins at login:
  ln -sfv /usr/local/opt/jenkins/*.plist ~/Library/LaunchAgents

Then to load jenkins now:
  launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

Or, if you don't want/need launchctl, you can just run:
  jenkins

==> Summary
🍺  /usr/local/Cellar/jenkins/1.629: 6 files, 61M

********** UPDATE JAVA **********


swati:~ admin$ jenkins @ dev > sudo touch /Library/LaunchDaemons/org.jenkins-ci.plist

Jenkins requires Java7 or later, but you are running 1.6.0_65-b14-466.1-11M4716 from /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
java.lang.UnsupportedClassVersionError: 50.0
at Main.main(Main.java:90)

Remember to update your Java to latest to enjoy best features

********** LAUNCH DAEMONS **********


swati:~ admin$ sudo launchctl load -w /Library/LaunchDaemons/org.jenkins-ci.plist
Password:
/Library/LaunchDaemons/org.jenkins-ci.plist: Path had bad ownership/permissions

swati:~ admin$ sudo chmod 600 /Library/LaunchDaemons/org.jenkins-ci.plist
swati:~ admin$ sudo chown root /Library/LaunchDaemons/org.jenkins-ci.plist
swati:~ admin$ sudo launchctl load /Library/LaunchDaemons/org.jenkins-ci.plist

********** org.jenkins.plist **********


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>Jenkins</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/bin/java</string>
            <string>-jar</string>
            <string>/usr/local/Cellar/jenkins/1.414/lib/jenkins.war</string>
        </array>
        <key>OnDemand</key>
        <false/>
        <key>RunAtLoad</key>
        <true/>
        <key>UserName</key>
        <string>jenkins</string>
    </dict>
</plist>

If user has a different name remember to add that in plist else it will run via System root


After all this you can reboot your MAC or type below mentioned command in browser
http://localhost:8080

yippieeee.... see how it looks



Now you are ready to go ahead...
Create your jobs , download plugins, integrate SCM, automate builds & Enjoy..

Hope you enjoyed the first step.
Next step will be posted soon
:)













Thursday, September 17, 2015

Pull To Refresh Tutorial


Hi all,

I have heard and seen this feature many a times while browsing through apps.
Liked it very much.

So i decided why not to try out this feature and share my experience with you all.
Hope somebody finds help with this.

Lets start....


1) Create a Project "Single View Application"



2) Set a product name : PullToRefresh


3)  Open the storyboard file and add UITableView to the provided view

Connect TableView Outlets, Delegates and Datasources


4) Under UITableView add UITableViewCell. 

This is a Static cell with Identifier as "CellIdentifier" and with only "Title" property.


5) Now comes the Controller part

5.1) Open ViewController.h and add properties for


@interface ViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
{
    
}

@property(nonatomic, strong)IBOutlet UITableView   *dataTable;
@property(nonatomic, strong)NSArray                        *fruitsArray;
@property(nonatomic, strong)UIRefreshControl          *refreshControl;

@end


5.2) Open ViewController.m and make dough from ingredients :P


- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.fruitsArray = [[NSArray alloc] initWithObjects:
                                 @"Apple", @"Orange", @"Mango" , @"Grapes", @"Banana", nil];
    
    self.refreshControl = [[UIRefreshControl alloc] init];

    [self.refreshControl addTarget:self
                                           action:@selector(refreshControlValueChanged) 
                         forControlEvents:UIControlEventValueChanged];

    self.refreshControl.tintColor = [UIColor redColor];

    [self.dataTable addSubview:self.refreshControl];
}



- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;

}



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.fruitsArray.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    
    cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier" 
                                                                   forIndexPath:indexPath];
    
    cell.textLabel.text          = self.fruitsArray[indexPath.row];
    cell.textLabel.textColor = [UIColor blueColor];

    return cell;

}



- (void)refreshControlValueChanged
{
    self.fruitsArray = [self.fruitsArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    
    [self performSelector:@selector(updateTable)
                     withObject:nil
                      afterDelay:1];
}



- (void)updateTable
{
    [self.dataTable reloadData];
    
    [self.refreshControl endRefreshing];
}


6) Now run your App and see a list of fruits that are not sorted.



7) Drag your table & see the spinning wheel


8) Now see the refreshed data...



Happy Coding....
Enjoy :)




Thursday, May 8, 2014

Ant on Mac



Hey,

For the first time i tried working with Ant on Mac, so thought of sharing some stuff..

1) Firstly ant is available by default with Mac.
2) Now lets know the current version

admin$ ant -version
Apache Ant(TM) version 1.8.1 compiled on April 29 2014

3) Wanna update to latest

Download link : http://ant.apache.org/bindownload.cgi

4) Create a local directory in usr if not exists

admin$ sudo mkdir -p /usr/local

5) Copy the downloaded folder to the newly created usr/local folder

admin$ sudo cp -rf apache-ant-1.9.4 /usr/local/apache-ant

6) Set global variable PATH

admin$ export PATH=/usr/local/apache-ant/bin:"$PATH"

7) Echo global variable PATH

admin$ echo 'export PATH=/usr/local/apache-ant/bin:"$PATH"' >> ~/.profile

8) Now lets know the updated version

admin$ ant -version

Apache Ant(TM) version 1.9.4 compiled on April 29 2014


Enjoy :)

NSPredicates : A handy tool


Hi all,

Searching and sorting is an utmost important part of any iOS app, i believe so...

Lets try to use a simpler way provided by Apple named NSPredicates that make development easier..
:) :)

We have numerous situations where NSPredicates play an important role, very few are here..

Ohhh...list may increase
:)

1) Filter an array of objects

Basic
  •     I have an array : arrCustomObjects 
  •     It contains objects of type : CustomObject
  •     Properties of CustomObject : iDname
  •     Data :
    • [@"32"   , @"Maria"] 
    • [@"51"   , @"John"] 
    • [@"100" , @"Stuart"] 
    • [@"500" , @"Barbie"]

What to do
  •  Search object from arrCustomObjects where id = @"32" 

How To do
  
 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"iD == %@", @"32"];
 NSMutableArray *filtered = (NSMutableArray*)[arrCustomObjects 
                                       filteredArrayUsingPredicate:predicate];

  if(filtered.count>0)
     CustomObject *customObject  = [filtered objectAtIndex:0];


====================================================================


2) Filter in form of Sets

    What to do
    • Filter array that contains only my favorite female friends

    How To do

     NSArray *girlsArray = [NSArray arrayWithObjects:@"Barbie",@"Maria"];
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name IN %@", girlsArray];
     NSMutableArray *filtered = (NSMutableArray*)[arrCustomObjects 
                                           filteredArrayUsingPredicate:predicate];

      if(filtered.count>0)
        CustomObject *customObject  = [filtered objectAtIndex:0];


    ====================================================================


    3) Filter using Regular Expressions

    What To do
    • Email ID validation using regex

    How To do

     NSString *emailRegex =
        @"^(?i)(?:(?:https?|ftp):\\/\\/)?(?:\\S+(?::\\S*)?@)?(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?$";

        NSPredicate *regextest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",  emailRegex];
        
        if ([regextest evaluateWithObject: url] == YES
            NSLog(@"URL is valid!");
        else 
            NSLog(@"URL is not valid!");



    Enjoy the ease :) :)