iDev: How to extend existing method in Objective-C

Hi Friends,

Todays you learn a very good technique, I hope:)

With blocks it’s more easy if you need extend your method. But if you will need extend some method of another class, not yours, and you will not be able to get the sources then this solution for you. (And if you will not be able or does not have any reason for creating a subclass)

1. You need create a category of class

2. import runtime in implementation file (.m)

#import <objc/runtime.h>

3. implement your method inside category, for example :

– (void) extend_method {

// your code

//  here will be performed the original method
[self extend_method];

// your code
}

It looks like this method has recursive calls itself, but it’s not true. Look next step

4. add method for replace (you can use +initialize or +load)

+ (void) initialize {
Method original = class_getInstanceMethod(self, @selector(method));
Method replacement = class_getInstanceMethod(self, @selector(extend_method));
method_exchangeImplementations(original, replacement);
}

Done!

Reference : Press Here

Keep Coding 🙂

 

Advertisements

iDev: Secure site trust (Https:) in iOS using NSURLConnection

Secure Coding iPhone and iPad Apps Against MiTM

Many iOS applications use HTTP to connect to server side resources. To protect user-data from being eavesdropped, iOS applications often use SSL to encrypt their HTTP connections.

In this article, I will present sample Objective-C code to illustrate how HTTP(S) connections are established and how to locate insecure code that can leave the iOS application vulnerable to Man in the Middle attacks. I will also discuss how to configure an iOS device to allow for interception of traffic through an HTTP proxy for testing purposes.

A Simple App Using NSURLConnection

The easiest way to initiate HTTP requests in iOS is to utilize the NSURLConnection class. Here is sample code from a very simple application that takes in a URL from an edit-box, makes a GET request, and displays the HTML obtained.

[Please note that the code in this particular example is mostly from Apple’s wonderful tutorial on how to use NSURLConnection]

//This IBAction fires when the user types in a URL and presses GO
– (IBAction) urlBarReturn:(id)sender
{   
    //htmlOutput is the UITextView that displays the HTML
    htmlOutput.text=@””;

    //urlBar is the UITextField that contains the URL to load
    NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:urlBar.text]
                                              cachePolicy:NSURLRequestUseProtocolCachePolicy
                                              timeoutInterval:60.0];
    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

    if(!theConnection)
        htmlOutput.text=@”failed”;   
}

– (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{
    //receivedData is of type NSMutableData
    [receivedData setLength:0];

}

– (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [receivedData appendData:data];

    NSString *tempString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    htmlOutput.text = [NSString stringWithFormat:@”%@%@”,htmlOutput.text,tempString];

    [tempString release];
}

– (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{

    [connection release];

    [receivedData release];

    NSLog(@”Connection failed! Error: %@ %@”,
          [error localizedDescription],
          [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);

    htmlOutput.text=[NSString stringWithFormat:@”Connection failed! Error %@ %@”,[error localizedDescription],
                     [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]];
}

– (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@”Succeeded! Received %d bytes of data”,[receivedData length]);

    [connection release];

    [receivedData release];

}

The result is a simple iOS application that fetches HTML code from a given URL.

IOS-app-simple-html
Figure: Simple iOS App using NSURLConnection to fetch HTML from a given URL.

In the screen-shot above, notice that the target URL is https. NSURLConnection seamlessly establishes an SSL connection and fetches the data. If you are reviewing source code of an iOS application for your organization to locate security issues, it makes sense to analyze code that uses NSURLConnection. Make sure you understand how the connections are being inititated, how user input is utilized to construct the connection requests, and if SSL is being used or not. While you are at it, you may also want to watch for NSURL* in general to include invocations to objects of type NSHTTPCookie, NSHTTPCookieStorage, NSHTTPURLResponse, NSURLCredential, NSURLDownload, etc.

Man in the Middle 

74.125.224.49 is one of the IP addresses bound to the host name http://www.google.com. If you browse to https://74.125.224.49, your browser should show you a warning due to the fact that the Common Name field in the SSL certificate presented by the server (www.google.com) does not match the host+domain component of the URL.

IOS-safari-warning Figure: Safari on iOS warning the user due to mis-match of the Common Name field in the certificate.

As presented in the screen-shot above, Safari on iOS does the right thing by warning the user in this situation. Common Name mis-matches and certificates that are not signed by a recognized certificate authority can be signs of a Man in the Middle attempt by a malicious party that is on the same network segment as that of the user or within the network route to the destination.

Ios-NSURL-warning Figure: NSURLConnection’s connection:didFailWithError: delegate is invoked to throw a similar warning.

The screenshot above shows what happens if we attempt to browse to https://74.125.224.49 using our sample App discussed ealier: the connection:didFailWithError: delegate is called indicating an error, which in this case warns the user of the risk and terminates.

This is fantastic. Kudos to Apple for thinking through the security implications and presenting a useful warning message to the user (via NSError).

Unfortunately, it is quite common for application developers to over-ride this protection for various reasons: for example, if the test environment does not have a valid certificate and the code makes it to production. The code below is enough to over-ride this protection outright:

 

– (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace

{
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

– (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

{
                [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
}

The details on this code is available from this stackoverflow post. There is also a private method for NSURLRequest called setAllowsAnyHTTPSCertificate:forHost: that can be used to over-ride the SSL warnings but Apps that use it are unlikely to get through the App store approval process (Apple prohibits invocations of private API).

If you are responsible for reviewing your organization’s iOS code for security vulnerabilities, I highly recommend you watch for such dangerous design decisions that can put your client’s data and your company’s data at risk.

Intercepting HTTPS traffic using an HTTP Proxy.

As part of performing security testing of applications, it is often useful to intercept HTTP traffic being invoked by the application. Applications that use NSURLConnection‘s implementation as-is will reject your local proxy’s self-signed certificate and terminate the connection. You can get around this easily by implanting the HTTP proxy’s self-signed certificate as a trusted certificate on your iOS device [Note: This is not a loop-hole against the precautions mentioned above: in this case we have access to the physical device and are legitimately implatining the self-signed certificate].

If you are using the Burp Proxy or the Charles Proxy, all you need to do is place the self-signed cert on a HTTP location and browse to it. Instructions for the Burp Proxy are available here, and instructions for Charles Proxy are also available.

Once you have your iOS device or simulator setup using the self-signed certificate of your HTTP proxy, you should be able to intercept HTTPS connections that would otherwise terminate. This is useful for fuzzing, analyzing, and testing iOS applications for security issues.

Source Reference : Click Here..

Thanks 🙂

Keep Coding and innovation new thing in your code … 😉

 

iDev : Essential Tools for iOS Developers

75 Essential Tools for iOS Developers

Source Reference : Here

If you were to go to a master woodworker’s shop, you’d invariably find a plethora of tools that he or she uses to accomplish various tasks.

In software it is the same. You can measure a software developer by how they use their tools. Experienced software developers master their tools. It is important to learn your current tools deeply, and be aware of alternatives to fill in gaps where your current ones fall short.

With that in mind, I present to you a gigantic list of tools. Some of these I use daily, others I see potential in. If you have more tools you’d like to see here, just make sure to add a comment.

I tried to categorize these the best I can. Some of the entries are websites, some are back-end services, but most are apps that you install. Not all of the apps are free, so I’ll make a note with a $ to denote that an app costs money.

And without further ado, we’ll start from the beginning of any project, and that

Inspiration

  • pttrns – A great library of iOS screen designs categories by task. If you want to see how other apps handle activity feeds, for instance, this is a great place to go see a bunch of examples.
  • TappGala – Another great collection of nice app designs. It’s not categorized by task, but is just a list of great apps to get inspiration from.
  • Cocoa Controls – A great list of components (code) that you can use in your iOS apps. Sometimes you’ll find great pieces of code that can save you time, other times you can just learn how other developers accomplish certain features. Subscribe to their weekly newsletter; all signal, little noise.
  • IICNS – A collection of really great icons. Get inspired, but don’t copy.
  • Dribbble – Some of the best digital designers post up their work for all to see. A treasure-trove of designs to look at.
  • Capptivate – a gallery of inspirational designs. Some contain animations. Thanks, @joaopmaia!

Design

  • Mocks ($) – An easy to use tool to create a quick mockup of an iOS app. Comes with a bunch of the default controls you can use to assemble something quickly.
  • Briefs ($) – A really useful app that allows you to create a mockup of an app and stitch them together so you can see the interaction. Deploy to a device so you can see what it feels like in your hand.
  • Acorn ($) – A strong competitor to Photoshop, only way cheaper. I find myself reaching for Photoshop less & less these days. Under active development.
  • Sketch ($) – A vector-based drawing tool that is increasingly useful these days, as screen sizes and pixel densities change. It is often helpful to design once and have the freedom to scale up & down as needed. Also sports a really powerful export system. For some example Sketch projects, check out Sketchmine. See my screencast on Sketch for a live demo.
  • iOS 7 PSD by Teehan+Lax – A super handy resource if you (or your designer) uses Photoshop. An iOS 6 version is also available.
  • Bjango’s Photoshop Actions – A definite time-saver if you use Photoshop to design iOS apps. One click access to resize canvases, scale by 200% (or 50%), set global lighting to 90º, and more. Their blog also has a bunch of useful Photoshop workflow tips.
  • xScope ($) – An indespensible swiss-army knife of tools such as guides, pixel loupes, screen rulers, and more. Want to know what color value that pixel is? Want to see how many pixels between a button and the window for a random Mac app? xScope has you covered. Also check out their companion iPhone app for mirroring designs you’re working on and seeing them in pixel-perfect glory on your iDevice.
  • Glyphish ($) – A fantastic collection of high quality icons for your iOS apps. Apple doesn’t provide a lot of built-in icons, so it’s handy to have a collection of icons covering all kinds of various concepts. I’m still looking for a use for that baby icon though. Glyphish comes in packs, and the latest pack has iOS 7 “thin line” icons which will be very handy when designing an iOS 7 app.
  • Fontastic Icons for iOS – An open source set of classes for utilizing icon fonts, such as Font Awesome in your iOS app. Quickly and easily have an icon in whatever pixel dimensions you require. Since fonts by nature can be scaled up and down with ease, this makes a really nice way to ship & use your icons without having to export multiple versions for the sizes you require.
  • PaintCode ($) – A vector-based drawing tool that exports your artwork as the equivalent Core Graphics source code. Awesome for learning how Core Graphics drawing works, but also incredibly handy if you want your drawing to be dynamic. See my screencast on PaintCode for a live demo.
  • Edge Insets ($) – A simple tool that helps you define your edge insets for repeatable images. Available on the Mac App Store.
  • LiveView – A remote screen viewer for iOS, making it easy to immediately see your designs on a device. Thanks, @_funkyboy!
  • Skala Preview ($) – Another excellent tool for quickly showing your designs off on a real device. The guys at Bjango are awesome and this app is deserving of the price. Thanks, jn40!

Source Control

  • Git – If you’re not using source control stop what you’re doing and rectify that. I use git for everything I do and love it.
  • Kaleidoscope ($) – The best diff/merge tool around. Does 3-way merges and is beautiful to look at. I use it every day.
  • p4merge – A free, ugly alternative to Kaleidoscope. Powerful 3-way merge, but good luck finding the download link. It’s hidden deeper in their site every time I look for it.
  • Git X – A simple, powerful GUI tool for visualizing git timelines and quickly & easily staging commits. I usually live in the Terminal for git usage, but fall back to this app when I need to stage hunks of changes into logical commits. This is a fork of the original (abandoned) GitX, which I found on this list of forks.
  • Source Tree – A free, full-featured Git application. I don’t use this because I favor the command line, but if a GUI tool is your cup-o-tea, check this app out.

Dissecting Apps

  • pngcrush – This little utility can crush & uncrush PNG files, which is handy when you want to view images contained in app bundled distributed in the App Store. Just open iTunes, view the local Apps list, and right click on any icon to Show in Finder. Once there, open up the app and you’ll see a bunch of PNG files, but you can’t view them. Using pngcrush you can extract the full version so it can be opened with Preview.
  • appcrush.rb – This handy little ruby script will automate the above process for all images. Just point it to a .app file on your disk and it will extract all the images to a folder on your desktop. Handy for seeing how apps on your phone accomplish certain designs. Check out my screencast on dissecting apps for a live demo.
  • Charles ($, free limited demo) – I don’t know what’s going on with the ugly UI or icon, but Charles is an essential tool for any developer. Charles acts as a proxy to allow you to inspect your network traffic to & from the iPhone Simulator. You can also inspect traffic from your device by setting your phone’s proxy to your Mac running Charles. With self-signed SSL certificates, request & response breakpoints, and request/response viewers, Charles is really amazingly powerful. A must-have tool. Again, my screencast on dissecting apps covers this well.

Editors

I know what you’re thinking, don’t all iOS developers use Xcode? Well mostly, yes. But with my love/hate relationship with Xcode, I believe there is tremendous value in considering alternatives.

  • AppCode – A full-fledged IDE from Jetbrains (makers of the excellent ReSharper for .NET). Immensely powerful refactorings & features that help you write code faster. Quickly identify dead code, automatically insert #import statements when you use related code, easily extract variables, methods, and classes. My only wish for this app is that it would instead be a plugin to Xcode.
  • Vim – Wait, vim? Really? Yes, there are folks who do all their Objective-C development in vim. I’m not one of these, but I am a fan of vim for Ruby development. As such, I’m a huge fan of…
  • Xvim – An Xcode plug-in that gives you vim keybindings. Works well, ‘nuff said.
  • OMColorSense – Another plugin for Xcode, this one gives you a small display of color when your cursor is on a line looking like: [UIColor redColor]. Clicking on this little color tab opens a color picker that you can change, and any change in color you make is reflected in the code by changing the line to [UIColor colorWithRed:… green:… blue:… alpha:… ]. When someone is watching me write code with this enabled, they invariably ask me, “Whoa! What was that?!”
  • KSImageNamed – Another Xcode plug-in, this one allows you to autocompleted image filenames from your bundle when typing [UIImage imageNamed:…]. Great way to avoid the inevitable typo that causes this method to return nil and you to subsequently waste 10 minutes trying to figure out why your images aren’t displaying.
  • CocoaPods Xcode Plugin – This plug-in adds a menu item for interacting with CocoaPods. Useful if you don’t like dropping to the command line.
  • Alcatraz Package Manager – An awesome meta plug-in that allows you to easily install other Xcode color schemes and plug-ins with a single click.
  • Code Runner ($) – a light-weight code-aware text editor that knows how to compile & run code in most languages. Want to test out a quick snippet of Objective-C code and don’t want to create an entire Xcode project to do it? Code Runner to the rescue.

Documentation

Ahhh, documentation, everyone’s favorite topic. Even still, documentation is really important to have, so pay attention so we can make your life easier.

  • appledoc – Want to automatically generate documentation that look’s like Apple’s? Look no further. Automatically inter-links symbols defined in your project as well as extracting discussion to output using specially formatted code-comments. Generates official docsets and HTML web sites.
  • Dash ($) – A must-have API documentation viewer and code snippet manager. This tool is really handy as it allows you to download & search API docs for all kinds of languages & frameworks with lightning speed. The fastest way to get access to the docs. I integrate Dash with Alfred to make searches even faster.

Dependency Management

Yes, there’s only one tool listed here. I didn’t want to include actual 3rd party libraries, as that would be a different list entirely. When it comes to dependency management, there’s only one game in town:

  • CocoaPods – The essential tool for Objective-C projects. Allows you to quickly & easily integrate 3rd party libraries into your application. It does so by creating a second static library project and automatically links this with your projects. There are thousands of pods available, and it’s easy to add support for libraries that you don’t own (or perhaps are private). I use CocoaPods in every single project I work on.

Diagnostics & Debugging

At some point our app is in the field and we need to understand better what’s going on, maybe to fix bugs or to improve performance.

  • Cocoa Lumberjack – a much more powerful NSLog, Cocoa Lumberjack offers advanced logging behaviors such as logging to rotated files, logging to the network, and filtering based on log level (info, debug, warn, error). Covered by NSScreencast Episode 61
  • DCIntrospect – crazy powerful tool that you’d link inside your app when running in debug and on the simulator. Once you do, you can press the spacebar to get some really helpful view debugging support. See exact dimensions of elements on the screen, print out view hierarchies, even nudge views horizontally or vertically.
  • Pony Debugger – another tool you’d use by embedding a library in your debug builds, Pony Debugger actually utilizes Chrome’s dev tools for seeing network requests coming out of the device, as well as a rudimentary Core Data browser. It’s hard to describe, but check out my screencast on Pony Debugger for more info.
  • Runscope ($) – Runscope is a service running online that can capture requests, log details, and give you valuable data about your API. Simple to set up, as it’s an HTTP pass-through API, all you need to change is your host name.
  • SimPholders – Quick, easy access to your simulator folders. Browse by iOS version, then app name and jump right to the folder in Finder.
  • Spark Inspector ($) – Debug your view hierarchy running on your app in debug mode, in 3D. This app really has to be seen to fully understand the value, but it can really help to understand what views are used to compose your app. Also contains a notification center inspector, so you can easily see what NSNotifications are firing and who is observing them. Another app to look at that is similar is Reveal.

Images

  • ImageAlpha – A Mac app that allows you to convert a 24-bit PNG with transparency to an 8-bit PNG with an alpha channel. Typically 8-bit PNGs don’t have an alpha channel, so if your image can be represented in 8-bits (say, a solid color button) you can save a lot on storage by converting the 24-bit PNG to 8-bit using ImageAlpha.
  • ImageOptim – Another Mac app that compresses PNGs in order to save space. Most PNG files can shave off a few % of the size, and sometimes you’ll shrink the files by 30% or more. Smaller images mean smaller app sizes and less memory used to load them at runtime.
  • Prepo – A little Mac app that can quickly resize artwork in all the various sizes you might need. Just drag a large icon file (say, 1024×1024) onto Prepo and watch it spit out 512×512 iTunesArtwork, 114×114 Icon@2x.png, and all the other sizes & filenames you’d expect.
  • Slender ($) – an awesome app that analyzes your app and finds all sorts of problems, such as missing retina artwork, unused images, image that could benefit from compression and more. Shave kilobytes off of your iPhone app by shedding unused images with Slender.

Core Data

  • Mogenerator – still a super useful tool for generating smart subclasses of your NSManagedObjects in your Core Data model. Some use Xcode for this, and resort to manually subclassing or creating categories in order to add logic to the models. Mogenerator runs as a quick pre-compile script to generate subclasses for you to use. It does this by creating an underscored version (_User) and a regular one for you to modify (User).
  • Base ($) – there will come a time when you need to inspect your actual Core Data sqlite database to see what’s going on. You can use the sqlite3 command line tool, but Base offers a nice looking GUI browser. Just don’t vomit when you see the database schema that Core Data created for you.
  • Core Data Editor ($) – for more advanced data anlysis, exploration, and modification you can use Core Data Editor. This app understands Core Data, so you’re working directly with the entities instead of database rows.

Back-end Services

Ultimately your iOS app will likely want to talk to a server to share data, fetch new content, send push notifications or whatever. While this can be accomplished manually, you might want a more drop-in solution.

  • Helios – Helios is an open-source framework that provides essential backend services for iOS apps, from data synchronization and push notifications to in-app purchases and passbook integration. Built on top of many open source ruby gems, so you can pick & choose and build your own stack if you so desire. Take a look at the Nomad CLI set of handy related tools as well.
  • Windows Azure Mobile Services – you can think of this sort of like a programmable database in the cloud. Create tables, run JavaScript on read, insert, delete to add additional functionality. Really easy support for push notifications as well.
  • Urban Airship – I’ve been using Urban Airship to deliver push notifications for a while now. Really easy to integrate with, and small usage is free.
  • Parse – This is another data-in-the-cloud service, but offers an impressive API and online data browser. We use Parse for a really small app and works well for that.

Analytics

There are other players here, but none that I’ve seen have been compelling enough to switch from flurry. I’m open to hearing suggestions, so let’s hear about ‘em in the comments.

  • Flurry – I’ve used flurry for a long time to provide useful analytics on the usage of my apps. Need to know when to stop supporting iOS 5? Flurry gives you the numbers to have a realistic conversation.

Deployment

  • Deploymate ($) – Need to support iOS 4 still, but you’re compiling with the iOS 6 SDK? Deploymate will warn you when you’re using symbols that don’t exist in your deployment target.
  • Cupertino – Part of the Nomad CLI tools, Cupertino gives you command line access to managing devices & profiles in the Apple Provisioning Portal. For example, just type ios devices:list to see the current list of devices in your account. Useful for automating lots of processes.
  • Hockey App ($) – A great service for managing the distribution of your ad-hoc builds. Testers can get a link to install new betas over the air. Also provides robust crash reporting so you can easily respond to crashes in your apps.
  • TestFlight – A free service, similar to Hockey App. We’ve used TestFlight with great success for easily distributing apps and collecting feedback from our users. My only wish is that they’d start charging for the service. Also includes analytics and crash reporting, but we don’t use those features.
  • iOS Simulator Cropper – A really easy way to snap images of the simulator, with or without status bar, with or without device chrome, etc. Great for taking App Store or just general marketing screenshots.
  • Status Magic ($) – Take better app store screenshots. Nothing makes your app look less crappy than an App Store screenshot that includes a low battery, or low signal. Status Magic gives you complete customization over what’s present in your status bar, including removing elements, changing the time to “9:41 AM” like Apple tends to do, and more.
  • Crashlytics – Excellent crash reporting for your apps in the field. Automatically uploads dSYMs on release builds so your crashes are automatically symbolicated and organized for you to focus on the most critical ones.

Testing

I don’t think we as a community focus enough on testing. There are great tools available to us, and most are so easy to use we have no real excuse not to write at least some tests for our apps.

  • Kiwi – A great Rspec-style testing framework for iOS. Built on top of SenTestingKit, so you just type ⌘U to run your specs. Also includes a completely robust mocking & stubbing library as well as assertions.
  • Specta – A light-weight BDD framework very similar to Kiwi, but the expectation syntax has one major benefit over Kiwi: everything is implicitly boxed like this: expect(items.count).to.equal(5). There’s no need to wrap 5 in an NSNumber like Kiwi does. Use in conjunction with Expecta for a bunch of useful matchers.

The following are all various ways of performing end-to-end acceptance tests. These tests will actually interact with your interface, touching buttons, scrolling, etc. By nature these will be slower and more brittle, but testing in broad strokes is certainly helpful to see if all of the pieces fit together properly.

Demos / Marketing

  • Reflector ($) – Wirelessly mirror your iOS device on your Mac using Air Play. Great for doing demos of applications on your computer.
  • Placeit – A great collection of high res photos of people using devices, but the screens are templates that you can insert your own screenshots into. Very cool, and great for displaying your app in a nice way on your website.

App Sales Reporting

Of course you want to be able to see how much money you’re making on your app, right? There are a few solutions for this, but here are a couple that work well:

  • App Viz 2 ($) – a really useful Mac app for tracking sales of your apps. You run it locally and it logs in and downloads your sales reports.
  • App Annie – an online sales reporting tool. I’m less comfortable giving my credentials to iTunes to a 3rd party, but it does keep the reports up to date for you so you don’t have to run an app locally. In the comments, Josh Brown suggests creating a different user for analytics in iTunes Connect, which is a really good idea.

Grab Bag

These tools don’t have a defined category above, but deserve a mention nonetheless.

  • Quick Radar – Submitting bug reports to Apple is our only way of making their tools better. If you’re frustrated by the lack of a feature, you should be submitting a bug report. If you come across a bug, you should be submitting a bug report. One has no right to complain if they have not yet filed a radar :). With that in mind, submitting bug reports via bugreporter feels like a trip back to 1995. Quick Radar is an awesome little app that makes submitting bug reports super easy. Sports automatic posting to open radar so others can see it, in addition to tweeting, and posting to App.net. I use this app several times per week.

Thanks 🙂

Keep Reading and Experiment on your code….

 

iDev: iOS Device not detect by xcode-5

Hi Friends,

Today I found a one major issue with XCode, Actually I upgarde my iOS Devices (6.0 to 7.1 ) , after that my device not detected by Xcode 5.0,with this error on organizer,

“The version of iOS on “iPhone/iPad ” is not supported by this installation of the iOS SDK. Please restore the device to a version of the OS listed below, or update to the latest version of the iOS SDK; which is available here.”

Solution:

Please upgrade your XCode to 5.1 and above version using the OS X App Store application, your reference links are :

And fix this issue.

For Reference : Here

Thanks 🙂

 

iDev: iOS7 Feature – AVSpeechSynthesizer (Text To Speech )

Hi Friends,

Apple added lots of new useful API’s in iOS 7, I am going to speak about one quickly today, AVSpeechSynthesizer (Text To Speech).

In short, this is Text to Speech, a really simple way to have iOS read a piece of text out loud. There are a number of use cases for this, navigation, directions, visual impairments, introductions etc.

Firstly you will need to include AVFoundation.framework Frameworks in your project

avfoundation

The simplest implementation of Text To Speech is only a few lines of code, in this example you could test this by adding the following code to your ViewDidLoad method, make sure that you have imported the AVFramework into your header file (#import <AVFoundation/AVFoundation.h>).

/****************************** .h File ***********************/

//
//  ST_VMViewController.h
//  iDev_TextToSpeech
//
//  Created by Vinay Mishra on 3/12/14.
//  Copyright (c) 2014 Vinay Mishra. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ST_VMViewController : UIViewController

@property (nonatomic, weak) IBOutlet UIButton *sayVoiceButton;
@property (nonatomic, weak) IBOutlet UITextView *txtView;

-(IBAction)sayVoiceButtonPress;
@end

/****************************** .M File ***********************/

//
//  ST_VMViewController.m
//  iDev_TextToSpeech
//
//  Created by Vinay Mishra on 3/12/14.
//  Copyright (c) 2014 Vinay Mishra. All rights reserved.
//

#import “ST_VMViewController.h”

@interface ST_VMViewController ()

@end

@implementation ST_VMViewController

@synthesize txtView = _txtView;
@synthesize sayVoiceButton;

– (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

-(IBAction)sayVoiceButtonPress{
if(_txtView.text.length>0){
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:_txtView.text];
AVSpeechSynthesizer *syn = [[AVSpeechSynthesizer alloc] init];
utterance.rate = 0.4;// Speed of Speaking [range (0.1 to 1.0)]
utterance.volume = 10;
NSLog(@”Speech ==> %@”, [AVSpeechSynthesisVoice speechVoices]);
NSLog(@”Current Langague == > %@”, [AVSpeechSynthesisVoice currentLanguageCode]);
[syn speakUtterance:utterance];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@”Message” message:@”Please enter the text” delegate:nil cancelButtonTitle:@”OK” otherButtonTitles: nil];
[alert show];
}
}
@end

Simply you create a function in which you only pass the string only like this

-(void) playVoiceWithString:(NSString *) textString{

AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString: textString];
AVSpeechSynthesizer *syn = [[AVSpeechSynthesizer alloc] init];
utterance.rate = 0.4;// Speed of Speaking [range (0.1 to 1.0)]
utterance.volume = 10;
[syn speakUtterance:utterance];

}

Thanks 🙂

Keep Coding:)

iDev: CSS inheritance sequence

CSS inheritance sequence

Starting today, I will also write about a few things CSS apart from Google Maps Javascript API and Jquery Mobile. I will cover some really interesting things in CSS and keep updating this blog as and when I learn something new and think its worth sharing with you all.

Today we will look at a very common mostly known thing in CSS – the inheritance sequence of CSS. Most of you reading this post must be aware that there are 3 ways in which you can include CSS into your web application.

  • External Stylesheet
  • Internal Stylesheet
  • Inline Styles
 
External Style Sheet
    An external style sheet is ideal when you are writing a style that would be applied across multiple pages. The external style sheet gives the developer lot of control over the look and feel of the entire website or web application. The external style sheet is included using the the “link” tag which is included in the head section.
<link rel=”stylesheet” href=”styles/default.css” />
Internal Style Sheet
    An internal style sheet is used usually when a single document has unique style. The internal styles are written as part of the “style” tag which is again included in the “head” section.
<style>
    p{
        font-size: 20px;
        color: #a123bb;
    }
</style>
Inline Style
    An inline style loses many of the advantages of style sheets by mixing the content with the presentation. Inline styles should generally be avoided and be used when absolutely necessary and unavoidable!
<p style=”font-size: 20px; color: #a123bb;”></p>
    As we know and/or have learned from experience, that these styles cascade into one, let’s say a “virtual” style sheet which gets applied on the entire web site/application. This cascade follows the following sequence to override each other and create one final style sheet. Number #4 in the following list has the highest priority in the cascade.
  1. Browser default styles
  2. External style sheet
  3. Internal style sheet
  4. Inline styles
    So an inline styles has the highest priority, meaning that it will override a style defined inside the “head” tag, or in an external style sheet or the default browser styles. However, there are a few cases where this sequence of cascade can change!
Case #1: Usage of the !important keyword
    In case there is the “!important” keyword associated with an of the styles, then that style would get applied irrespective of whether it is part of the internal or the external style sheet.
Case #2: Javascript
    When styles are applied through javascript, these styles will override all styles included as part of the internal or external style sheet or even the inline styles and the ones with even the “!important” keyword associated with them.
Case #3: Sequence of inclusion of stylesheets
    If the link to the external style sheet is placed after the internal style sheet in the “head” tag, the external style sheet will override the internal stye sheet!
    Hope you have enjoyed this post and learned a few new things. Do let me know in case you want me to include a topic as part of the blog and I would be happy to write about it! Till then keep reading and keep sharing.
Reference : Here

iDev : A DOM Manipulation Class in 100 Lines of JavaScript

Hi Friends

A DOM Manipulation Class in 100 Lines of JavaScript By Krasimir Tsonev

If you build web applications you probably deal with the DOM a lot. Accessing and manipulating DOM elements is a common requirement of nearly every web application. Very often we collect information from different controls, we need to set values, change the content of div or span tags. Of course there are a lot of libraries that help handle these actions, with the most popular being jQuery, of course, which is the de factor standard. However, sometimes you don’t need everything that jQuery provides, so in this article we will take a look at how to build your own class for managing DOM elements.

The API

As developers we make decisions every day. I believe in the test-driven development and one of the things which I really like is the fact that it forces you to make design decisions before you start the actual coding. Along those lines, here is what I want the DOM management class’s API to look like in the end:

// returns DOM element dom(‘.selector’).el // returns the value/content of the element dom(‘.selector’).val()  // sets the value/content of the element dom(‘.selector’).val(‘value’)

This should cover most of the possible use cases. However it would be even better if we could manipulate several objects at once. And it would be great if we could generate a JavaScript object.

// generates an object containing DOM elements dom({     structure: {         propA: ‘.selector’,         propB: ‘.selector’     },     propC: ‘.selector’ })

Once we have our elements stored we could easily execute the val method for all of them.

// retrieving the values of several DOM elements dom({     structure: {         propA: ‘.selector’,         propB: ‘.selector’     },     propC: ‘.selector’ }).val()

This will be aneffective method for translating data from the DOM directly into a JavaScript object.

Now that we have an idea of what our API should look like, our class starts with the following code:

var dom = function(el) {     var api = { el: null }     api.val = function(value) {         // …     }     return api; }

Scoping

It is clear that we are going to use methods like getElementById, querySelector or querySelectorAll. Typically, you might access the DOM like this:

var header = document.querySelector(‘.header’);

What is really interesting here is that querySelector, for example, is not just a method of the document object, but also of any other DOM element. This means that we are able to run the query in specific context. For example:

<header>     <p>Big</p> </header> <footer>     <p>Small</p> </footer>  var header = document.querySelector(‘header’); var footer = document.querySelector(‘footer’); console.log(header.querySelector(‘p’).textContent); // Big console.log(footer.querySelector(‘p’).textContent); // Small

We are able to operate within specific part of the DOM tree and our class should support the passing of a scope. So, together with a selector it would be good if it accepts a parent element.

var dom = function(el, parent) {     var api = { el: null }     api.val = function(value) {         // …     }     return api; }

Reaching the DOM element

As we said above, we are going to use querySelector and querySelectorAll to reach the DOM elements. Let’s create two shortcuts for these functions.

var qs = function(selector, parent) {     parent = parent || document;     return parent.querySelector(selector); }; var qsa = function(selector, parent) {     parent = parent || document;     return parent.querySelectorAll(selector); };

After that we should use the passed el argument. Normally this will be a string (selector) but we should also support:

  • A DOM element – the val method of the class will be pretty handy so we may need to use the class with already referenced element;
  • A JavaScript object – in order to create JavaScript object containing multiple DOM elements.

The following switch will cover both cases:

switch(typeof el) {     case ‘string’:         parent = parent && typeof parent === ‘string’ ? qs(parent) : parent;         api.el = qs(el, parent);     break;     case ‘object’:          if(typeof el.nodeName != ‘undefined’) {             api.el = el;         } else {             var loop = function(value, obj) {                 obj = obj || this;                 for(var prop in obj) {                     if(typeof obj[prop].el != ‘undefined’) {                         obj[prop] = obj[prop].val(value);                     } else if(typeof obj[prop] == ‘object’) {                         obj[prop] = loop(value, obj[prop]);                     }                 }                 delete obj.val;                 return obj;             }             var res = { val: loop };             for(var key in el) {                 res[key] = dom.apply(this, [el[key], parent]);             }             return res;         }     break; }

The first case is executed if the developer passes a string. We prepare the parent and call the querySelector shortcut. The second part of the statement is for the cases where we have a DOM element sent or a JavaScript object. We are checking if the object has nodeName property, and, if it does, then we directly apply it as a value of the api.el property. If it doesn’t, then we go through all the parts of the object and initialize a class instance for every property. Here are some test cases involving the following markup:

<p>text</p> <header>     <p>Big</p> </header> <footer>     <p>Small</p> </footer>

Accessing the first paragraph:

dom(‘p’).el

Accessing the paragraph in the header node:

dom(‘p’, ‘header’).el

Passing a DOM element:

dom(document.querySelector(‘header’)).el

Passing a JavaScript object:

var els = dom({     footer: ‘footer’,     paragraphs: {         header: ‘header p’,         footer: ‘footer p’     } })) // At the end we have again JavaScript object. // It’s properties are actually results // of dom function execution. For example, to get // the paragraph in the footer: els.paragraphs.footer.el

Getting or setting the value of an element

The value of the form elements like input or select could be retrieved easily – we can use the value property of the element. We already have an access to the DOM element – it is stored in api.el. However, it is a little bit tricky when we are working with radio or check boxes. For the other HTML nodes like divs, sections or spans for example we need to get the value of the textContent property. If there is no textContent defined then innerHTML will produce similar results. Let’s use another switch statement:

api.val = function(value) {     if(!this.el) return null;     var set = !!value;     var useValueProperty = function(value) {         if(set) { this.el.value = value; return api; }         else { return this.el.value; }     }     switch(this.el.nodeName.toLowerCase()) {         case ‘input’:         break;         case ‘textarea’:         break;         case ‘select’:                       break;         default:     }     return set ? api : null; }

First of all we need to have api.el defined. The variable set is a boolean telling us if we are retrieving or setting the value of the element. There is a helper method defined for those elements which have .value property. The switch will contain the actual logic of the method. At the end we are returning the API itself in order to chain the methods of the class. Of course we are doing this only if we are using the function as a setter.

Let’s see how to handle the different types of elements. For example the input node:

case ‘input’:     var type = this.el.getAttribute(‘type’);     if(type == ‘radio’ || type == ‘checkbox’) {         var els = qsa(‘[name=”‘ + this.el.getAttribute(‘name’) + ‘”]’, parent);         var values = [];         for(var i=0; i<els.length; i++) {             if(set && els[i].checked && els[i].value !== value) {                 els[i].removeAttribute(‘checked’);             } else if(set && els[i].value === value) {                 els[i].setAttribute(‘checked’, ‘checked’);                 els[i].checked = ‘checked’;             } else if(els[i].checked) {                 values.push(els[i].value);             }         }         if(!set) { return type == ‘radio’ ? values[0] : values; }     } else {         return useValueProperty.apply(this, [value]);     } break;

This is may be the most interesting case. There are two types of elements which need to be processed differently – radio and check boxes. These elements are grouped into sets and we need to keep this in mind. That’s why we are using querySelectorAll to fetch the whole group and find out which one is selected/checked. It’s even more complex, because a group of check boxes could have more then one value. The method above successfully handles all these situations.

The processing of a textarea element is pretty simple thanks to the helper we wrote above.

case ‘textarea’:      return useValueProperty.apply(this, [value]);  break;

Here’s how we handle a drop down (select):

case ‘select’:     if(set) {         var options = qsa(‘option’, this.el);         for(var i=0; i<options.length; i++) {             if(options[i].getAttribute(‘value’) === value) {                 this.el.selectedIndex = i;             } else {                 options[i].removeAttribute(‘selected’);             }         }     } else {         return this.el.value;     } break;

And this will process everything else:

default:      if(set) {         this.el.innerHTML = value;     } else {         if(typeof this.el.textContent != ‘undefined’) {             return this.el.textContent;         } else if(typeof this.el.innerText != ‘undefined’) {             return typeof this.el.innerText;         } else {             return this.el.innerHTML;         }     } break;

With these lines of code we have finished our val method. Here is a short HTML form and its corresponding test:

<form>     <input type=”text” value=”sample text” />     <input type=”radio” name=”options” value=”A”>     <input type=”radio” name=”options” checked value=”B”>     <select>         <option value=”10″></option>         <option value=”20″></option>         <option value=”30″ selected></option>     </select>     <footer>version: 0.3</footer> </form>

If we use the following code:

dom({     name: ‘[type=”text”]’,     data: {         options: ‘[type=”radio”]’,         count: ‘select’     },     version: ‘footer’ }, ‘form’).val();

We will get:

{     data: {         count: “30”,         options: “B”     },     name: “sample text”,     version: “version: 0.3” }

This method could be really helpful if you want to translate a data from HTML form into JavaScript object. This is a pretty common task that many of us need to accomplish almost every day.

Final result

The finished class is only 100 lines of code but it still gives us what we need to access DOM elements and to get or set their value/content.

var dom = function(el, parent) {     var api = { el: null }     var qs = function(selector, parent) {         parent = parent || document;         return parent.querySelector(selector);     };     var qsa = function(selector, parent) {         parent = parent || document;         return parent.querySelectorAll(selector);     };     switch(typeof el) {         case ‘string’:             parent = parent && typeof parent === ‘string’ ? qs(parent) : parent;             api.el = qs(el, parent);         break;         case ‘object’:              if(typeof el.nodeName != ‘undefined’) {                 api.el = el;             } else {                 var loop = function(value, obj) {                     obj = obj || this;                     for(var prop in obj) {                         if(typeof obj[prop].el != ‘undefined’) {                             obj[prop] = obj[prop].val(value);                         } else if(typeof obj[prop] == ‘object’) {                             obj[prop] = loop(value, obj[prop]);                         }                     }                     delete obj.val;                     return obj;                 }                 var res = { val: loop };                 for(var key in el) {                     res[key] = dom.apply(this, [el[key], parent]);                 }                 return res;             }         break;     }     api.val = function(value) {         if(!this.el) return null;         var set = !!value;         var useValueProperty = function(value) {             if(set) { this.el.value = value; return api; }             else { return this.el.value; }         }         switch(this.el.nodeName.toLowerCase()) {             case ‘input’:                 var type = this.el.getAttribute(‘type’);                 if(type == ‘radio’ || type == ‘checkbox’) {                     var els = qsa(‘[name=”‘ + this.el.getAttribute(‘name’) + ‘”]’, parent);                     var values = [];                     for(var i=0; i<els.length; i++) {                         if(set && els[i].checked && els[i].value !== value) {                             els[i].removeAttribute(‘checked’);                         } else if(set && els[i].value === value) {                             els[i].setAttribute(‘checked’, ‘checked’);                             els[i].checked = ‘checked’;                         } else if(els[i].checked) {                             values.push(els[i].value);                         }                     }                     if(!set) { return type == ‘radio’ ? values[0] : values; }                 } else {                     return useValueProperty.apply(this, [value]);                 }             break;             case ‘textarea’:                  return useValueProperty.apply(this, [value]);              break;             case ‘select’:                 if(set) {                     var options = qsa(‘option’, this.el);                     for(var i=0; i<options.length; i++) {                         if(options[i].getAttribute(‘value’) === value) {                             this.el.selectedIndex = i;                         } else {                             options[i].removeAttribute(‘selected’);                         }                     }                 } else {                     return this.el.value;                 }             break;             default:                  if(set) {                     this.el.innerHTML = value;                 } else {                     if(typeof this.el.textContent != ‘undefined’) {                         return this.el.textContent;                     } else if(typeof this.el.innerText != ‘undefined’) {                         return typeof this.el.innerText;                     } else {                         return this.el.innerHTML;                     }                 }             break;         }         return set ? api : null;     }     return api; }

I’ve created a JSBin example that you can play with to see how the class works.

Summary

The class I discussed above is part of the AbsurdJS client-side components. The full documentation for the module could be found here. The aim of the code is not to replace jQuery or the dozens of popular libraries available for DOM access. The idea of the function is to be independent, to do only one thing and to do it well. Which is the main concept behind AbsurdJS and its build-in modules like the router or Ajax wrapper.

iDev:iOS 7 – NSURLSession

iOS 7 – NSURLSession

by Nicholas Cipollina 

NSURLConnection is the workhorse of networking code in the iOS 6 SDK, and virtually every app in the App Store uses it. NSURLConnection is both a class and a suite of related classes whose primary purpose is to either upload or download data to the web or even to the file system. In iOS 7, the networking stack has been overhauled to support NSURLSession, a completely rewritten and improved replacement API for NSURLConnection. NSURLConnection won’t be going away and is still supported; however, NSURLSession supports new, convenient behaviors that enable developers to easily support new iOS 7 features like background network requests. For this blog post I’m going to be discuss a sample app that downloads an image from the Internet, either in-process or in the background. If you’d like to skip right to it, the sample code it can be found on GitHub.

For Reference: Downloading An Image Using NSURLConnection

For comparison’s sake, the snippet below is a short implementation that represents how an iOS 6 application would use NSURLConnection.

NSURL *imageURL = [NSURL URLWithString:
@" http://www.nasa.gov/sites/default/files/ladee_9.4.13_nasa_edge_0.jpg";

NSURLRequest *request = [NSURLRequest requestWithURL:imageURL];
// Configure your request here.  Set timeout values, HTTP Verb, etc.
NSURLConnection *connection = 
         [NSURLConnection connectionWithRequest:request delegate:myConnectionDelegateClass];

This is a perfectly acceptable way to download data from the web, however NSURLSession will improve the behavior of requests similar to the one in this example.

What is NSURLSession?

NSURLSession is a replacement for NSURLConnection, and similarly it is both a distinct class and also a group of related APIs. It has is able to do everything NSURLConnection could do but also adds improvements on top. You may be asking yourself “if it is very similar to NSURLConnection, why replace it?” There are several reasons for this.

Instead of storing all of the networking objects (such as a response cache) globally, NSURLSession provides a mechanism for storing objects either on a global basis or on a per session basis. NSURLSession also provides better authentication handling, which is now done with an explicit authentication challenge on a connection basis instead of NSURLConnection’s request basis. NSURLSession provides a configurable container that applies to the session as opposed to configuration based solely on request. Probably the biggest improvement over NSURLConnection is NSURLSession’s support for out-of-process background transfers. This means that you can start a download of a large image or file, close the app and the download will continue until it completes. When the user re-launches the app, the app will be in the post-download state. This is possible because uploads and downloads are now done through the file system. This is beneficial because it optimizes battery life, uses the same delegate model as in-process transfers and supports UIKit multitasking.

The Classes of NSURLSession

NSURLSessionConfiguration is the first class you’ll probably work with in the NSURLSession API. It is a class that allows you to do exactly what its name suggests: configure your NSURLSession with connection/HTTP policies, caching behavior, maximum number of connections, custom headers, etc. For example, if you have a scenario where an authentication token is required to be passed in header on every call to a RESTful API, you can set the token in the session configuration and it will apply to all requests made using that session. With NSURLConnection, the token must be set on each and every request.

NSURLSessionConfiguration provides a few factory methods to create your session configuration. The methods are:

  • +defaultConfiguration – provides access to the global singleton storage and settings
  • +ephemeralSessionConfiguration – a private, in-memory only storage
  • +backgroundSessionConfiguration: – out-of-process configuration that is keyed to the identifier string. This identifier string is something you specify and must be unique for your app. It is used to retrieve the upload or download response by re-attaching to the previous session that used the identifier.

NSURLSessionTask is the class that actually replaces the NSURLConnection class. NSURLSessionTask provides properties that will show status and progress for the task as opposed to only being available in delegate methods. NSURLSessionTask supports the canceling, suspending or resuming an operation. There are a couple of NSURLSessionTask sub-classes that have been provided to differentiate between types of tasks: Data, Upload and Download. The upload and download tasks are the only types of tasks that can be run out-of-process, and the download task is the only task that can be paused and then resumed later.

There are also several delegates available in the NSURLSession API:

  • NSURLSessionDelegate – The single delegate for all NSURLSession messages. This applies to the session, task, data task and download task. TheNSURLSessionDelegate is strongly referenced and will exist until the session has been invliadted
  • NSURLSessionTaskDelegate – A delegate that provides messages for data, download or upload tasks.
  • NSURLSessionDataDelegate – Provides additional messages specific to data tasks.
  • NSURLSessionDownloadDelegate – Provides additional messages specific to download tasks.

NSURLSession is the class that manages all of the tasks. You use the NSURLSessionConfiguration class to configure your NSURLSession. You can use the public global configuration or you can provide custom sessions with private configuration with your sessions. The NSURLSession creates all of your data, upload and download task objects. It also provides several asynchronous convenience methods to perform operations without having to create your own tasks.

Downloading an Image Using NSURLSession

Now that we’ve been introduced to all the objects that make up NSURLSession API, let’s move on to writing code to download an image with NSURLSession. The sample application has two buttons: one to download the image in-process and the other to download the image in the background. To create our in-process session we simply do the following:

NSURLSessionConfiguration *configuration = 
    [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = 
     [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];

As you can see we are using the defaultSessionConfiguration to utilize the public storage area with our session. In this case we are performing all of the network interaction code inside of an NSOperation subclass that implements our delegate methods. By setting the delegateQueue to nil, we are letting the system create a serial operation queue for performing all delegate method calls and completion handler calls.

As I mentioned before we also want to be able to support downloading the image in a background process so that if the user starts the image download and switches to another app, the download will complete anyway. However, if the app is manually quit by the user or pruned by the OS and the download has not completed, it will not continue in the background. The code to create the background session looks like this:

NSURLSessionConfiguration *backgroundConfiguration 
   = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.captech.NSURLSample.BackgroundSession"];
NSURLSession *backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration
                                                          delegate:self
                                                     delegateQueue:nil];

This is very similar to the logic to create our in-process session with the exception of how the session configuration is created. In this case we create a background session named com.captech.NSURLSample.BackgroundSession.

Now that we have our session created, the next step is to create our download task:

NSURL *downloadURL = [NSURL URLWithString:self.downloadUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL];
self.downloadTask = [self.session downloadTaskWithRequest:request];
        [self.downloadTask resume];

First we create our an NSURLRequest with that URL passed into the operation. Creating the download task is as simple as calling thedownloadTaskWithRequest: method using the NSURLRequest we just made. You’ll notice after the task is created we have to call the resume method because by default all tasks that are created start out in the suspended state, and it won’t actually begin without calling it.

As I mentioned earlier, download tasks provide the ability to report on progress of the download as it’s occurring. The sample app has a progress indicator to show the progress of the image download. To wire this up we just have to implement:

URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:

in the class conforming to NSURLSessionDownloadDelegate. This looks like this:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
   didWriteData:(int64_t)bytesWritten 
    totalBytesWritten:(int64_t)totalBytesWritten 
     totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    if (downloadTask == self.downloadTask && self.progressAction){
        self.progressAction((double)totalBytesWritten, (double)totalBytesExpectedToWrite);
    }
}

Since the delegate is actually my NSOperation class running off the main thread, I didn’t want to directly update the UI in this method. Instead the operation has a block property (not shown below) where the UI can specify what happens when this didWriteData is called. The logic to actually update the progress indicator looks like this:

        double progress = bytesWritten / bytesExpected;
dispatch_async(dispatch_get_main_queue(), ^{
    self.progressView.progress = (float) progress;
});

We simply calculate the progress and update the indicator in the UI. Once the download task has completed, we need to hide our progress indicator and display the image on our screen. The sample app saves the image to the file system when complete:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
  didFinishDownloadingToURL:(NSURL *)location {
    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSArray *urls = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
    NSURL *documentsDirectory = [urls objectAtIndex:0];

    NSURL *originalUrl = [[downloadTask originalRequest] URL];
    NSURL *destinationUrl = [documentsDirectory URLByAppendingPathComponent:[originalUrl lastPathComponent]];
    NSError *error;

    [fileManager removeItemAtURL:destinationUrl error:NULL];
    BOOL success = [fileManager copyItemAtURL:location toURL:destinationUrl error:&error];
    if (self.completionAction){
        self.completionAction(destinationUrl, success);
    }
}

Just like with the progress updates, we won’t do any UI updates from our operation so there is a block on the operation (not shown in code sample below) to handle the updates. That logic looks like this:

dispatch_async(dispatch_get_main_queue(), ^{
    if (success){
        UIImage *image = [UIImage imageWithContentsOfFile:[imageUrl path]];
        self.downloadedImage.image = image;
    }
    self.downloadedImage.hidden = NO;
    self.progressView.progress = 0;
    self.progressView.hidden = YES;
    self.downloadOperation = nil;
});

If the operation was successful, we retrieve the image from the file system, update the UIImageView, then reset the progress indicator and hide it. Then we set our download operation to nil so that we can download the image again if we want to.

That covers the in-process download and it almost completes the out-of-process download as well, but we have a few other things to take care of to complete this. In our NSURLSessionDelegate we have to implement the URLSessionDidFinishEventsForBackgroundURLSession method so that we can call the app delegate completion handler for the background download. This completion handler lets the system know that your app’s user interface is updated and a new snapshot can be taken. Our implementation looks something like this:

CTAppDelegate *appDelegate = (CTAppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.backgroundSessionCompletionHandler) {
    void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
    appDelegate.backgroundSessionCompletionHandler = nil;
    completionHandler();
}

We store the completion handler as a property in the app delegate and call it once the background download is complete. The completion handler is passed to the app delegate by the operating system whenever the background download has completed. If the app becomes active before the download completes, the delegate will begin receiving callbacks again without any action required by the application.

The logic to actually start the download, either in-process or out-of process looks like this:

if (self.downloadOperation){
    return;
}

CTSessionOperation *operation = [CTSessionOperation new];
operation.downloadUrl = downloadUrl;
operation.progressAction = ^(double bytesWritten, double bytesExpected){
    double progress = bytesWritten / bytesExpected;
    dispatch_async(dispatch_get_main_queue(), ^{
        self.progressView.progress = (float) progress;
    });
};
operation.completionAction = ^(NSURL *imageUrl, BOOL success){
    dispatch_async(dispatch_get_main_queue(), ^{
        if (success){
            UIImage *image = [UIImage imageWithContentsOfFile:[imageUrl path]];
            self.downloadedImage.image = image;
        }
        self.downloadedImage.hidden = NO;
        self.progressView.progress = 0;
        self.progressView.hidden = YES;
        self.downloadOperation = nil;
    });
};
operation.isBackground = background;

[operation enqueueOperation];
self.downloadedImage.hidden = YES;
self.progressView.hidden = NO;
self.downloadOperation = operation;

We create a new instance of our CTSessionOperation and set all of the properties necessary to download our image. We then enqueue the operation on anNSOperationQueue, hide the UIImageView and show our progress indicator. The operation then does all the work to download the image.

As you can see, utilizing NSURLSession API is an easy and powerful way to interact with a network. This is a very simplified example of how you can write code to interact with a network, but the NSURLSession makes it very easy to do.

Thanks 🙂

iDev: iOS 7 SDK-Background Transfer Service

iOS 7 SDK: Background Transfer Service

This tutorial will show you how to use the background transfer service, a Multitasking API provided by iOS 7. I’ll teach you how to create an app that will download a file without the application in the foreground. Once the file fully downloads, a notification message will pop-up. Continue reading to create this service!

Introduction

Background transfer service originated with iOS 6. This feature allowed apps to transfer files in both foreground and background modes, but limited the minutes. The biggest problem was when the “limited minutes” did not allow the user to download or upload large files. This is why Apple improved the framework in iOS 7.

With iOS 7, this feature underwent major changes, including:

  • iOS manages downloads and uploads
  • The transfer continues even when the user closes the application
  • Time is unlimited
  • It can be put in the queue anytime (foreground and background)
  • The app wakes up to handle authentication, errors, or completion
  • The app includes a Progress View

Background Transfer Service can be used for several distinct and useful tasks such as: uploading photos or videos, combining background fetch and remote notifications, and for keeping the app up to date, like with purchases for books, TV shows, podcasts, game content, maps, and more.

1. Setup the Project

To create this service, we need a single view with the following properties:

  • A ViewController
  • A NavigationController
  • A Bar Item (to start the Download)
  • An UIDocumentInterationController (to open the PDF document download)

First, start a new Xcode iPhone project. Then create a Single View Application. Next, go to the Main.Storyboard and add some objects to our View. To add theNavigationController select the Default View Controller. In the Xcode menu, select Editor > Embed In > Navigation Controller. You need to drag-and-drop theBar Item and the Progress View to your View Controller. Once you’re finished the View Controller should look similar to the following image:

Figure 1: After Setup - Background Transfer!
Illustration of App – After Setup – Background Transfer

Now, let’s add the properties necessary to interact with the objects we added. InViewController.h, add the following lines:

1
2
3
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
- (IBAction)start:(id)sender;

Now change the view for the ViewController.m. A warning will appear, but don’t worry about it; we’ll fix it later. Go back to the Main.Storyboard and connect the objects with the properties and actions.

This step is trivial, but if you have any concerns feel free to use the comment section below.

2. NSURLSession

The NSURLSession class and related classes provide an API to download or upload content via HTTP. This API is responsible for managing a set of transfer tasks. You will need to create three objects that directly relate with that class: oneNSURLSessionNSURLSessionDownloadTask, andUIDocumentInteractionController.

Your ViewController.h will be something like this:

1
2
3
@property (nonatomic) NSURLSession *session;
@property (nonatomic) NSURLSessionDownloadTask *downloadTask;
@property (strong, nonatomic) UIDocumentInteractionController *documentInteractionController;

Additionally, you will also declare four protocols: NSURLSessionDelegate,NSURLSessionTaskDelegateNSURLSessionDownloadDelegate, andUIDocumentInteractionControllerDelegate. Your @interface should look like:

1
@interface ViewController : UIViewController < NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDownloadDelegate,UIDocumentInteractionControllerDelegate>

The properties we’ll add are useful to instantiate and manipulate our session and the download process, which will allow you to resume, suspend, cancel, or retrieve the state. The last property, UIDocumentInterationController is used to present the PDF document downloaded in this tutorial.

Now move to ViewController.m.

The first task to complete is to add a string to the location of the file to download. You should use a standard Apple PDF.

On the viewDidLoad method, let’s instantiate and set both the session and the progress views:

1
2
3
4
self.session = [self backgroundSession];
self.progressView.progress = 0;
self.progressView.hidden = YES;

Since you call the backgroundSession method, and it does not exist, you must declare it now. This method is responsible for dispatching one action that will be the background session. The backgroundSession through the dispatch_onceexecutes a block once for the entire lifetime of the application. The NSStringreceived by the NSURLSessionConfiguration represents the ID of our session. This ID needs to be unique for each NSURLSession instance.

The complete method is as follows:

1
2
3
4
5
6
7
8
9
- (NSURLSession *)backgroundSession {
  static NSURLSession *session = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.example.apple-samplecode.SimpleBackgroundTransfer.BackgroundSession"];
    session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
  });
  return session;
}

The (IBAction)start:(id)sender method starts the document download. You will then initiate an NSURL and a NSURLRequest and use the downloadTask property to pass the request object to the downloadTaskWithRequest method. The complete method is below.

01
02
03
04
05
06
07
08
09
10
11
- (IBAction)start:(id)sender {
  if (self.downloadTask) {
        return;
    }
  NSURL *downloadURL = [NSURL URLWithString:DownloadURLString];
  NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL];
  self.downloadTask = [self.session downloadTaskWithRequest:request];
    [self.downloadTask resume];
    self.progressView.hidden = NO;
}

3. Protocols

At this point, you’ll notice that three warnings are present. They state that the protocol method should be implemented. The NSURLSessionDownloadDelegateprotocol defines the methods to handle the download task. To perform the download, it’s required to use the three delegate methods.

So, add the following three methods:

  • 1. (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
  • 2. (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL {
  • 3. (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes

The (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite method is responsible to track the overall download process. It also updates the progressView accordingly. The complete method is below.

01
02
03
04
05
06
07
08
09
10
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    if (downloadTask == self.downloadTask) {
        double progress = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
        NSLog(@"DownloadTask: %@ progress: %lf", downloadTask, progress);
        dispatch_async(dispatch_get_main_queue(), ^{
            self.progressView.progress = progress;
        });
    }
}

4. Download Task

The (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL method deals with the data itself (origin and destination). It controls the file only once it’s completely downloaded. To put it simply, it tells the delegate that a download task has finished downloading. It contains the session task that’s finished, the download task that’s finished, and a file URL where the temporary file can be found. It should look like this:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *URLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
    NSURL *documentsDirectory = [URLs objectAtIndex:0];
    NSURL *originalURL = [[downloadTask originalRequest] URL];
    NSURL *destinationURL = [documentsDirectory URLByAppendingPathComponent:[originalURL lastPathComponent]];
    NSError *errorCopy;
    // For the purposes of testing, remove any esisting file at the destination.
    [fileManager removeItemAtURL:destinationURL error:NULL];
    BOOL success = [fileManager copyItemAtURL:downloadURL toURL:destinationURL error:&errorCopy];
    if (success) {
        dispatch_async(dispatch_get_main_queue(), ^{
            //download finished - open the pdf
            self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:destinationURL];
            // Configure Document Interaction Controller
            [self.documentInteractionController setDelegate:self];
            // Preview PDF
            [self.documentInteractionController presentPreviewAnimated:YES];
            self.progressView.hidden = YES;
        });
    } else {
        NSLog(@"Error during the copy: %@", [errorCopy localizedDescription]);
    }
}

Finally, the (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes must also be declared. But be aware that we wont use it any further.

1
2
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {
}

5. Session Tasks

You’re almost done with this class, only two methods remain: (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error, and - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session.

The first method informs the delegate that the task has finished transferring data. You should also use it to track any error that occurs.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    if (error == nil) {
        NSLog(@"Task: %@ completed successfully", task);
    } else {
        NSLog(@"Task: %@ completed with error: %@", task, [error localizedDescription]);
    }
    double progress = (double)task.countOfBytesReceived / (double)task.countOfBytesExpectedToReceive;
  dispatch_async(dispatch_get_main_queue(), ^{
    self.progressView.progress = progress;
  });
    self.downloadTask = nil;
}

Finally, you need to add the(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session method. It tells the delegate that all messages enqueued for a session have been delivered. It instantiates your AppDelegate in order to launch aUILocalNotification. The method you need to use is:

01
02
03
04
05
06
07
08
09
10
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    if (appDelegate.backgroundSessionCompletionHandler) {
        void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
        appDelegate.backgroundSessionCompletionHandler = nil;
        completionHandler();
    }
    NSLog(@"All tasks are finished");
}

Several errors will appear because you haven’t imported the AppDelegate.h into your class yet.

1
#import "AppDelegate.h"

Move to the AppDelegate.h and add the two following objects:

1
2
3
@property (strong, nonatomic) UIWindow *window;
@property (copy) void (^backgroundSessionCompletionHandler)();

In the AppDelegate.m you should implement the delegate method(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler. It tells the delegate that events related to a URL session are waiting to be processed and calls a custom method (presentNotification) to notify the user when the file completely downloads. The complete method is:

1
2
3
4
5
6
7
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier
  completionHandler:(void (^)())completionHandler {
  self.backgroundSessionCompletionHandler = completionHandler;
    //add notification
    [self presentNotification];
}

6. Local Notification

The presentNotification method uses the UILocalNotification class to create a local notification. It creates a sound and uses the badge system for that notification. Here’s the complete method:

01
02
03
04
05
06
07
08
09
10
11
12
13
-(void)presentNotification{
    UILocalNotification* localNotification = [[UILocalNotification alloc] init];
    localNotification.alertBody = @"Download Complete!";
    localNotification.alertAction = @"Background Transfer Download!";
    //On sound
    localNotification.soundName = UILocalNotificationDefaultSoundName;
    //increase the badge number of application plus 1
    localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
    [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}

By the way, to restart the counter on the top left at the App Icon, you must add the following line to the (void)applicationDidBecomeActive:(UIApplication *)application method in the AppDelegate.

1
application.applicationIconBadgeNumber = 0;

The notification should be similar to the following image:

Figure 2: Notification!
Illustration of App – Notification – MTBackgroundTransfer

It is now time to Run the app and test the background download.

Conclusion

At the end of this tutorial, you should have completed your background transfer service in iOS 7. You should understand the background transfer service and how to implement it. If you have any questions, please leave them in the comment section below.

iDev : Create, Rename, Delete, Read and Write File on iOS Functions

Hi Friends,

On iOS Programming, one of the most frequent tasks is Manipulation with Files. Using Local Files is one of the most efficient way to store your local data, other ways may include NSUserDefault, Core Data, but local files is very easy to be implemented and organized. So in this tutorial, we will focus on 5 main manipulation related to Local File on iOS.

Before we get started, we first should know what files have been stored in your app’s sandbox. As you might know, every app on iPhone is like an island, usually we name it SandBox. It contains AppName.app, Library folder, tmp folder and Document folder. User usually have their data stored in Document folder if they choose to use local file to store their data because other folders are not designed to store user’s data. So here we use Document Folder to give our test.

So, let’s list all the files exists in Document Folder in our Sandbox.

 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

– (void)listAllLocalFiles

{

// Fetch directory path of document for local application.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

// NSFileManager is the manager organize all the files on device.

NSFileManager *manager = [NSFileManager defaultManager];

// This function will return all of the files’ Name as an array of NSString.

NSArray *files = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];

// Log the Path of document directory.

NSLog(@”Directory: %@”, documentsDirectory);

// For each file, log the name of it.

for (NSString *file in files) {

NSLog(@”File at: %@”, file);

}

}

1, Create a File in the Document Folder.

 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

– (void)createFileWithName:(NSString *)fileName

{

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];

NSFileManager *manager = [NSFileManager defaultManager];

// 1st, This funcion could allow you to create a file with initial contents.

// 2nd, You could specify the attributes of values for the owner, group, and permissions.

// Here we use nil, which means we use default values for these attibutes.

// 3rd, it will return YES if NSFileManager create it successfully or it exists already.

if ([manager createFileAtPath:filePath contents:nil attributes:nil]) {

NSLog(@”Created the File Successfully.”);

} else {

NSLog(@”Failed to Create the File”);

}

}

2, Delete a File in the Document Folder.

 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

– (void)deleteFileWithName:(NSString *)fileName

{

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

// Have the absolute path of file named fileName by joining the document path with fileName, separated by path separator.

NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];

NSFileManager *manager = [NSFileManager defaultManager];

// Need to check if the to be deleted file exists.

if ([manager fileExistsAtPath:filePath]) {

NSError *error = nil;

// This function also returnsYES if the item was removed successfully or if path was nil.

// Returns NO if an error occurred.

[manager removeItemAtPath:filePath error:&error];

if (error) {

NSLog(@”There is an Error: %@”, error);

}

} else {

NSLog(@”File %@ doesn’t exists”, fileName);

}

}

3, Rename a File in the Document Folder.

 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

– (void)renameFileWithName:(NSString *)srcName toName:(NSString *)dstName

{

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *filePathSrc = [documentsDirectory stringByAppendingPathComponent:srcName];

NSString *filePathDst = [documentsDirectory stringByAppendingPathComponent:dstName];

NSFileManager *manager = [NSFileManager defaultManager];

if ([manager fileExistsAtPath:filePathSrc]) {

NSError *error = nil;

[manager moveItemAtPath:filePathSrc toPath:filePathDst error:&error];

if (error) {

NSLog(@”There is an Error: %@”, error);

}

} else {

NSLog(@”File %@ doesn’t exists”, srcName);

}

}

4, Read a File in the Document Folder.

 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

/* This function read content from the file named fileName.

*/

– (void)readFileWithName:(NSString *)fileName

{

// Fetch directory path of document for local application.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

// Have the absolute path of file named fileName by joining the document path with fileName, separated by path separator.

NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];

// NSFileManager is the manager organize all the files on device.

NSFileManager *manager = [NSFileManager defaultManager];

if ([manager fileExistsAtPath:filePath]) {

// Start to Read.

NSError *error = nil;

NSString *content = [NSString stringWithContentsOfFile:filePath encoding:NSStringEncodingConversionAllowLossy error:&error];

NSLog(@”File Content: %@”, content);

if (error) {

NSLog(@”There is an Error: %@”, error);

}

} else {

NSLog(@”File %@ doesn’t exists”, fileName);

}

}

5, Write a File in the Document Folder.

 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

/* This function Write “content” to the file named fileName.

*/

– (void)writeString:(NSString *)content toFile:(NSString *)fileName

{

// Fetch directory path of document for local application.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

// Have the absolute path of file named fileName by joining the document path with fileName, separated by path separator.

NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];

// NSFileManager is the manager organize all the files on device.

NSFileManager *manager = [NSFileManager defaultManager];

// Check if the file named fileName exists.

if ([manager fileExistsAtPath:filePath]) {

NSError *error = nil;

// Since [writeToFile: atomically: encoding: error:] will overwrite all the existing contents in the file, you could keep the content temperatorily, then append content to it, and assign it back to content.

// To use it, simply uncomment it.

//        NSString *tmp = [[NSString alloc] initWithContentsOfFile:fileName usedEncoding:NSStringEncodingConversionAllowLossy error:nil];

//        if (tmp) {

//            content = [tmp stringByAppendingString:content];

//        }

// Write NSString content to the file.

[content writeToFile:filePath atomically:YES encoding:NSStringEncodingConversionAllowLossy error:&error];

// If error happens, log it.

if (error) {

NSLog(@”There is an Error: %@”, error);

}

} else {

// If the file doesn’t exists, log it.

NSLog(@”File %@ doesn’t exists”, fileName);

}

// This function could also be written without NSFileManager checking on the existence of file,

// since the system will atomatically create it for you if it doesn’t exist.

}

Appending the file and add another text continously used this on Write menthod

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSString *docPath = [documentsDirectory stringByAppendingPathComponent:@”File.txt”];

NSString *appendString = //Your appending string ;

NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:docPath];

[myHandle seekToEndOfFile];

[myHandle writeData:[savedString dataUsingEncoding:NSUTF8StringEncoding]];

Also, similar API applies to URL and Directory. Check Apple’s Doc for more details.