iOS App Transport Security – Enforced from 2017 for Apple app submissions

The ATS requirement is here.

https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW59
(Section NSAppTransportSecurity)

In summary, below is what we need to do in the apps

1. Make every URLs to https
2. Ensure the TLS version is TLS1.2.
3. Have the certificate used in the server to client communication is trusted.

How do we detect if a URL is ATS compliant?

The nscurl tool on OS X El Capitan supports diagnosing ATS secure connections.

For example, /usr/bin/nscurl –ats-diagnostics https://www.example.com will display ATS connection information for http://www.example.com. Run /usr/bin/nscurl -h for more information.

This tools prints PASS / FAIL information. Ensure PASS results for test with diagnose dictionary with NO exceptions specified.

To view the certificate info of a particular Domain or test out the connection, TLS tool will be a good utility.
https://developer.apple.com/library/content/samplecode/sc1236/Introduction/Intro.html#//apple_ref/doc/uid/DTS40014927-Intro-DontLinkElementID_2

Does it affect Socket communication?

Below is the answer from Apple staff (https://forums.developer.apple.com/thread/48979)

Right now ATS is only enforced by our high-level APIs (NSURLSession, NSURLConnection, and anything layered on top of those), and there’s been no announcements about that changing.

Keep in mind, however, that ATS’s enhanced security requirements are not arbitrary; they are defined to give your users a good level of security on an increasingly hostile Internet. As such, your app should aim to comply with these requirements even if ATS is not actively enforcing them.

IOS Coding Tips for Beginners

1. Create view objects in Interface builder not in source code.

2. Flower brackets always be there in if conditions or while loops, even it has single statement.

3. Give one line space between @implementation and @synthesize

4. Open flower bracket “{” should start in next line.

5. Give one line space above conditional or loop statements like if, while, for.

6. The method name itself should resembles its behavior.

7. Remove unnecessary methods which are created by the file templates.

8. Use Edit->Format->Re-Indent to re-indent the selection of statements.

9. Don’t use string literals as keys, make the string literal as constant and use that. Place all constants in a common file.

10. Try to use property directly than calling the accessory method. for example Object.memberVariable than [Object memberVariable];

11. Try to define all literals in common file.

12. Instead of using literals, create meaningful constants for them in common file and use them.

13. Always group the things like constants, statements, etc.

14. The format for method signature should be like
– (void) methodName:(id) sender;

15. One line space between logical group of statements and two lines between physical groups.

16. Try to eliminate autorelease objects, instead use retain and release.

17. If you are declaring a UI object, please suffix the type to the variable. For example, if you are declaring a UILabel object with name ‘userName’, then name it ‘userNameLabel’.

18. Maintain all image names in lowercase with underscore dividing the inline words.

19. Directly access the variable instead of using property in the same class. For example, don’t access

UITableView mTableView;
@Property () UITableView *tableView;
//To reload the table in the same class use
[mTableView reloadData]; // correct
[self.tableView reloadData]; //wrong

Using C++ to access file from Documents folder on iOS and Print the contents

void printFileInfo()
{

char *home = getenv(“HOME”);
char *subdir = “/Documents”;

std::stringstream ss;
ss << home << subdir << “/file.txt”;
std::string s = ss.str();

s.erase(0, strlen(“/private”)); // Erase “/Private” from the final string

char sss;

char letter ;
int i ;
std::string line ;

std::ifstream reader(s.c_str()) ;

if (!reader) {

std::cout << “Error opening input file” << std::endl ;
return -1 ;

}

for (i = 0; !reader.eof() ; i++) {

getline( reader , line ) ;
std::cout << s.c_str() << std::endl;
std::cout << line << std::endl ;

}
reader.close() ;

}

iPv6 Network not available issue

+ (instancetype)  reachabilityForInternetConnection
{

Reachability *reach = NULL;
NetworkStatus status = NotReachable;

struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;

reach = [self reachabilityWithAddress: (const struct sockaddr *) &zeroAddress];

if  (reach != NULL)
{

status = [reach currentReachabilityStatus];

if (status != NotReachable)
{

NSLog(@”Connected to Ipv4 Environment”);

return reach;

}

}

if  ([[UIDevice currentDevice].systemVersion floatValue] < 9.0)
{

// check whether you are in iPv6 environment

struct sockaddr_in6 zeroAddress1;
bzero(&zeroAddress1, sizeof(zeroAddress1));
zeroAddress1.sin6_len = sizeof(zeroAddress1);
zeroAddress1.sin6_family = AF_INET6;

reach = [self reachabilityWithAddress: (const struct sockaddr *) &zeroAddress1];

if  (reach != NULL)
{

status = [reach currentReachabilityStatus];

if (status != NotReachable)
{

NSLog(@”Connected to Ipv6 Environment”);

}

}

}

return reach;

}

CoreTelephony CTCallCenter

The [[CTCallCenter alloc] init] must be run in the main queue. Is it thread safe ??? Better call it on main thread only.

There is an iOS bug that causes instances of the CTCallCenter class to sometimes get notifications after they have been deallocated. Instead of instantiating, using, and releasing instances you must instead retain and never release them to work around the bug.

static CTCallCenter *netInfo; static dispatch_once_t dispatchToken; if (!netInfo) { dispatch_once(&dispatchToken, ^{ netInfo = [[CTCallCenter alloc] init]; }); }

 

How to programmatically know Bluetooth headset is connected to iOS device

Call this method to find out the bluetooth headset is connected or not.

 

- (BOOL) isBluetoothHeadsetConnected
{
    AVAudioSession *session = [AVAudioSession sharedInstance];
    AVAudioSessionRouteDescription *routeDescription = [session currentRoute];

    DEBUGLOG(@"Current Routes : %@", routeDescription);

    if (routeDescription)
    {
        NSArray *outputs = [routeDescription outputs];

        if (outputs && [outputs count] > 0)
        {
            AVAudioSessionPortDescription *portDescription = [outputs objectAtIndex:0];
            NSString *portType = [portDescription portType];

            DEBUGLOG(@"dataSourceName : %@", portType);

            if (portType && [portType isEqualToString:@"BluetoothA2DPOutput"])
            {
                return YES;
            }
        }
    }

    return NO;
}

How to enable or disable Proximity sensor programmatically in iPhone

Use the following API to enable/disable the proximity sensor.

[UIDevice currentDevice].proximityMonitoringEnabled = NO; // Disables the Proximity Sensor

[UIDevice currentDevice].proximityMonitoringEnabled = YES; // Enables the Proximity Sensor

Not all iOS devices have proximity sensors. To determine if proximity monitoring is available, attempt to enable it. If the value of the proximityMonitoringEnabled property remains NO, proximity monitoring is not available.