Sunday, December 13, 2015

programmatically implement Single-App Mode in IOS 7 and above

Hi All,

Recently i had to work on a app where the requirement is to lock the device(iOS) to Single-App mode, i.e the device to lock to the app and even when restarted it should boot back to the same app.

I had to use the  UIAccessibilityRequestGuidedAccessSession api
 to make it work. the code is pretty simple as mentioned in the Apple document and SO.

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/index.html#//apple_ref/c/func/UIAccessibilityRequestGuidedAccessSession

as mentioned there pass YES to lock, NO to unlock. The call back method didSucceed actually confirms whether it worked or not.

Here are the things with my app and the steps i performed.


  1. Supervise the iPad/iphone using the Apple Configurator.
  2.  Install the MDM related files ( Each MDM has its own set of instructions, usually involves downloading a profile).
  3. Every MDM has a option of Single APP Mode or MultipleAppMode. Select the second option and add the app IDs to the list. (A single APP mode works pretty well with MDM's but i did not want the app to be locked to a single APP all the time).
  4. As mentioned used the UIAccessibilityRequestGuidedAccessSession to lock at the beginning and unlock at the end.
  5. FYI.. this is a Enterprise App as you must have already noticed but just wanted to mention.

Thanks,
Bob :)






Tuesday, October 20, 2015

set label minimum font size IOS 6 and above dynamically


For changing the font scale of the label earlier we used to use a code like this

myLabel.minimumFontSize = 24;  


myLabel is the label and the minimumFontSize we want is 24.

This gives a warning saying "minimumFontSize first deprecated in ios 6".

the following is the appropriate code to do it post ios6.

[myLabel setMinimumScaleFactor:24.0/myLabel .font.pointSize];


Thanks,
Bob



cant install SWIFT IPA (Enterprise or Adhoc )

When you try to install a IPA that has Swift code from a MDM or through a URL it doesn't work. It works when you run it through the Developer profile, but doesnt work when you install it in the above way.

When you look at the log you should see a similar message as shown below.


dyld: Library not loaded: @rpath/libswiftCore.dylib

Referenced from: /private/var/mobile/Containers/Bundle/Application 
/90ABFFGH-AB09-7584-A2BC-9AX2S41234Z/App-Name.app/App-Name           

Reason: image not found        

(lldb)

For some, the following worked.

Setting Embedded Content Contains Swift Code to YES

Some developers the adding the following to the Runpath worked.
@executable_path/Frameworks

your_target -> Build Settings -> Linking -> Runpath Search Paths

For others repacking the IPA the following ways worked as mentioned in this article.

https://devforums.apple.com/message/984530#984530

As mentioned there do the following using the terminal.

ditto -xk yourIPAFile.ipa /tmp/tempPath
ditto -ck --norsrc /tmp/tempPath NewIPA_file.ipa
rm -r /tmp/tempPath

The only solution that worked for me was Revoking the Distribution Certificate, creating a new Distribution certificate, creating a New provisioning profile that works with this certificate.
I did all the above steps manually without the Xocde creating them automatically.
  1. Create new distribution Certificate.
  2. Create new provisioning profile.
  3. Downloading them onto the mac.
  4. open Xcode -> preferences -> view Accounts and Refreshing downloaded and it worked for me.
I know this solution might not work for some as removing Distribution profiles would stop the Apps from working. As we can have two distribution certificates, i used the second one to create and made it work.

This might happen if the distribution certificate was created prior to Xcode6 or IOS8 where in a entity "OU" is missing from the certificate.If you want to check to see if your certificate has it, please do so by running the following command 
openssl x509 -in ios_distribution.cer -inform DER -text -noout
as mentioned in the article 

Xamarin not downloading Provisioning Profiles

I was working with a Xamarin project the other day to help a developer make a IPA so that the app can distributed for testing.

I made sure that everything is set properly i.e the Xcode has the correct Certificates and profiles etc.., but still XAMARIN wont download the provisiong profiles for distribtuion.

Upon close inspection, found that the BundleIdentifier is set wrong for the Xamarin project.

Once that was taken care of and made sure that the name matches then it downloaded and was able to generate the IPA.

The project bundle identifier should match the APP ID of the provisiong profile, other wise it wont be downloaded.

Bobby.

Misc. Objective-c code blocks

Adding arrow to the table view cell

cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;


change the back color of navigation controller:

self.navigationController.navigationBar.barStyle=UIBarStyleBlack;
self.navigationController.navigationBar.tintColor = [UIColor blueColor];

HexColor to UIColor

Add the following macro to predefine.pch file
#define UIColorFromHexColor(rgbValue) [UIColor colorWith 
Red:((float)((rgbValue & 0xFF0000) >> 16))/255.0 
green:((float)((rgbValue & 0xFF00) >> 8))/255.0 
blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

call it in your m file like this

label.textColor=UIColorFromHexColor(0xFBAE08);
label.text = @"Some Text";

That is it .
Advantage of adding in the pch file is that it is available to the whole project.


Hide Status bar xcode

Here is how to do it.
in plist File add the following.

Status bar is initially hidden -->  YES
View controller-based status bar appearance --> NO

If you want to remove the navigation controller as well like in my case please do the following.

In the first screen or the Load screen add the
self.navigationController.navigationBar.hidden=true;

NSDate to NSString and NSString to NSDate

 
-(NSDate*) getDateFromString: (NSString*)dtStr{
   NSDateFormatter* dateFrmt = [[NSDateFormatter alloc]init];
    [dateFrmt setDateFormat: @"mm/dd/yyyy HH:mm:ss"];
    return [dateFrmt dateFromString:dtStr];
}

-(NSString*)getStringFromNSDate: (NSDate*)dt{
    NSDateFormatter* dateFrmt=[[NSDateFormatter alloc]init];
    [dateFrmt setDateFormat:@"mm/dd/yyyy HH:mm:ss"];
    return [dateFrmt stringFromDate:dt];
}

Create a new GUID Xcode:-

- (NSString *)generateUID
{
   CFUUIDRef guidRef= CFUUIDCreate(NULL);
   CFStringRef guidRefinStringRef= CFUUIDCreateString(NULL, guidRef);
   CFRelease(guidRef);
   return [(NSString *)guidRefinStringRef autorelease];
}

code to check for email using regular expression 



- (BOOL) checkIfStringisEmailusingRegEx: (NSString *) emailString {

    NSString *regExForEmail =

    @"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}"
    @"~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
    @"x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-"
    @"z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5"
    @"]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
    @"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21"
    @"-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
    NSPredicate *isEmail = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", 
regExForEmail];
    
    return [isEmail evaluateWithObject:emailString];
}



Thanks,
Bobby :)