Thursday 9 August 2012

How do you make images wobble like on the iPhone home screen?


If you want to make your views, images, etc. wobble, like the home screen, you could do something like this:
    CGAffineTransform leftWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(-15.0));
    CGAffineTransform rightWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(15.0));

    view.transform = leftWobble;  // starting point

    [UIView beginAnimations:@"wobble" context:view];
    [UIView setAnimationRepeatAutoreverses:YES];
    [UIView setAnimationRepeatCount:5]; // adjustable
    [UIView setAnimationDuration:0.125];
    [UIView setAnimationDelegate:self];
    view.transform = rightWobble; // end here & auto-reverse
    [UIView commitAnimations];
You would also need to add this define:
#define RADIANS(degrees) ((degrees * M_PI) / 180.0)

Thursday 17 May 2012

Niche Technologies- iOS 6: Apple drops Google Maps, debuts in-house ‘Maps’ in 3D mode

Apple has an incredible headline feature in development for iOS 6: a completely in-house maps application. Apple will drop the Google Maps program running on iOS since 2007 in favor for a new Maps app with an Apple backend. The application design is said to be fairly similar to the current Google Maps program on the iPhone, iPad, and iPod touch, but it is described as a much cleaner, faster, and more reliable experience.

While Apple has always had full control of the actual iOS Maps application design, the backend has belonged to Google. That will change with iOS 6 thanks to their purchases of Placebase, C3 Technologies, and Poly9; acquisitions that Apple has used to create a complete mapping database.

Now that the application is fully in-house, it is being referred to simply as “Maps” (some people call the current version Google Maps because of the backend). We reported prior to the launch of iOS 5 that Apple and Google had extended their Maps deal, and now it is obvious when that deal ends.

Signifying the application’s complete re-write is a new logo for iOS Maps: it is basically a redesigned version of the current iOS Maps icon with a view of Apple’s 1 Infinite Loop Campus, but redrawn with a new color scheme. Apple’s replacement for Google Street View will likely also be an in-house solution. C3 Technologies worked on street view capability as shown in the photo above.

The most important aspect of the new Maps application is a powerful new 3D mode. The 3D mode does not come enabled by default, but users simply need to click a 3D button that is conveniently and visibly stored in the app. Perhaps under the fold like the current traffic, pin, and map view buttons. This 3D mode is said to essentially be technology straight from C3 Technologies: beautiful, realisitic graphics based on de-classified missile target algorithms.

Wednesday 16 May 2012

Niche technologies-IOS 6 FEATURES: 10 NEW FEATURES IN NEW IOS 6

"We’re thrilled with sales of over 35 million iPhones and almost 12 million iPads in the March quarter … The new iPad isoff to a great start, and across the year you’re going to see a lot more of the kind of innovation that only Apple can deliver.”


Here are the IOS 6 features:

1. Siri support for iPad 3, 2, iPhone 5, iPhone 4S devices
2. New Notification Center interface
3. Facebook Integration
4. IM Support in Messages
5. iPhone / iPod Touch Multitask Gestures
6. New 3D Maps
6. GPS integrated into 3D Maps
7. AirDrop for iOS
8. New iCloud with Notes,iPhoto Album, Reminders
9. Ability to delete default apps
10.New Notification banners

Niche Technologies- how to create news stand app in iOS Newsstand

A new way to distribute magazines

Since the beginning of the iPad era, one of the most appreciated features in the tablet has been the possibility to read magazines and newspapers. Practically all major publishers (and a lot of minor) have created their own magazine and newspaper apps and the first in-house experiments have grown with increasingly better applications. Besides a lot of software companies followed this path, the major ones by providing their own publishing system and a lot of other start-ups simply exist to offer their services to create custom apps for their customers.
While Apple in the time applied several regulations, e.g. limiting the possibility to purchase issues outside the In App Purchase system, or introducing a subscription mechanism, it behaved before iOS 5 mainly as an observer, limiting its own participation in the app arena with the iBooks app, dedicated to books. But with iOS 5 we assisted to the first important step of Apple towards introducing a coherent methodology for magazine and newspapers applications, by providing a feature, called Newsstand, and a developer a framework, called Newsstand Kit, that provides a common hub for all magazine and newspapers apps and a new completely different way to interact with an application. It is important to highlight the fact that each developer or publisher can still present the content in the preferred way, Apple currently doesn’t provide any specific solution for content presentation, apart the generic HIG guidelines and of course the moltitude of services aimed to present content (PDF, images, media). We will not be surprised if in the next future Apple will change its SDK rules by requiring all apps to be Newsstand compatible to be eligible for the App Store.
So how a Newsstand app differ from other apps? first of all the icon presentation: a Newsstand compatible application will not see anymore its icon in the springboard, but a different and customizable icon will be shown in a special icon group called Newsstand. This icon will not be the typical square icon but instead it will be the cover of a magazine and furthermore this cover can be customized and keep aligned with the current latest issue available in the store.
Besides an app that decides to live behind the Newsstand umbrella will benefit of background downloading of new issues and the device can be informed, and proceed with automatic download eventually, of new issue by receiving special push notifications.
In order to achieve these, and several other features, an application must take in consideration several aspects, from icon management, to push notifications, inside the code and up to the iTunesConnect definition. In this tutorial we’ll try to build a simple Newsstand compatible app from scratch.

Application setup

Basic app

Prerequisite to follow this tutorial is to have XCode 4.2 and iOS 5 SDK installed. Even if most of the new features can be tested directly in the iPhone Simulator, the push notifcations and In App Purchase part of this tutorial require an iOS Developer Account.
So let’s start with a simple approach: open XCode and create a new “Empty” project, feel free to choose the target device between iPhone and iPad. Then create a new view controller, call it StoreViewController, and inside the app delegate instantiate a new object for this controller and put it inside a new navigation controller. Finally define a new icon, add it inside your project and run it in the simulator. The obvious result will be something like this, with our icon in the springboard and the app showing an empty screen:

Enabling for Newsstand

Now we need to instruct the system that we want our app to be compatible with Newsstand. The first requirement is to create an icon specific for Newsstand: this icon is different from the usual app icons at it must appear as a cover of our magazine. In our case we prepared a simple 130 x 190 px icon and imported in XCode. Besides we need to add or modify three new fields in the application Info.plist. The first new field is UINewsstandapp that must added and set to YES. The second is to create or modify the CFBundleIcons dictionary item by adding the Newsstand icons. Finally, if we want to support background download of new assets, we need to add the newsstand-code in the application background capabilities. The newly added plist items will appear in xml syntax as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 <key>CFBundleIconFiles</key>
 <array>
  <string>icon.png</string>
  <string>icon@2x.png</string>
 </array>
 <key>CFBundleIcons</key>
 <dict>
  <key>CFBundlePrimaryIcon</key>
  <dict>
   <key>CFBundleIconFiles</key>
   <array>
    <string>icon.png</string>
    <string>icon@2x.png</string>
   </array>
   <key>UIPrerenderedIcon</key>
   <false/>
  </dict>
  <key>UINewsstandIcon</key>
  <dict>
   <key>CFBundleIconFiles</key>
   <array>
    <string>icon_newsstand.png</string>
   </array>
   <key>UINewsstandBindingEdge</key>
   <string>UINewsstandBindingEdgeLeft</string>
   <key>UINewsstandBindingType</key>
   <string>UINewsstandBindingTypeMagazine</string>
  </dict>
 </dict>
 <key>UINewsstandApp</key>
 <true/>
 <key>UIBackgroundModes</key>
 <array>
  <string>newsstand-content</string>
 </array>
Note that the CFBundleIconFiles section still exists for backward compatibility but in the new iOS 5 syntax it has been copied inside the CFBundlePrimaryIcon section of CFBundleIcons. These new settings appear in XCode as in the figure below, we have displayed here the values instead of the key names for the Info parameters, just to let you see how the new icon files structure is marked with an iOS 5 tag:
Let’s build and run the app again, the result will appear as below: our original icon has been removed from the springboard and replaced with the cover-like icon inside the Newsstand group; if we open the group then we’ll be able to click in our app icon to move it to foreground. Note that the classic style icons are still required by the system, as they are used in spotlight, for push notifications, in the App Store.

Displaying and downloading magazines

It’s time to now to start writing some code. The first operation is to link our project to the NewsstandKit framework. Don’t forget to import the NewsstandKit headers in the classed that need it:
1
#import <NewsstandKit/NewsstandKit.h>
For simplicity we suppose that the list of available issues (all free) is inside a plist file that can be downloaded from the publisher server. So for the purpose we define a class called Publisher which will take care of downloading the current list of items. As soon as the items have been downloaded they will be presented to the user. The plist is quite simple: it is an array of dictionaries, each dictionary represents an issue by providing the identifying name (unique), the title (visible to the user), the publishing date and the URLs for thumbnail cover image and content (PDF file) downloading.
1
2
3
4
5
6
7
8
9
10
11
12
 <dict>
  <key>Name</key>
  <string>Magazine-0</string>
  <key>Title</key>
  <string>Magazine Issue 0</string>
  <key>Date</key>
  <date>2011-10-01T06:00:00Z</date>
  <key>Cover</key>
  <string>http://www.viggiosoft.com/media/data/blog/newsstand/magazine-0.png</string>
  <key>Content</key>
  <string>http://www.viggiosoft.com/media/data/blog/newsstand/magazine-0.pdf</string>
 </dict>
At startup the StoreViewController will download the issues list from the server, parse it and will present this list in the table. Concurrently it will download the covers thumbnails and will show them in the table. This is quite typical code still not related to Newsstand so I will not explain the details. At the end of the loading the view will present itself in this way. You will simply the list of items together with their cover and a hint that invites to tap for download.
Now one of the most interesting things about the Newsstand framework is that the system manages for us the issues library by giving us access to a shared class called NKLibrary. Once we get the library, we’ll iterate through our issues list downloaded from the server and we will add our issues into the shared NK library. This can be done using the NKLibrary’s addIssueWithName:date: that needs as input only the unique name and publishing date for the issue and will return an NKIssue instance. Note that this data is only a subset of the data we need for our application (our simple issue dictionary contains in addition the display title, and the content and cover URLs), so we’ll need to maintain our own list and keep it in sync with the NKLibrary content. Also consider that once an issues has been added it will be permanently saved into the system NK library repository, even on subsequent runs of the application, this is because the operating system needs to maintain the status of all of our issues: this means that will be forbidden to add an issue with the same name twice, doing this will raise an exception and will crash the app. Going back to our code, concurrently with the downloading of the issues from the publisher’s server we’ll update the NKLibrary issues by adding only the ones not added yet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Publisher.m
// "issues" is the array of issues downloaded from the publisher's server
-(void)addIssuesInNewsstand {
    // shared NKLibrary instance
    NKLibrary *nkLib = [NKLibrary sharedLibrary];
    // we iterate through our issues and add only the one not in the NK library yet
    [issues enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString *name = [(NSDictionary *)obj objectForKey:@"Name"];
        NKIssue *nkIssue = [nkLib issueWithName:name];
        if(!nkIssue) {
            nkIssue = [nkLib addIssueWithName:name date:[(NSDictionary *)obj objectForKey:@"Date"]];
        }
    }];
}
Note the way we manage the static information coming from the publisher with the dynamic information present in the NKLibrary. In particular we can link a given publisher’s issue with the corresponding NKIssue by the unique name identifier, thanks to the fact that NKLibrary exposes the method:
1
- (NKIssue *)issueWithName:(NSString *)name
Thanks to this link we are able to populate our table cells with a mix of static and dynamic information. This cell view infact other than providing the Title information (retrieved from the publisher’s list) will show an action label that will be “TAP TO DOWNLOAD” or “TAP TO READ” according to the fact that the magazine has been downloaded or not. Besides if the issue is under downloading we’ll show instead of the “TAP” message a bar that will show the download progress. We know the magazine status by checking the NKIssue status property, which has three possible values: NKIssueContentStatusAvailable, NKIssueContentStatusDownloading or NKIssueContentStatusNone.

Downloading an issue

Let’s explore now how issue download happens while the app is in foreground. This will be done by introducing a new class, called NKAssetDownload. First of all a few important concepts:
  1. each issue is composed of a single asset (as in this case: we just have a PDF file) or multiple assets (e.g.: pdf, images, videos, thumbnails); in the latter case the recommendation is to pack all files in a single zip and then download this single file.
  2. the final local destination path is established by the Newsstand framework and consist of a system assigned directory inside the app sandbox cache, so compliant with iCloud requirements
  3. this local destination can be retrieved from the NKIssue’s contentURL property
  4. we can build our final destination path by appending to the contentURL path our own file name, as we did in the piece of code below:
  5. 1
    2
    3
    
    -(NSString *)downloadPathForIssue:(NKIssue *)nkIssue {
        return [[nkIssue.contentURL path] stringByAppendingPathComponent:@"magazine.pdf"];
    }
    
So in our code when a table cell is tapped and the corresponding issue has not been downloaded yet we need to start the download. The code below retrieves the NKIssue object, then ask the Publisher instance for the original server URL where to download the issue (in a more complex app this request will require, for example, the In App Purchase receipt for validation before returning the download URL) and finally we’ll ask NKIssue for a new NKAssetDownload object that will be queued for downloading. Note that we store in the NKAssetDownload userInfo property the actual index of the table view cell. This is required as during our download we want to update the progress bar that can be retrieved only by querying for the right cell in the table. Even if this userInfo is a dictionary its storage is limited to plist-valid objects only, the penalty will be a runtime exception, so be careful!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    // let's retrieve the NKIssue
    NKLibrary *nkLib = [NKLibrary sharedLibrary];
    NKIssue *nkIssue = [nkLib issueWithName:[publisher nameOfIssueAtIndex:index]];
    // let's get the publisher's server URL (stored in the issues plist) 
    NSURL *downloadURL = [publisher contentURLForIssueWithName:nkIssue.name];
    if(!downloadURL) return;
    // let's create a request and the NKAssetDownload object
    NSURLRequest *req = [NSURLRequest requestWithURL:downloadURL];
    NKAssetDownload *assetDownload = [nkIssue addAssetWithRequest:req];
    [assetDownload setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInt:index],@"Index",
                                nil]];
     // let's start download
    [assetDownload downloadWithDelegate:self];
In the code above we set the assetDownlaod delegate property to self. This allows the view controller to monitor the download progress implementing the NKURLConnectionDownloadDelegate which is an extension (or a specialization) of the already known NSURLConnectionDelegate protocol. This protocol defines three methods:
1
2
3
 connection:didWriteData:totalBytesWritten:expectedTotalBytes:
 connectionDidResumeDownloading:totalBytesWritten:expectedTotalBytes:
 connectionDidFinishDownloading:destinationURL:
The first method allows us to monitor the progress status of our download. Thanks to the connection’s newsstandAssetDownload property we can retrieve the NKAssetDownload associated to the connection and then we’ll be able to retrieve the table view cell associated to this asset’s magazine thanks to the Index property we previously stored in the userInfo dictionary:
1
2
3
4
5
6
7
8
9
10
11
12
-(void)connection:(NSURLConnection *)connection didWriteData:(long long)bytesWritten totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes {
    [self updateProgressOfConnection:connection withTotalBytesWritten:totalBytesWritten expectedTotalBytes:expectedTotalBytes];
}
-(void)updateProgressOfConnection:(NSURLConnection *)connection withTotalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes {
    // get asset
    NKAssetDownload *dnl = connection.newsstandAssetDownload;
    UITableViewCell *cell = [table_ cellForRowAtIndexPath:[NSIndexPath indexPathForRow:[[dnl.userInfo objectForKey:@"Index"] intValue] inSection:0]];
    UIProgressView *progressView = (UIProgressView *)[cell viewWithTag:102];
    progressView.alpha=1.0;
    [[cell viewWithTag:103] setAlpha:0.0];
    progressView.progress=1.f*totalBytesWritten/expectedTotalBytes;
}
While the implementation of the progress method is optional, all in all we are not strictly required to monitor the progress status, the next two methods must be implemented. One method informs us that the downloading of an asset has been resumed and that we can update our progress; we’ll see this detail later, for the moment we behave exactly as in the method above, by updating the progress bar. The other method instead needs to be implemented as it informs the delegate that the download has finished and that the downloaded content (currently stored in a temporary area) can be moved to its final location (that we know is given to us witth the contentURL property of NKIssue. Our implementation then moves the new content to its final location and refresh the table by removing the progress bar and replacing with the new “TAP TO READ” message:
1
2
3
4
5
6
7
8
9
10
11
-(void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL {
    // copy file to destination URL
    NKAssetDownload *dnl = connection.newsstandAssetDownload;
    NKIssue *nkIssue = dnl.issue;
    NSString *contentPath = [publisher downloadPathForIssue:nkIssue];
    NSError *moveError=nil;
    if([[NSFileManager defaultManager] moveItemAtPath:[destinationURL path] toPath:contentPath error:&moveError]==NO) {
        NSLog(@"Error copying file from %@ to %@",destinationURL,contentPath);
    }
    [table_ reloadData];
}
If your issue is made of multiple assets, of course you can queue them all. In such case other than monitoring the single assets downloads (at least to copy them in their final destination directory) you may be interested to know when all queued assets download have finished. In such case you can register to the NKIssueDownloadCompletedNotification that will be posted (without userInfo) by the interested issue.
An interesting point we would like to highlight is the way we’re downloading the magazine covers for our table. If you have a look at the code, you will see that as soon as the controller needs to provide the image for the table cell view, it will query the Publisher class sending the index of the cover to be retrieved and a completion handler block that will be executed by the publisher instance. The publisher instance infact does an async download of the cover data and when done runs the block that will update the table. This works perfectly but it can be done in a different way by using the Newsstand capabilities: infact if you consider that the image cover is, after all, an issue asset, you can still add this asset request to the system and in the connection delegate you can re-load the affected cell with the new item. We didn’t cover this aspect in this code, as we preferred to focus on the content download, but you may consider for your applications this approach which is more elegant.

Background downloading

One of the most interesting features of Newsstand is that once an asset downloading has started it will continue even if the application is suspended (that is: not running but still in memory) or it is terminated. Of course during while your app is suspended it will not receive any status update but it will be woken up in the background in order to process the download completion operation: in this case you will have the chance to copy the downloaded asset in its final destination or, for zipped content, to unpackage it.
In case that app has been terminated while downloading was in progress, the situation is different. Infact in the event of a finished downloading the app can not be simply woken up and the connection delegate finish download method called, as when an app is terminated its App delegate object doesn’t exist anymore. In such case the system will relaunch the app in the background and then the UIApplicationDelegate application:didFinishLaunchingWithOptions: will be called with the UIApplicationLaunchOptionsNewsstandDownloadsKey key in the launchOptions dictionary. If defined, this key will contain the array of all asset identifiers that caused the launch. From my tests it doesn’t seem this check is really required if you reconnect the pending downloading as explained in the next paragraph.
Another important thing to consider is that each time the app is relaunched, we need to check for existing pending downloads. If there any then we must reconnect them to the download delegate. If we don’t do this, then all not-reconnected downloads are considered abandoned by the system and they will be cancelled:
1
2
3
4
5
    // inside the app delegate's application:didFinishLaunchingWithOptions: and after the view controller has been initialized
    NKLibrary *nkLib = [NKLibrary sharedLibrary];
    for(NKAssetDownload *asset in [nkLib downloadingAssets]) {
        [asset downloadWithDelegate:store];
    }

New content notification

One of the most interesting features related to Newsstand it the possibility to receive push notifications when new content is available: this means that the app will be able in background to automatically download the new content and update the cover as appears inside the Newsstand group.
The implementation of this feature requires some preliminary setup. I will not enter in the detail of the operations required to have push notification working in your app, so I will limit myself to summarize the required steps:
  • In the developer portal, create a Bundle ID specific for your app, without wildcards
  • In the developer portal, enable the Bundle ID for push notifications and create the server certificate
  • Install the server certificate in your push notification servers. If you don’t have one, you can refer to external services such as Urban Airship (which is free for development and free up to some limit for production)
  • Check in your Info.plist that the Bundle ID in your code is the same that you used in the developer portal
  • In the developer portal create a provisioning profile for the app and use it when compiling and installing the app in your device
It is initially suggested to test if push notifications are working. So register the app for receiving basic push notifications and try from your push server to send a message. If you get it you’re ready to continue with Newsstand integration.
1
2
3
4
5
    // APNS standard registration to be added inside application:didFinishLaunchingWithOptions:
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                         UIRemoteNotificationTypeSound |
                                                         UIRemoteNotificationTypeAlert)];
}
Newsstand Kit adds a new remote notification type, called UIRemoteNotificationTypeNewsstandContentAvailability which informs the app that it is able to receive new content updates through push notifications. As our app is not interested in receiving other kind of push notifications, we can replace the code above with:
1
2
3
    // APNS standard registration to be added inside application:didFinishLaunchingWithOptions:
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeNewsstandContentAvailability];
}
When you start the app the first time you will get a new kind of alert. If you don’t get it then your setup is invalid and I suggest to implement and check the error message passed with the - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error method.
At this point you’re ready to send a push notification to your device informing Newsstand that a new issue is available. The push notification message has the same syntax as standard push notifications with the only difference that the payload must contain the content-available key set to 1:

1
2
3
4
5
6
{
  "aps":{
 "content-available":1,
        },
   "device_tokens": ["E9623F5CFDE92B40DA4AA90B97B70428BCD8FFCBA067BE17A6EF5102651E66E9"]
}
There is one importation limitation related to the frequency of pushes: to limit the consumption of resources due to background downloading (which, by the way, we’ll happen only if the device is connected to a Wi-Fi network) Newsstand push notifications are coalesced and only one background download is permitted per day. For testing purposes you can remove this limit by setting an appropriate key in the user defaults (do this at startup in your App Delegate):
1
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NKDontThrottleNewsstandContentNotifications"];
When a notification is sent your app can be in two possible states: running in the foreground or not. In the first case you must respond to the UIApplicationDelegate application:didReceiveRemoteNotification:, and your action could be simply alerting the user or starting the new download automatically or asking the server for the new issue data (title, cover, and so on). In the other case your app will be activated in the background again with a call to the application:didFinishLaunchingWithOptions: and what this method has to do, in addition to the other things is doing, is to check the launch options for the UIApplicationLaunchOptionsRemoteNotificationKey and retrieve the payload. In this case what can be done is to start a background task that will fetch the latest issue from the server of get the list of all issues and starting downloading the last one for example. Normally this background task should be completed in a couple of seconds, which is the time assigned by the operation system to start the automatic download. If this time is not considered enough, because you have to query your server before, then the suggested approach is to run this procedure inside a beginBackgroundTaskWithExpirationHandler: call thus getting about 10 minutes for the whole job.
The example below shows how the app can behave in case it is not running (neither in the foreground nor as inactive). In this simple example we assume the latest magazine is “Magazine-4” (but we could have given the name inside the notification payload) and then just schedule the download. At this point the app will terminate again but when the download terminates it is resumed, thanks to the internal rules of NK previously explained, and then the magazine is moved to its final location.
1
2
3
4
5
6
7
8
9
10
11
    NSDictionary *payload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
    if(payload) {
        // schedule for issue downloading in background
        NKIssue *issue4 = [[NKLibrary sharedLibrary] issueWithName:@"Magazine-4"];
        if(issue4) {
            NSURL *downloadURL = [NSURL URLWithString:@"http://www.viggiosoft.com/media/data/blog/newsstand/magazine-4.pdf"];
            NSURLRequest *req = [NSURLRequest requestWithURL:downloadURL];
            NKAssetDownload *assetDownload = [issue4 addAssetWithRequest:req];
            [assetDownload downloadWithDelegate:store];
        }
    }

Updating the Newsstand icon

A new special feature introduced with Newsstand is the possibility to update the Newsstand app icon according to the last updated cover. The recommendation from Apple is to use the cover of the last updated issue. Another interesting possibility is that we can mark this icon with a New sash to mark that an issue is new and has not been read yet. Of course as soon as the app is restarted or the new issue has been read it is good practice to remove this marker. The way we can change the icon and set the sash visible is quite easy, just put this code somewhere after your download did finish and your issue has been safely saved in its destination path (never show the cover before it is available!):
1
2
3
4
5
6
    // update the Newsstand icon
    UIImage *img = [publisher coverImageForIssue:nkIssue];
    if(img) {
        [[UIApplication sharedApplication] setNewsstandIconImage:img];
        [[UIApplication sharedApplication] setApplicationIconBadgeNumber:1];
    }
Your screen will appear like this: the Newsstand icon badged, your app icon cover update to the new cover and the “New” sash on top of it.

Conclusions

In the next article we will talk about the interaction of a Newsstand app with the In App Purchase system and how to manage it using the iTunesConnect service. The full source code to be used more than a reference to better follow this tutorial than a real example to be run, can be found on GitHub.
At this point you may ask yourself if adding Newsstand for your next apps makes sense or not. There are several advantages but also drawbacks. The main drawback is that Newsstand works on devices that have migrated to iOS5. At the time of writing, after few days from iOS 5 distribution to the customers, the adoption rate is 1/3. We may expect by the end of 2011 an adoption rate greater than 80%. Anyway consider this point before starting delivering a magazine app with Newsstand and if you are doing this for a client then talk with her/him about this point. If you have a magazine already in the App Store and you’re considering to migrate it to Newsstand, then of course you will not lose your existing customer base as releasing an update will not impact all users that have installed the previous app versions, provided you don’t change your back-end, that is the server side web service remain compatible with old app versions. Clearly new users potential still stuck to iOS4 will not be able to install the newer iOS 5 versions.
The major advantages in using Newsstand are that from the point of view of user experience, it is improved as the user feels more natural to pick its magazine from a single stand; besides some features as latest cover and automatic download will be greatly appreciated. From the point of view of the publisher having an app in the Newsstand will bring a marketing advantage as Newsstand presents itself as a separate area in the store, quite visible and well promoted by Apple. Finally from the point of view of the developer you will be able to take advantage of many features, including a shared issues library and an efficient background download system, whose development from scratch can be difficult and requires care of many details: now some of the possible issues are managed by the framework and you, as developer, can spend more time on delivering a good user experience.

Monday 23 April 2012

Custom Cell in UITableView



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellTableIdentifier = @"CellTableIdentifier";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];
    
    
    if (cell == nil) {
        CGRect cellFrame = CGRectMake(0,0,300,65);
        cell = [[[UITableViewCell alloc] initWithFrame: cellFrame
                                       reuseIdentifier:CellTableIdentifier] autorelease];
    
             
        CGRect projectValueRect = CGRectMake(12,44,100,17);
      
        UILabel *projectValue = [[UILabel alloc] initWithFrame:projectValueRect];    
         projectValue.textAlignment = UITextAlignmentLeft;
        projectValue.backgroundColor=[UIColor clearColor];
        projectValue.textColor=[UIColor whiteColor];
       // projectValue.font = [UIFont boldSystemFontOfSize:12];
        projectValue.tag = kProjectValueTag;
        [cell.contentView addSubview:projectValue];
        [projectValue release];

        CGRect RTRect = CGRectMake(90,45,60,15);
        UILabel *RTRectLbl = [[UILabel alloc] initWithFrame:RTRect];           
        RTRectLbl.textAlignment = UITextAlignmentLeft;
        RTRectLbl.text = @"R.Time:";
        RTRectLbl.backgroundColor=[UIColor clearColor];
        RTRectLbl.textColor=[UIColor whiteColor];
        //RTRectLbl.font = [UIFont boldSystemFontOfSize:14];
        [cell.contentView addSubview: RTRectLbl];
        [RTRectLbl release];   

        CGRect timeValueRect = CGRectMake(150,45,60,15);
        UILabel *timeValue = [[UILabel alloc] initWithFrame:timeValueRect];      
        timeValue.backgroundColor=[UIColor clearColor];
        timeValue.textColor=[UIColor whiteColor];
         timeValue.tag = kTimeValueTag;
        [cell.contentView addSubview:timeValue];
        [timeValue release];
        
        CGRect nameValueRect = CGRectMake(10,9,100,15);
        UILabel *nameValue = [[UILabel alloc] initWithFrame:nameValueRect];    
        nameValue.backgroundColor=[UIColor clearColor];
        nameValue.textColor=[UIColor whiteColor];
        nameValue.tag = kNameValueTag;
        [cell.contentView addSubview:nameValue];
        [nameValue release];
        
        CGRect DueDate = CGRectMake(160,9,150,15);
        UILabel *dueDate = [[UILabel alloc] initWithFrame:DueDate];   
        dueDate.backgroundColor=[UIColor clearColor];
        dueDate.textColor=[UIColor whiteColor];
        dueDate.tag = kDueValueTag;
        [cell.contentView addSubview:dueDate];
        [dueDate release];
        
        
        
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button addTarget:self 
                   action:@selector(cellClick:)
         forControlEvents:UIControlEventTouchDown];
         button.tag=indexPath.row;
         [button setBackgroundImage:[UIImage imageNamed:@"detail.png"] forState:UIControlStateNormal];
        //[button setTitle:@">>" forState:UIControlStateNormal];
        button.frame = CGRectMake(260, 45.0, 45.0, 45.0);
        [cell.contentView addSubview:button];
        
        
        
        
        
    }
    
    // Set up the cell...
    NSLog(@"%d",indexPath.row);
    Tasks *taskDetails=[allTasks objectAtIndex:indexPath.row];
    Projects *projrctDetails=[allProjects objectAtIndex:indexPath.row];
    
    NSLog(@"%@",projrctDetails.project_title);
    
    
    UILabel *name = (UILabel *)[cell.contentView viewWithTag:kNameValueTag];
    name.text = taskDetails.task_title;
    
    UILabel *Duedate = (UILabel *)[cell.contentView viewWithTag:kDueValueTag];
    Duedate.text = taskDetails.task_due_date;
    
    
    UILabel *projectText = (UILabel *)[cell.contentView viewWithTag:kProjectValueTag];
    projectText.text = projrctDetails.project_title;
   
    
    UILabel *timeTag = (UILabel *)[cell.contentView viewWithTag:kTimeValueTag];
   NSTimeInterval lastDiff = [[self.dateFormatter dateFromString:taskDetails.task_due_date] timeIntervalSinceNow];
    
    NSDate *now = [NSDate date];  
    NSString *dateString = [self.dateFormatter stringFromDate:now];
    NSTimeInterval todaysDiff = [[self.dateFormatter dateFromString:dateString] timeIntervalSinceNow];
    NSTimeInterval dateDiff = lastDiff - todaysDiff;
    
    
    div_t h = div(dateDiff, 3600);
    int hours = h.quot;
    // Divide the remainder by 60; the quotient is minutes, the remainder
    // is seconds.
    div_t m = div(h.rem, 60);
    int minutes = m.quot;
    timeTag.text = [NSString stringWithFormat:@" %d:%d",hours,minutes];
    
   // [cell setBackgroundColor:[UIColor colorWithRed:3/255.0f green:130/255.0f blue:242/255.0f alpha:1.0]];
    
    return cell;
}

How to convert NSTimeInterval to hours, minutes


 NSDate *now = [NSDate date];  
    NSString *dateString = [self.dateFormatter stringFromDate:now];
    NSTimeInterval todaysDiff = [[self.dateFormatter dateFromString:dateString] timeIntervalSinceNow];
    NSTimeInterval dateDiff = lastDiff - todaysDiff;
    
    
    div_t h = div(dateDiff, 3600);
    int hours = h.quot;
    // Divide the remainder by 60; the quotient is minutes, the remainder
    // is seconds.
    div_t m = div(h.rem, 60);
    int minutes = m.quot;
    timeTag.text = [NSString stringWithFormat:@" %d:%d",hours,minutes];

Wednesday 18 April 2012

Add current location on map in IOS


-(void)viewWillAppear:(BOOL)animated{
    map.mapType = MKMapTypeStandard;
    map.showsUserLocation=YES;
     NSLog(@"%f%f",self.lat_task,self.long_task);
    CLLocationCoordinate2D coord = {.latitude = self.lat_task, .longitude = self.long_task};
    MKCoordinateSpan span = {.latitudeDelta0.3, .longitudeDelta0.3};
    MKCoordinateRegion region = {coord, span};
    [map setRegion:region];
    //map.delegate=self;
     MKPlacemark *mPlacemark = [[[MKPlacemark alloc] initWithCoordinate:coord    addressDictionary:nil] autorelease];
    [map addAnnotation:mPlacemark];
  

}

Thursday 12 April 2012

8 Things Instagram Did Right


With its billion-dollar sale to Facebook, Instagram instantly became the latest poster child for startup success. In just 551 days, the photo-sharing mobile app zoomed from zero to 30 million-odd users, and 10 million U.S. visits by March 2012, up 1000% since December 2011. Its valuation outstrips that of the 116-year-old New York Times.
An amazing run, and it wasn't all just luck, though the company enjoyed plenty of that. To boost its chances to win the startup lottery, Instagram did eight very important things right.

1. Instagram Operated as a Nimble Start-up

Despite its meteoric growth, Instagram kept its overhead low with a total of only 13 employees, and its headquarters weren't anything to brag about, either. Instagram is housed in Twitter's old digs on 164 South Park Street in the trendy but still slightly seedy SOMA neighborhood of San Francisco.
More important, it stayed nimble enough to switch gears from its original idea of a location-based social network called Burbn to an iPhone app focused solely on photo-sharing. And instead of hiring workers or looking for revenue, the company was able to focus on growing the platform, its community and its aesthetic offerings.

2. Instagram Cashed in on the Mobile Explosion

Instagram's timing was perfect, capitalizing on a historic increase in smartphone use. Starting out as an iOS app, it successfully targeted the burgeoning legions of hip iPhone-app users. It waited until Android reached nearly 50% mobile marketshare to launch the long-awaited app on that platform. Meanwhile, Instagram mostly ignored the no-longer-as-hot Web space, although there is a Web version called Webstagram.

3. Instagram's Interface Stayed Junk-Free

Spend 20 minutes on Instagram and chances are you'll be hooked. Beautiful pictures filtered through hazy lenses flow down an otherwise cold, glass screen. Instagram charges up a smartphone screen, filling it with emotion - not piles of distracting controls and icons. On Instagram, the image stands alone. Instagram successfully created a new world where images - not functionality - are the main focus.

4. Instagram Didn't Get Creepy

Instagram managed to keep its creep vibe low. It doesn't push users to post, to share or even to like - it is an open space, available to use as you wish. Stay on the sidelines and just observe - no one will ever know. Pop into a conversation and then quickly leave. You won't be the only one: Instagram users are notoriously fickle.
That's why Instagram's easy follow/unfollow option doesn't require a commitment as heavy-handed as "friending" on Facebook. Follow whomever you want, or just wander off and find new images to look at. You won't accidentally see some old fling pop up in the Instagram stream, unless you purposely follow that person.

5. Instagram Married Visceral, Visual Communication & Community

Instagram built a devout community based on a single idea: capturing and sharing beautiful images. Powerful images are inherently emotional - think about The Atlantic's In Focus section.
Instagram gave people an easy way to connect around images, without the added pressure of complex social relations. Communities popped up organically around filters, around using too many filters and around just friends.
"There are a lot of things in [a] photo that someone can respond to, [that] promote conversation - then you get a wonderful interaction out of it," says Piictu Community Manager Zachary McCune. "I hope that continues, because that's what's beautiful about being able to relate to photographs."
A talented photographer can capture a single emotion in a square image, and make the viewer stop and feel something, if only for a moment. Instagram makes that moment easier to share.

6. Instagram Created a Valuable New Data Set

Every time an Instagram user snaps a picture, the app can capture a rich set of data, including location, time of day and other data points that can be associated with a smartphone's sensors, explains ReadWriteWeb's Dan Rowinski in How Instagram Will Help Facebook Monetize Mobile.
Instagram may not have been monetizing that data, but you can bet Facebook will. "Facebook is adding another crucial set of data points/edges to analyze people's activity online," says PixableCEO Inaki Berenguer. "With Instagram in the fold, Facebook can now quantify what people are taking photos about based on the tags they put on their photos."

7. Instagram Didn't Worry About Making Money

In its short 15-month lifespan, Instagram focused on building its community, user base and functionality rather than worrying about how the platform was going to make money. By not chasing the dollar, it was able to focus on making the app better.
Of course, Instagram did pay attention to acquiring VC funding. Right before the Facebook acquisition, it closed a $50M Series B round from Sequoia, Thrive, Greylock and Benchmark, valuing the company at a sweet $500 million.
Figuring out revenue streams is now something that Facebook COO Sheryl Sandberg and her teamwill have to worry about.

8. Instagram Embodied a Cultural Shift Toward Photo Inboxes

As the future of photo-only inboxes approaches, and more people use photo-sharing apps to connect with their friends, the need for more visual communication will only intensify. The idea that social interactions will increasingly become visual and mobile is attracting widespread interest.
"Increasingly, we see people using photos to share an experience with a friend, whether it's to tell them what they had for lunch, show them a cool spot in their city that they found or to share special moments like birthdays or weddings," says Pixable's Berengeur. "The ultimate goal of sharing mobile photos is to broadcast your life to your friends instead of keeping a memory. The rise of smartphones, photo apps and social networks have made taking and sharing a photo easier than ever."

What Other Startups Can & Can't Learn From Instagram

What worked for Instagram isn't guaranteed to work for every startup. It's always easier to look back and uncover the right and wrong strategic moves. Only in retrospect is it clear that Instragram did everything right. Along the way, there were plenty of critics carping at just about every decision the company made.
There is, however, one thing that other startups can certainly learn from Instagram: Timing is everything. If Instagram had come along six months later, things might have turned out very differently. Some other company might have already executed on its ideas and it would be the one preparing to cash some very big checks