Tuesday, December 5, 2017

Difference between weak self and unowned self #iOS #swift

If you remember the Automatic Reference Counting(ARC) concept, you must heard about retain cycle or Strong reference cycle.

I will explain about what is retain cycle. Let's go through the below example

class Person {
    var name:String
    var address:String
    var apartment:Apartment?
    init(name:String, address:String) {
        self.name = name
        self.address = address
    }
    deinit {
        debugPrint("Person class - Deinit method called")
    }
}

class Apartment {
    var name:String
    var personDetails:Person?
    init(name:String) {
        self.name = name
    }
    deinit {
        debugPrint("Apartment class - Deinit method called")
    }
}

var person:Person?
var apartment:Apartment?
person = Person.init(name: "John", address: "CA")
apartment = Apartment.init(name: "My Apartment")

person?.apartment = apartment
apartment?.personDetails = person

person = nil

apartment = nil

Are you getting shocked why deinit function not getting called. Welcome to retain cycle concept.

Even though you are making class instance to nil, both class instance parameters (apartment and personDetails) having strong reference with each other. whenever you create the instance or assigning the instance to some other variable it will create a strong reference.

Now the challenge is to break this retain cycle to deinitialize the classes from memory. How can we achieve this?

Just add weak keyword before the apartment variable.

class Apartment {
    var name:String
    weak var personDetails:Person?
    init(name:String) {
        self.name = name
    }
    deinit {
        debugPrint("Apartment class - Deinit method called")
    }
}

That's it. Now automatically both classes will remove from memory.

Weak Self vs Unowned Self:

Like class, closures also reference type. So, when you are accessing any Self instance params inside the closures, it will create the strong reference. To avoid this, we need to use either weak self or unowned self.

Both unowned and weak kind of optional, but weak variable initialised with nil. But unowned must have non-nil values. You have to use unowned, only if you know that the instance definitely will be there in memory. If you try to access the self variable after it released from memory your app will crash. So, better to use weak self inside the closures. Lets see one example to understand this better.

class ViewController:UIViewController {
    var name:String = "David!"
    override func viewDidLoad() {
        super.viewDidLoad()
        print(printNameWithHello())
    }
    
    private func printNameWithHello() -> String {
        let signature:String = { [weak self] in
            guard let string = self?.name else { fatalError("Unable to access name")}
                return "Hello" + string
        }()
        return signature
    }
}

The example I have given above is just for your understanding. Here the function is safe, because closure can't access the Self variable name if it is not in memory.

class ViewController:UIViewController {
    var name:String = "David!"
    override func viewDidLoad() {
        super.viewDidLoad()
        print(printNameWithHello())
    }
    
    private func printNameWithHello() -> String {
        let signature:String = { [unowned self] in
                return "Hello" + self.name
        }()
        return signature
    }
}

See the above unowned self example, it will try to access the value from memory even after it got released. So, app will be crash. Here you can't check self.name != nil because it is non-optional value.

Hope you understand about Retain cycle and the difference between weak self and unowned self.

!! Happy Coding !! :)

Add custom font in Xcode project

Here I am going to discuss about, how to add the custom font in your Xcode project. Also will discuss about, what mistake will developer do while adding custom fonts.

Step 1:

First download the custom fonts and add it in your project folder.


Step 2:

Then you have to include those fonts in info.plist



Mistakes:

When you drag and drop the custom fonts inside the project folder, check whether you have enabled the checkbox target for that file.


Suppose if you forgot to select the target, get ready for app crash.
Also, if you called the font name which mismatch the TypeScript family name then also your app will crash. :P

Solved!!! Disable Automatic building on latest Xcode


Solution: Disable Automatic building on latest Xcode

Sometimes developer will face the issue like why Xcode doing automatic build for each and every key stroke. Here is the solution for that issue.

You have to do two changes in Xcode to fix this issue.

Change I :

Goto Xcode -> Preferences -> General Tab. Uncheck the Show live issues check box.


Change II :

Select Storyboard file and goto Editor option from menu options then uncheck the Automatically Refresh Views option.


Friday, March 10, 2017

How to set the validation for Full name field using Objective C?

Full name field validation using Objective C code.

if ([self validate:self.fullnamefield.text] == 0)
{
        NSLog(@"Please Enter Valid User Name");

}

- (BOOL)validate:(NSString *)string
{
    NSError *error             = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[a-zA-Z .]" options:0 error:&error];
    
    NSUInteger numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, [string length])];
    
    return numberOfMatches == string.length;

}

How to compress image without quality loss using Objective C?

Compress image, without quality loss using Objective C code:


NSData *imageData1= nil;

imageData1 =UIImageJPEGRepresentation([self compressForUpload:self.imageView.image scale:1.0], 0.8);

-(UIImage *)compressForUpload:(UIImage *)original scale:(CGFloat)scale
{
    CGSize originalSize = original.size;
    CGSize newSize = CGSizeMake(originalSize.width  *scale, originalSize.height  *scale);
    
    UIGraphicsBeginImageContext(newSize);
    [original drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage* compressedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return compressedImage;

}

Monday, March 6, 2017

How to make a phone call programmatically in iOS?

I struggled lot to find this solution to make a call from iPhone using Objective C code.
Please use the below code to solve that issue.

Objective C:

NSString *phNo = @"911234567890; //91-countrycode remaining are mobile number.

NSString *phoneNumber = [NSString stringWithFormat:@"tel:%@",phNo];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumber]];

Note: For iPad it won't work.

Swift:

let phoneNo = model.mobileNo
let newString:String = phoneNo.replacingOccurrences(of: " ", with: "")
let phoneUrl = URL(string: "telprompt:+91\(newString)")
if let callURL = phoneUrl {
     self.makeCall(callURL)

}

//makeCall function
func makeCall(_ phoneURL:URL) {
        if UIApplication.shared.canOpenURL(phoneURL) {
            UIApplication.shared.openURL(phoneURL)
        }
        else {
            let alertController = UIAlertController(title: "Warning!", message: "Not possible to make call", preferredStyle: .alert)
            let okAct = UIAlertAction(title: "OK", style: .default, handler: { (act) in
                print("OK")
            })
            alertController.addAction(okAct)
            self.present(alertController, animated: true, completion: nil)
        }
    }