Wednesday, March 30, 2016

How to change the color or font style of a word or a character within a single UILabel?

In iOS, usually while displaying a heading or topic name or any sort of text within our app, we generally assign our string to a UILabel. 
But suppose what if, If we have a requirement like if you want to highlight a particular word or letter in between a single string or what if you want to change color of a specific character or a word in between a string?
Do you add multiple UILabel's to achieve this?, Isn't that sounds weird? of-course right :), so what is the best approach to achieve this then?
Here is a solution, by using NSMutableAttributedString you can achieve this just by using one single UILabel.

In the below example I have created a category method for NSMutableAttributedString, since the scope of this highlighting method will be existing throughout my application, if you need this in only one place then go and create an instance method within your implementation class, its up to you.


My NSMutableAttributedString category method is like below,
- (void)highlightText:(NSString *)highlightString withFont:(UIFont *)font andColor:(UIColor *)color
{
    NSRange range = [self.mutableString rangeOfString:highlightString options:NSCaseInsensitiveSearch];
    
    if (range.location != NSNotFound)
    {
        [self addAttribute:NSFontAttributeName value:font range:range];
        [self addAttribute:NSForegroundColorAttributeName value:color range:range];
    }
}
and in my calling class I can just call this category method and pass the specific word or letter which needs to be highlighted to this method with required style and color as a parameters and my job is done.
Here in the below example, I am highlighting “iOS” and “Apple” word in my string with different font style and color, so my calling class code snippet is like below,

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"iOS is Apple's mobile OS"];
    [attributedString highlightText:@"iOS" withFont:[UIFont fontWithName:@"AmericanTypewriter-Bold" size:25.0] andColor:[UIColor redColor]];
    [attributedString highlightText:@"Apple" withFont:[UIFont fontWithName:@"Georgia" size:35.0] andColor:[UIColor greenColor]];
    _attributedLabel.attributedText = attributedString;

and the output of this is as below,
Reference screenshot for NSAttributedString


For more information on this refer Apple's official documentation here,

Hope this post is helpful, any comments or suggestions are acceptable.

Friday, August 28, 2015

Whats new in iOS 9

In this article I will cover some of the major features and functionalities of iOS 9 and what are the main aspects we should keep in mind so as to make our apps iOS 9 compatible one.

Existing apps will function normally in iOS 9, Ideally Apple will take care of it; which is nothing but “Forward Compatibility”, as it was managing this before in its earlier version releases.

If you want to release an update of your existing app or you are going to release a brand new iOS app, in which you wish to make use of iOS 9 features and make your app compatible with iOS 9 then you need to take care of few stuffs, 

Prerequisites for iOS 9: Xcode 7; iOS 9 SDK is compatible with Xcode 7, So the first and foremost thing any one wants to do is download Xcode 7 from developer.apple.com and start using iOS 9.0 SDK.

Before going in to details here is a quick snapshot on crucial points on iOS 9.0,

- Multitasking Enhancements for iPad
- App Transport Security(Adopt/Migrate your web-services to HTTPS asap)
- App Thinning
- Search
- Support for Right-to-Left Languages
- Contacts and Contacts UI
- UI Testing in Xcode 7

1) Multitasking Enhancements for iPad:
iOS 9 enhances the user’s multitasking experience on iPad with Slide Over, Split View, and Picture in Picture

- The Slide Over(below is the reference image) feature lets users pick a secondary app and quickly interact with it.


- The Split View(below is the reference image) feature gives users the ability to use two apps side by side on iPad, both the apps were responsive for user interaction and will run in parallel. 



- The Picture in Picture feature (also known as PiP - below is the reference image) lets users watch video in a window that floats above other onscreen apps.
Picture in Picture feature is for apps whose primary role is video playback.


Apple recommends for existing apps to adopt multitasking enhancements of iOS9 on iPad,If you are releasing any new iPad app or releasing an update for the existing app, Its better that if you adapt your apps for multitasking since users will be expecting all apps with Slide Over, Split View, and Picture in Picture features of iOS 9.

Note: For apps which you are planning to support multitasking enhancements make sure that you are supporting all the interface orientation.” You need to explicitly add the  UIRequiresFullScreen key to our Xcode project’s Info.plist file and apply the Boolean value YES from next update/new release.”

- SplitView functionality will work only from iPad Air 2 and above(with upcoming iPad devices).
- SlideOver and Picture in Picture functionality will work on iPad Mini 2,iPad Mini 3,iPad Air,iPad Air 2 (and with upcoming iPad devices).

Reference for Implementation:

2) App Transport Security

App Transport Security is a feature that requires secure connections between an app and web services. 

Here is a note from Apple mentioned on developer site: “You should adopt ATS as soon as possible, regardless of whether you’re creating a new app or updating an existing one.”

“If you’re developing a new app, you should use HTTPS exclusively. If you have an existing app, you should use HTTPS as much as you can right now, and create a plan for migrating the rest of your app as soon as possible. In addition, your communication through higher-level APIs needs to be encrypted using TLS version 1.2 with forward secrecy. If you try to make a connection that doesn't follow this requirement, an error is thrown. If your app needs to make a request to an insecure domain, you have to specify this domain in your app's Info.plist file.”

Reference for Implementation:

So go ahead instantly and migrate your web-services to HTTPS, if you are developing new services then by default opt for HTTPS services.

For a temporary fix or to bypass App Transport Security in your app, refer http://just-works.blogspot.in/2015/08/how-to-make-http-services-work-on-ios-9.html


3) App Thinning

The App Store and operating system optimize the installation of iOS apps by tailoring app delivery to the capabilities of the user’s particular device, with minimal footprint. This optimization, called app thinning.

If you adopt App thinning within your apps, then apps will occupy minimum disk space, faster downloads from App store.

App Thinning includes three components: slicing, bitcode, and on-demand resources.

- In general Slicing is recommended as a best practice for every app as-well as developer,
Since Slicing will check the user’s iOS device and based on that specific device it will send a specific installation package(unnecessary resource files will not be included in the package during download process(.ipa))
Below is a reference image(pictorial representation) on how App Thinning will work,



- Bitcode is an intermediate representation of a compiled program. Apps you upload to iTunes Connect that contain bitcode will be compiled and linked on the App Store. Including bitcode will allow Apple to re-optimize your app binary in the future without the need to submit a new version of your app to the store.

Note: For iOS apps, bitcode is the default, but optional. If you provide bitcode, all apps and frameworks in the app bundle need to include bitcode. 

- On-demand resources are resources—such as images and sounds—that you can tag with keywords and request in groups, by tag. The App Store hosts the resources on Apple servers and manages the downloads for you. On-demand resources enable faster downloads and smaller app sizes, improving the first-time launch experience. For example, a game app may divide resources into game levels and request the next level of resources only when the app anticipates that the user will move to that level. Similarly, the app can request In-App Purchase resources only when the user buys the corresponding in-app purchase.
Below is a reference image(pictorial representation) on how On-demand resources will work,


Reference for Implementation:

4) Search

Search in iOS 9 gives users great new ways to access information inside of your app, even when it isn’t installed. 
If you adopt iOS 9 Search feature in your apps, it helps you to increase the usage of your app and improve its discoverability by displaying the app content(description of the app) when users search across the system and on the web; even when your app is not installed in users device.

Reference for Implementation:
iOS 9 introduces the following APIs to adopt Search:



5) Support for Right-to-Left Languages

iOS 9 brings comprehensive support for right-to-left languages, which makes it easier for you to provide a flipped user interface.

Arabic, Persian, Urdu are few of the examples for Right to Left languages.

Reference for Implementation:

6) Contacts and Contacts UI

iOS 9 introduces the Contacts and Contacts UI frameworks (Contacts.framework and ContactsUI.framework), which provide modern object-oriented replacements for the Address Book and Address Book UI frameworks.

Reference for Implementation:


7) UI Testing in Xcode 7

Find and interact with UI elements, Validate the UI properties and state, UI recording.
- Xcode 7 introduces UI testing as a major new feature of the existing XCTest framework.
- Now from Xcode 7 and iOS 9 their is a native support for both Unit testing and UI testing.

Reference for Implementation:

Go ahead and explore and make use of this amazing native UI Automation testing support for your apps from Apples Xcode.

For more information & additional new features of iOS 9 refer Apple's official documentation here, https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS9.html

Hope this post is helpful, any comments or suggestions are acceptable and appreciated.

How to make http services work on iOS 9 or how to bypass App Transport Security(ATS) of iOS 9?


By default in iOS 9 if we try to load an HTTP resource in your app it's actually going to try to load the HTTPS version. If the HTTPS version is using security which Apple considers weak, or the server just doesn't support HTTPS at all, the request will fail.

But as a temporary fix for this without migrating your existing services to https is to add Pre-Domain exceptions to your applications info.plist file as below,

1) If you know all the insecure domains which you need to use in our app, then go for the below solution,

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>yourserver.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow HTTP requests-->
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

2) If you don’t know all the insecure domains which you need to use or if you want to completely allow any http request to work within your app, then go for the below solution(add those keys to your apps info.plist file),

<key>NSAppTransportSecurity</key>
<dict>
  <!--Include to allow all connections-->
  <key>NSAllowsArbitraryLoads</key>
      <true/>
</dict>

Below is a pictorial representation of this solution in the actual info.plist file, for your reference,




NOTE: Disabling or Bypassing App Transport Security is not a good idea and its not recommended by Apple. This is just a temporary fix until you implement App Transport Security for your app. Since It's yet to be seen how hard Apple will come down during app review in the coming years about ATS exceptions we request.

Why Apple is forcing us to implement ATS or to use secure connections is for protecting personal data from being compromised over insecure wireless connections, and making sure our users online activity is properly secured from unwanted network snooping.

The permanent fix for this problem is to go ahead and implement App Transport Security by considering Apple recommended security practices.

While migrating the services from http to https protocol you must consider the Apple recommended security practices listed below,

The protocol Transport Layer Security (TLS) must be at least version 1.2.

Connection ciphers are limited to those that provide forward secrecy.

Certificates must use at least an SHA256 fingerprint with either a 2048 bit or greater RSA key, or a 256 bit or greater Elliptic-Curve (ECC) key.


For more information on this refer Apple's official documentation here, https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/index.html

Hope this post is helpful, any comments or suggestions are acceptable and appreciated.


Monday, September 22, 2014

Improving performance when dealing with layer properties or Core Animation

Prior or subsequent to this post I recommend you guys to take a look in to one of my another post related to enhancing performance and memory management of an iOS app here, http://just-works.blogspot.in/2014/05/how-to-manage-memory-and-enhance.html
Before going in to depth there is a quick snapshot below for those who don’t want to dig in but just want a quick instant solution w.r.t improving performance when dealing with layer properties of UIView,
1)   Use Opaque Layers Whenever Possible. i.e; set opaque property to YES, whenever it is possible.
2)   Use Simpler Paths for CAShapeLayer Objects i.e; While drawing shape layers it is recommended to break up complex shapes into simpler shapes. 
3)   Specify a Shadow Path when adding a shadow to your view’s layer. i.e; make use of layers shadowPath property when you are dealing with layers shadow effect. 
4)   Use Asynchronous Layer rendering whenever required (if and only if really required). i.e; set drawsAsynchronously boolean property to YES whenever required, so as to process your drawing commands asynchronously in a background thread. 
5)   Use  shouldRasterize boolean property, If you have a complex view (i.e. relatively expensive to re-render) that you are animating, but for which the animated view is not itself changing, rasterizing the layer can improve the performance by not re-rendering the layer all the time.
shouldRasterize will consume memory for saving a rasterized image in memory, so use this whenever it is really required.
Bit more description/explanation on above points,
1) Use Opaque Layers Whenever Possible. i.e; set opaque property to YES, whenever it is possible.
- A Boolean value indicating whether the layer contains completely opaque content.
- The default value of this property is NO.
- Declare Views as Opaque Whenever Possible
Setting the opaque property of your layer to YES lets Core Animation know that it does not need to maintain an alpha channel for the layer. Not having an alpha channel means that the compositor does not need to blend the contents of your layer with its background content, which saves time during rendering.
Setting the value of this property to YES for a custom view tells UIKit that it does not need to render any content behind your view. Less rendering can lead to increased performance for your drawing code and is generally encouraged. Of course, if you set the opaque property to YES, your view must fills its bounds rectangle completely with fully opaque content.
The iPhone GPU is a tile-based renderer. If an overlaying layer is completely opaque over an entire tile, the GPU can ignore setting up and processing any graphics commands related to the layer underneath for that particular tile, in addition to not having to do compositing of the pixels in that tile.
2) One way to minimize drawing time for shape layers is to break up complex shapes into simpler shapes. Using simpler paths and layering multiple CAShapeLayer objects on top of one another in the compositor can be much faster than drawing one large complex path. That is because the drawing operations happen on the CPU whereas compositing takes place on the GPU. 
3) shadowPath - The shape of the layer’s shadow.
when ever we are using CALayer animation or for shadow effects, we usually see a jerk in rendering those views if the transition view consists of huge graphics or utilizing more layer properties of view, especially in lower versions of iOS devices.
So as to avoid this jerk on rendering and optimizing performance we have to set shadowPath property when we are setting layers shadow effects.
- The default value of shadowPath property is nil, which causes the layer to use a standard shadow shape. If you specify a value for this property, the layer creates its shadow using the specified path instead of the layer’s composited alpha channel.
- Specifying an explicit path usually improves rendering performance. 
- The value of this property is retained using the Core Foundation retain/release semantics. 
- When you specify a path object for this property, Core Animation uses that shape to draw and cache the shadow effect.
- For layers whose shape never changes or rarely changes, this greatly improves performance by reducing the amount of rendering done by Core Animation. 
Below code snippet is an example of setting shadow path for a view's layer which is having rounded corners,
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(10.0, 10.0)];
view.layer.shadowPath = path.CGPath;
Note: Your code will vary depending on the actual shape of your view. UIBezierPath has many convenience methods, you can get more info on this over here, https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIBezierPath_class/
- You will need to update the layer’s shadowPath each time the bounds of your view change. And if you’re animating a change to bounds, then you will also need to animate the change to the layer’s shadowPath to match. 
- This property will drastically improves view rendering performance.
4) drawsAsynchronously - Use Asynchronous Layer rendering whenever required.
- drawsAsynchronously is a boolean indicating whether drawing commands are deferred and processed asynchronously in a background thread. 
- The default value for this property is NO. 
- Any drawing that you do in your delegate’s drawLayer:inContext: method or your view’s drawRect: method normally occurs synchronously on your app’s main thread. 
- In some situations, though, drawing your content synchronously might not offer the best performance. If you notice that your animations are not performing well, you might try enabling the drawsAsynchronously property on your layer to move those operations to a background thread. 
- Make sure your drawing code is thread safe whenever you are using drawsAsynchronously property. 
Note: Always, you should always measure the performance of drawing asynchronously before putting it into your code. 
5) shouldRasterize a boolean that indicates whether the layer is rendered as a bitmap before compositing 
- The default value of this property is NO. 
- When animating a complex set of layers that, themselves, are not changing, you can set shouldRasterize to YES, do the animation, and then turn off shouldRasterize. 
- If you have a complex view i.e; views expensive to re-render, that you are animating, but for which the animated view is not itself changing, rasterizing the layer can improve the performance by not re-rendering the layer all the time. 
- When the value of this property is YES, the layer is rendered as a bitmap in its local coordinate space and then composited to the destination with any other content. 
- Shadow effects and any filters in the filters property are rasterized and included in the bitmap. 
Note: shouldRasterize will consume memory for saving a rasterized image in memory, so use this whenever it is really required. 
Hope this post is helpful, any comments or suggestions are acceptable.

Wednesday, May 28, 2014

How to change status bar appearance in iOS 7

If your iOS applications minimum deployment target is iOS7.0 and above and if you have a dark background in your app then you can’t see the status bar text, since in iOS 7.0 and above status bar is transparent by default.
If the background of your view is black(or any dark color) then your status bar will not be visible, and looks something like below snapshot,

So here is a way to make your status bar text visible in dark background,
1) Add "View controller-based status bar appearanceproperty (key is UIViewControllerBasedStatusBarAppearance) to your applications info.plist and set the value to NO.

2) Go to your applications AppDelegate.m file and add the below code snippet in didFinishLaunchingWithOptions method,
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

If you have done with the above 2 points then you are 90% done except your status bar will not be visible during the time of splash screen display, 
To make your status bar visible when splash screen is displaying with dark background, just do the below mentioned step,

3) Add "Status Bar Style" property (key is UIStatusBarStyle) to your applications info.plist and set the value to “Transparent black style (alpha of 0.5)” (key is UIStatusBarStyleLightContent).

and we are 100% done now,,, :)

Now if you run your app you can able to see status bar as shown in the below snapshot,


Hope this post is helpful,any comments or suggestions are acceptable.

Wednesday, May 21, 2014

How to manage memory and enhance performance of an iOS app

One of the major things in any mobile application development is a memory management and performance enhancement,

Here is an instant guide or list of few crucial points w.r.t. enhancing our apps memory management, in turn performance optimizations in our iOS application, which I came across in my daily life and spent lot of time in fixing it, thought it would be great or it may save someones valuable time and energy if I share my note on this regard,

Here we go,
1) Better to make all IBOutlet objects as __weak reference in ARC environment. Except for those from file’s owner to top-level objects in a xib(nib or a storyboard scene) file which should be strong. Outlets that you create typically should be weak by default.

2) Instead of calling init constructor method every time when pushing/navigating to a view controller/view call init only once and until and unless the viewController object reference exists in memory use the same reference to navigate.

Ex:-  Suppose we are navigating from Home screen to a DetailViewController then create an iVar of DetailViewController globally and in your push method check for this iVar reference in memory and navigate like,
if(detailVCObj)
{
            detailVCObj = [[DetailViewController alloc] initWithNibName:@”DetailViewController” bundle:nil];//if object reference is not their in memory then only alloc and initilize
}
[self.navigationController pushViewController:detailVCObj animated:YES];

and suppose if you want to set some property values before pushing a view controller then create your custom getter and setter methods for those properties and call those methods before pushing view whenever you are following the above protocol.
By doing this(by following this protocol) it will optimize memory consumption during runtime. Follow this protocol even in ARC enabled projects.

        3) In ARC enabled projects, assign nil to all re-creatable objects and iVars after making use of these objectsso as to handle memory in an optimized manner.

In MRC (Manual Reference Counting) type of projects release re-creatable objects and iVars and then assign nil, after making use of these objects.
Assigning nil is equivalent to release and dereference in ARC.
Ex:-
a) In ARC enabled environment,  myiVar = nil;
b) In MRC environment,
[myiVar release];//releasing  object
myiVar = nil;//dereferencing the object

4)  Avoid using images up to the maximum extent in your app, and try to achieve the design by using colors wherever and whenever it is possible for you.

Since this will optimize both time complexity (load time for image is more compared to a UIColor) and space complexity (size of .ipa file will be reduced drastically if we avoid images).
If you are using images then based on your requirement and particular instance which UIImage method to use? refer this link

5) Make use of Singleton design pattern in your application wherever it is required and can be used.

Ex:- Suppose if you are calling some of the methods of a class frequently in your app, like a database model class in your app will be called frequently for either to insert or to fetch or to update different tables and its entities. Make this class as a singleton class so that even if you make n number of calls to this class methods single object will manipulate the functionality.
For more information on important design patterns in iOS refer this link

6) Whenever you are making a core data fetch call use includesPropertyValues where ever possible, refer this link for further details on this API.

7) Keep track of temporary memory buffers and reuse it, and don’t keep unused memory, free it up as soon as you are done using it.

8) iOS will automatically kills the background processes and apps which consumes more memory and causes memory pressure during low memory conditions, its every programmer responsibility to handle low memory conditions inside our app as-well.


During low memory conditions iOS UIKit framework will send few notifications to our app,
- Implement the applicationDidReceiveMemoryWarning: method of your application delegate.
- Override the didReceiveMemoryWarning method in your custom UIViewController subclass.
- Register to receive the UIApplicationDidReceiveMemoryWarningNotification notification.

Upon receiving any of these notifications, your handler method should respond by immediately removing strong references to objects
View controllers automatically remove references to views that are currently offscreen, but you should also override the didReceiveMemoryWarning method and use it to remove any additional references that your view controller does not need.

9) Use Instruments and Static Analyzer Xcode tools to check your app specific memory stats, and take further actions w.r.t. memory allocations, memory pressure and memory leaks.





Hope this post was helpful, any comments or suggestions are acceptable.
-