Skip to content →

Category: iOS

Migrate NSUserDefaults to App Groups – Swift

I needed migrate my NSUserDefaults to using App Groups. I came across this post Migrating to App Groups, which was doing exactly what I wanted in Objective-C. Here’s the version I rewrote in Swift:

func migrateUserDefaultsToAppGroups() {
	
	// User Defaults - Old
	let userDefaults = NSUserDefaults.standardUserDefaults()
	
	// App Groups Default - New
	let groupDefaults = NSUserDefaults(suiteName: "group.myGroup")
	
	// Key to track if we migrated
	let didMigrateToAppGroups = "DidMigrateToAppGroups"
	
	if let groupDefaults = groupDefaults {
		if !groupDefaults.boolForKey(didMigrateToAppGroups) {
			for key in userDefaults.dictionaryRepresentation().keys {
				groupDefaults.setObject(userDefaults.dictionaryRepresentation()[key], forKey: key)
			}
			groupDefaults.setBool(true, forKey: didMigrateToAppGroups)
			groupDefaults.synchronize()
			print("Successfully migrated defaults")
		} else {
			print("No need to migrate defaults")
		}
	} else {
		print("Unable to create NSUserDefaults with given app group")
	}
	
}

Gist

Comments closed

Cocoapods – Generated duplicate UUIDs

I recently added another target to my Podfile to support tvOS. Here is an example of what the Podfile looks like:

source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!

target 'AppiOS' do
        platform :ios, '9.0'
        pod 'AFNetworking', '3.0.0-beta.1'
end

target 'AppTV' do
    platform :tvos, '9.0'
    pod 'AFNetworking', '3.0.0-beta.1'
end

I got this really long error complaining of duplicate UUIDS. Here is a shortened version:

[!] [Xcodeproj] Generated duplicate UUIDs:

PBXFileReference -- 
.... /Products/AFNetworking.framework

From what I understand, this deterministic UUIDs is a harmless warning and can be disabled by running the following command in the terminal. Then run pod install again.

$ export COCOAPODS_DISABLE_DETERMINISTIC_UUIDS=YES
Comments closed

Downgrading Cocoapods

I recently had some issues with a pre-release version of Cocoapods. To fix it, the suggestion was to downgrade Cocoapods to a previous version. It wasn’t obvious how to do that, but this is what I learned.

First you can figure out which version of Cocoapods you are on with the command:

pod --version

You can also see all the version of Cocoapods you have installed with this command:

sudo gem list cocoapods

Next uninstall Cocoapods. If you have multiple version, you will have the choice of uninstalling all or a specific version.

sudo gem uninstall cocoapods

Finally you can install the specific version with this command:

sudo gem install cocoapods -v 0.39.0.beta.3
Comments closed

WWDC 2015 – Wish list

Last year I made a WWDC 2014 Wish List. I got at least one thing I wanted. But Apple also gave me a whole bunch of things that I didn’t know I wanted.

Here is an updated list for WWDC 2015.

  • Bug Fixes – I’d be very happy if there were less new features and more bug fixes with the current products.  For example please fix the networking issues.  And I’m still having issues with Gmail in OS X Mail.
  • 3rd Party Complications on Apple Watch – Complications are awesome.  I’d like to be able to expose a complication from my app.
  • Complications on iOS Home Screen – Having complications on the Apple Watch, makes me want them on the iOS home screen.
  • Siri Extensibility – I’d like to see Apple open up Siri to third party apps.  For example if I have RunKeeper on my iPhone, I’d like to be able to tell Siri “Start my run”, “End my run”.  When Apple announced HomeKit in 2014, it allowed custom names for things in your house.  A step forward, but I’d like to see more.
  • AppleTV SDK – I’d love to be able to write apps for the AppleTV.
  • Sandboxing – I’m glad that Apple has sandboxing in the Mac App Store.  But it’s too restrictive.  Apps like Coda should be able to run.  Apple should start by sandboxing Xcode.
  • Filesystem – Mac OS X and iOS are due for a new filesystem. ZFS was rumored for awhile but fell through.
  • Extensions – I love extensions, but there are a few problems.  The difference between a share and action extension is confusing.  It’s hard to tell when new extension are available.   There should be more trigger points for extensions.
  • Default Applications on iOS – On OS X you can set a default application for things like mail and web browser.  I wish you could do the same on iOS.
  • Multiple profiles on iOS – It would be nice if iOS supported multiple users, so a family could share an iPad.
Comments closed

iOS File Size Formatter

iOS has a handy formatter for file sizes. Here is an example of formatting at long into a readable string:

// Get file size
unsigned long long size = [[NSFileManager defaultManager] 
  attributesOfItemAtPath:path error:nil].fileSize;
NSLog(@"size: %@", @(size));

// Format file size to a readable string
NSString * fileSize = [NSByteCountFormatter stringFromByteCount:size
   countStyle:NSByteCountFormatterCountStyleFile];
NSLog(@"fileSize: %@", fileSize);

Output:

size: 65346
fileSize: 65 KB

Comments closed

UIDocumentInteractionController vs UIActivityViewController

When I first released WebPDF, I used an UIActivityViewController to share the PDF. This only gave me a few apps to share to. I expected to see other apps that supported PDFs. Here is the code I used:

NSString* fileName = [NSString stringWithFormat:@"%@.pdf", 
  [self.detailItem valueForKey:@"pdfFilename"]];
NSString* filePath = [WebPDFUtils pathWithFilename:fileName];
NSArray *activityItems = @[[NSURL fileURLWithPath:filePath]];
    
UIActivityViewController *activityViewController = 
  [[UIActivityViewController alloc] initWithActivityItems:activityItems 
                                    applicationActivities:nil];
activityViewController.popoverPresentationController.barButtonItem = _shareButton;
    
[activityViewController setCompletionHandler:^(NSString *activityType, BOOL completed) {
  [self dismissViewControllerAnimated:YES completion:nil];
}];
    
[self presentViewController:activityViewController
                   animated:YES
                 completion:nil];

Here is what the share sheet looked like:
UIActivityViewController

After searching around I found the UIDocumentInteractionController. I updated my code:

NSString* fileName = [NSString stringWithFormat:@"%@.pdf", 
  [self.detailItem valueForKey:@"pdfFilename"]];
NSString* filePath = [WebPDFUtils pathWithFilename:fileName];
self.documentInteractionController = [UIDocumentInteractionController 
  interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
self.documentInteractionController.delegate = self;
self.documentInteractionController.UTI = @"com.adobe.pdf";
[self.documentInteractionController presentOptionsMenuFromBarButtonItem:sender 
                                                               animated:YES];

Here is what the share sheet looked like:
UIDocumentInteractionController

When should you use a UIActivityViewController vs a UIDocumentInteractionController. You should really read the Developer docs:

UIActivityViewController

The UIActivityViewController class is a standard view controller that you can use to offer various services from your application. The system provides several standard services, such as copying items to the pasteboard, posting content to social media sites, sending items via email or SMS, and more. Apps can also define custom services.

UIDocumentInteractionController

A document interaction controller, along with a delegate object, provides in-app support for managing user interactions with files in the local system. For example, an email program might use this class to allow the user to preview attachments and open them in other apps. Use this class to present an appropriate user interface for previewing, opening, copying, or printing a specified file.

In general if you’re sharing an image or url, you might want to use a UIActivityViewController. If you’re sharing a document, you might want to use a UIDocumentInteractionController.

Comments closed

WebPDF 1.1.0

me_icon
WebPDF has been updated to include support for saving a PDF from Safari.

In Safari, choose the share icon. Then tap on WebPDF. The page is saved as a PDF to WebPDF.

Source is available on GitHUB: https://github.com/dougdiego/WebPDF

Comments closed

WebPDF 1.0.0

me_icon
I needed an application that could create a PDF out of a webpage. I found a few apps on the AppStore, but none of them met my needs. I figured it would be a fun project and created WebPDF.

It’s a simple application that creates PDF’s out of webpages. The app saves the PDF, lets you view it and export it. It’s optimized for all iPhones (including the iPhone 6 and iPhone 6+) and the iPad.

I also made the source available on GitHUB: https://github.com/dougdiego/WebPDF

Comments closed

Xcode 6 Prefix Header

Prior to Xcode 6, all new projects contained a prefix header.  In Xcode 6 a prefix header is no longer included in the default project. Instead of using a prefix header you should put your imports in the files that need them.  But in the case that you need one, you can still add one.

From the menu, select File > New > File…

xcode6_prefixHeader1

 

Choose iOS > Other > PCH File

xcode6_prefixHeader2

 

In the Build Settings, each for “prefix” to narrow down your choices.  Under “Apple LLVM 6.0 – Language” find “Prefix Header”.  Add “$(SRCROOT)/PrefixHeader.pch”.  Make sure the path is correct.  When you close the dialog, it shows the expanded path.

xcode6_prefixHeader3

 

Comments closed

Xcode 6 category

After updating to Xcode 6, I thought Apple removed the ability to create a category when creating a new file. I was wrong. They just moved it.

To create a category in Xcode 6, choose File > New > File
xcode6_category1

 

Then select iOS > Source > Objective-C File

xcode6_category2

 

Choose File Type: Category.  Then enter you File name and the class you want to create a category for.

xcode6_category3

Comments closed