iOS: Create Password Protected Zip File

Source: https://code.google.com/archive/p/ziparchive/

NSString *filePath = @"/Users//Desktop/uf/abc.txt";
NSString *zipFilePath = @"/Users//Desktop/uf/abc.zip";
NSString *content = @"Contents to be stored";

NSError *error = nil;
BOOL isFileCreated = [content writeToFile:filePath atomically:YES encoding:NSASCIIStringEncoding error:&error];

if (isFileCreated)
{
    ZipArchive *zipArchive = [[ZipArchive alloc] init];
    BOOL isZipFileCreated = [zipArchive CreateZipFile2:zipFilePath Password:@"domle"];

    if (isZipFileCreated)
    {
       BOOL isFileAddedToZip = [zipArchive addFileToZip:filePath newname:[filePath lastPathComponent]];
       NSLog(@"isFileAddedToZipFile %d", isFileAddedToZip);
       [zipArchive CloseZipFile2];
    }
}

 

 

CNContactPickerViewController – UISearchBar looks black in colour and entered text not visible

Setting search bar background colour will fix the issue, but cancel button is not visible in edit mode due to cancel button text is in white colour. The cancel button will be visible when we set the tint colour for label.

  • [[UISearchBar appearance] setBackgroundColor:[UIColor whiteColor]];
  • [[UILabel appearanceWhenContainedInInstancesOfClasses:@[UISearchBar.class]] setTintColor:[UIColor blueButtonColor]];

iOS CallKit Directory Extension Tips

Tips:

  1. The label text that you see will have the following format: Caller ID:  You can change the app name part of the label by changing app’s Bundle Name.
  2. You must provide a full country code and area code with the phone number.
  3. -reloadExtensionWithIdentifier:completionHandler:, which requests to have your app extension’s data reloaded by the system. Call this whenever you have new blocking or identification data to provide to the system.
  4. -getEnabledStatusForExtensionWithIdentifier:completionHandler:, which allows your app to query whether its extension has been enabled in Settings. Call this from within your app before requesting to reload data, and perhaps prompt the user to first enable your extension in Settings in order to begin loading data.
  5. The array of phone numbers must be a sorted list of int64’s. From smallest to largest. The list will be rejected with an “entries out of order” error otherwise.
  6. Store all the contacts to directory every time, because directory is getting recreated (loosing the previous contacts). Checked in iOS 11.
  7. Make sure the phone numbers are of type NSNumber instead of NSString.

iOS AES128 Encryption and Decryption

Why I am giving the following steps instead of direct link is. The link is changing frequently I guess or they are updating the article or code itself. I saw the method names got changed.

Follow the steps.

  1. Go to http://iphonedevcentral.blogspot.in.
  2. Top left corner, you see search box. Search for Strong Encryption.
  3. Read the article and down the data from the link provided.

 

Code:

kCCOptionECBMode : Electronic Code Book (ECB). Electronic Code Book (ECB) is a mode of operation for a block cipher, with the characteristic that each possible block of plaintext has a defined corresponding ciphertext value and vice versa. In other words, the same plaintext value will always result in the same ciphertext value. Electronic Code Book is used when a volume of plaintext is separated into several blocks of data, each of which is then encrypted independently of other blocks. In fact, Electronic Code Book has the ability to support a separate encryption key for each block type.

Cited the above definition from http://searchsecurity.techtarget.com/definition/Electronic-Code-Book.

CCCrypt is the apple api that actually encrypts or decrypts based on the parameters passed to it.

kCCAlgorithmAES128 is the algorithm to use to encrypt or decrypt. It will successfully encrypt or decrypt only 15 characters, because the buffer size accepts 16 characters. Last character space is for termination character ‘\0’.

If you send more than 15 characters then you will face issue in decryption. So in order to encrypt more than 15 characters then you need to pass kCCOptionECBMode in options. That will internally split the characters and encrypt and provide you the result. In decryption also you mention this mode.

   CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode + kCCOptionPKCS7Padding,

                                          keyPtr, kCCKeySizeAES256,

                                          NULL /* initialization vector (optional) */,

                                          [self bytes], dataLength, /* input */

                                          buffer, bufferSize, /* output */

                                          &numBytesEncrypted );

Useful Links:

  1. https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
  2. https://de.wikipedia.org/wiki/Electronic_Code_Book_Mode
  3. https://www.tutorialspoint.com/cryptography/block_cipher_modes_of_operation.htm

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() ;

}

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;
}

Objective-C – How to use member variables in the categories.

.h

@interface UIView (ObjectTagAdditions)
@property (nonatomic, retain) id objectTag;
@end

.m

#import <objc/runtime.h>
static char const * const ObjectTagKey = "ObjectTag";

@implementation UIView (ObjectTagAdditions)
@dynamic objectTag;

- (id)objectTag {
    return objc_getAssociatedObject(self, &ObjectTagKey);
}

- (void)setObjectTag:(id)newObjectTag {
    objc_setAssociatedObject(self, &ObjectTagKey, newObjectTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

Cited from : http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/