Sunday, November 18, 2018

Uber android app v4.236.10001 feedback


Hi Team,

My loyalty shifted from OLA to Uber last month since finding a better deals on it. So while using Android app v4.236.10001 (latest version) found few critical features missing. These are listed below:

1. Once I was in UberGo cab and suddenly I got a call from wife to book a cab for her so checked Uber app to it but to my surprise this feature is missing. It should allow a person to book another cab while being on ride.

2. I wanted to get a receipt for rides done in last month so that it can be reimbursed. But then after going to 'Your Trips' section present in right tab showed me past trips. There are two important thing to be noted here:

- Past trip shows only day and time but no date thereby creating confusion. Refer screenshot at the end.

- There should be provision to send receipt to another email id (Suggestion: Tap on any past trip and pop-up should appear with default value as registered email id. This can be edited as needed. Tap on send should sent receipt instantly to email id) 

3. There should be custom pick-up location as well apart from GPS (in case for booking for someone else).

4. Alternatively, location (pick-up or drop) can also be set by adjusting the pins on map rather than entering in text field.





Friday, July 21, 2017

SSL pinning in iOS Swift code



SSL (Secure Socket Layer) pinning is used to prevent Man In The Middle attack.
This is generally used for secure end-to-end communication. Most the apps that requires secure communication such as Banking apps uses this mechanism.

You can implement this using Alamofire as below:

1. Ask Middleware team to implement SSL certificate on Server
2. They will give you .crt file
3. Now, convert this .crt file to .der online using https://www.sslshopper.com/ssl-converter.html
4. Add this .der file to your Xcode (Make sure that you checkmark copy items if needed on dialog box)
5. Now use below code for SSL Pinning in file where you make service calls:

var serverTrustPolicy:ServerTrustPolicy?
var serverTrustPolicies:[String: ServerTrustPolicy]?
var afManager: Alamofire.SessionManager?

if self.configureAlamoFireSSLPinning() == false {
            DispatchQueue.main.async() {
                let alert = UIAlertView(title: "", message: sslConfigurationError, delegate: nil, cancelButtonTitle: "OK")
                alert.show()                
            }
            return
        }


func configureAlamoFireSSLPinning() -> Bool {
        let githubCert = “APPNAME.COMPANYNAME.COM" // This name would be same as that of .der file
        let pathToCert = Bundle.main.path(forResource: githubCert, ofType: "der")
        let localCertificate:NSData = NSData(contentsOfFile: pathToCert!)!
        
        self.serverTrustPolicy = ServerTrustPolicy.pinCertificates(
            certificates: [SecCertificateCreateWithData(nil, localCertificate)!],
            validateCertificateChain: true,
            validateHost: true
        )
        
        self.serverTrustPolicies = [
            "github.com": self.serverTrustPolicy!
        ]
        
        let objConfiguration = URLSessionConfiguration.default
        objConfiguration.timeoutIntervalForResource = 600.0
        objConfiguration.timeoutIntervalForRequest = 30.0
        objConfiguration.urlCache = nil // Clear app cache
        
        self.afManager = Alamofire.SessionManager (
            configuration: objConfiguration,
            serverTrustPolicyManager: ServerTrustPolicyManager(policies: self.serverTrustPolicies!)
        )
        
        if self.afManager == nil {
            return false
        }
        
         return true
    }


6. Now make sure that you change the endpoint to https://

Wednesday, March 8, 2017

How to fetch IP address in Swift 3

You can fetch IP address using below code :
Note : I’ve used reachability so that it captures new IP address in case WiFi is changed to another

1. Podfile file  pod 'ReachabilitySwift' and then install pod

2. AppDelegate.swift file import ReachabilitySwift 
Note : If it prompts an error that Could not find ReachabilitySwift module then simply copy and paste this. It works!

3. didFinishLaunchingOptions function :

// Register to receive notification
        NotificationCenter.default.addObserver(self, selector: #selector(self.reachabilityChanged), name: ReachabilityChangedNotification, object: reachability)
        
        do{
            try reachability.startNotifier()
        }
        catch {
            print("could not start reachability notifier")
        }

4. Then copy paste below code in AppDelegate file 

func reachabilityChanged(note: NSNotification) {
        
        let reachability = note.object as! Reachability
        
        if reachability.isReachable {
            if reachability.isReachableViaWiFi {
                print("Reachable via WiFi")
            } else {
                print("Reachable via Cellular")
            }
            
            setIPAddress()
        } else {
            ipAddress = "" // No IP captures
            print("Network not reachable")
        }
    }
    
    func setIPAddress() {
        if let addr = self.getWiFiAddress() {
            print("ipAddress : \(addr)")
            ipAddress = addr
        } else {
            ipAddress = "" // No IP captures
            print("No WiFi address")
        }
    }
    
    // Return IP address of WiFi interface (en0) as a String, or `nil`
    func getWiFiAddress() -> String? {
        var address : String?
        
        // Get list of all interfaces on the local machine:
        var ifaddr : UnsafeMutablePointer<ifaddrs>?
        guard getifaddrs(&ifaddr) == 0 else { return nil }
        guard let firstAddr = ifaddr else { return nil }
        
        // For each interface ...
        for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
            let interface = ifptr.pointee
            
            // Check for IPv4 or IPv6 interface:
            let addrFamily = interface.ifa_addr.pointee.sa_family
            if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
                
                // Check interface name:
                let name = String(cString: interface.ifa_name)
                if  name == "en0" {
                    
                    // Convert interface address to a human readable string:
                    var addr = interface.ifa_addr.pointee
                    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
                    getnameinfo(&addr, socklen_t(interface.ifa_addr.pointee.sa_len),
                                &hostname, socklen_t(hostname.count),
                                nil, socklen_t(0), NI_NUMERICHOST)
                    address = String(cString: hostname)
                }
            }
        }
        freeifaddrs(ifaddr)
        
        return address
    }

5. Add this in Bridging-Header file 
#include <ifaddrs.h>

In case you don’t have this file then you can create it http://stackoverflow.com/a/37295090/1753005

6.
func applicationWillEnterForeground(_ application: UIApplication) {
        // Post notification
        NotificationCenter.default.post(name: ReachabilityChangedNotification, object: reachability)
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

7. Use this to remove observer

//Stop Reachability Notifier
         reachability.stopNotifier()

         NSNotificationCenter.defaultCenter().removeObserver(self,name: ReachabilityChangedNotification,object: reachability)

Sunday, July 31, 2016

Local Notification in iOS 10 for Objective-C and Swift 3


The way you use to work with Local Notification in iOS 9 and below is completely different in iOS 10.

Below screen grab from Apple release notes depicts this.


Below is code for local notification :

Objective-C :

1. In App-delegate.h file use @import UserNotifications;
2. App-delegate should conform to UNUserNotificationCenterDelegate protocol
3. In didFinishLaunchingOptions use below code :

 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
                          completionHandler:^(BOOL granted, NSError * _Nullable error) {
                              if (!error) {
                                  NSLog(@"request authorization succeeded!");
                                  [self showAlert];
                              }
                          }];

-(void)showAlert {
    UIAlertController *objAlertController = [UIAlertController alertControllerWithTitle:@"Alert" message:@"show an alert!" preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *cancelAction = [UIAlertAction
                                   actionWithTitle:@"OK"
                                   style:UIAlertActionStyleCancel
                                   handler:^(UIAlertAction *action) {
                                       NSLog(@"Ok clicked!");
                                   }];
    [objAlertController addAction:cancelAction];
    
    
    [[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:objAlertController animated:YES completion:^{
        
    }];
    
}

4. Now create a button in any view controller and in IBAction use below code :

 UNMutableNotificationContent *objNotificationContent = [[UNMutableNotificationContent alloc] init];
    objNotificationContent.title = [NSString localizedUserNotificationStringForKey:@“Notification!” arguments:nil];
    objNotificationContent.body = [NSString localizedUserNotificationStringForKey:@“This is local notification message!“
                                                         arguments:nil];
    objNotificationContent.sound = [UNNotificationSound defaultSound];
    
    /// 4. update application icon badge number
    objNotificationContent.badge = @([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
    
    // Deliver the notification in five seconds.
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger
                                                  triggerWithTimeInterval:10.f repeats:NO];       
    
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@“ten”
                                                                          content:objNotificationContent trigger:trigger];
    /// 3. schedule localNotification
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        if (!error) {
            NSLog(@“Local Notification succeeded“);
        }
else {
    NSLog(@“Local Notification failed“);
}
    }];


Swift 3:

1. In App-delegate.h file use import UserNotifications
2. App-delegate should conform to UNUserNotificationCenterDelegate protocol
3. In didFinishLaunchingWithOptions use below code 

 // Override point for customization after application launch.
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
            // Enable or disable features based on authorization.
            if((error == nil)) {
                print(“Request authorization failed!")
            }
            else {
                print(“Request authorization succeeded!")
                self.showAlert()
            }
        }


func showAlert() {
        let objAlert = UIAlertController(title: "Alert", message: "Request authorization succeeded", preferredStyle: UIAlertControllerStyle.alert)
        
        objAlert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
        //self.presentViewController(objAlert, animated: true, completion: nil)
        
        UIApplication.shared().keyWindow?.rootViewController?.present(objAlert, animated: true, completion: nil)
    }


4. Now create a button in any view controller and in IBAction use below code :

let content = UNMutableNotificationContent()
        content.title = NSString.localizedUserNotificationString(forKey: "Hello!", arguments: nil)
        content.body = NSString.localizedUserNotificationString(forKey: "Hello_message_body", arguments: nil)
        content.sound = UNNotificationSound.default()
        content.categoryIdentifier = "notify-test"
        
        let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5, repeats: false)
        let request = UNNotificationRequest.init(identifier: "notify-test", content: content, trigger: trigger)
        
        let center = UNUserNotificationCenter.current()
        center.add(request)

Saturday, July 16, 2016

Regex for checking 10 digit mobile number


if([self validatePhone:searchBar.text])
   NSlog(“Valid mobile number”);   
else
   NSlog(“Invalid mobile number”);

- (BOOL)validatePhone:(NSString *)phoneNumber
{
   // NSString *phoneRegex = @"^((\\+)|(00))[0-9]{6,14}$";
    NSString * phoneRegex = @"^(\\+?)(\\d{10})$”;
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", phoneRegex];
    
    return [phoneTest evaluateWithObject:phoneNumber];
}

-(BOOL) validateEmail:(NSString *)email
{
    NSString *emailRegex = @"^[^-._]+([A-Z0-9a-z]|([-._][^-._]))+[^-._]?@[A-Za-z0-9-]+\\.[A-Za-z]{2,4}$";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:email];

}

Add INR ahead of price value Eg. INR. 1,000


 _lblPriceValue.text = [_ModelController.price changePriceformatAndAddUnit];

- (NSString *)changePriceformatAndAddUnit {
    return [NSString stringWithFormat:@“INR. %@", [self changePriceformat]];
}


- (NSString *)changePriceformat {
    int count = 0;
    long long int a = self.longLongValue;
    while (a != 0) {
        count++;
        a /= 10;
    }
    
    NSMutableString *string = [NSMutableString stringWithString:self];
    NSMutableString *newstring = [NSMutableString string];
    while (count > 3) {
        count -= 3;
        NSRange rang = NSMakeRange(string.length - 3, 3);
        NSString *str = [string substringWithRange:rang];
        [newstring insertString:str atIndex:0];
        [newstring insertString:@"," atIndex:0];
        [string deleteCharactersInRange:rang];
    }
    [newstring insertString:string atIndex:0];
    
    return newstring;

}