PIXEL
DOCK

I like the smell of Swift in the morning…

Could not launch “APP_NAME”, process launch failed: Security

Posted: | Author: | Filed under: Xcode | Tags: , | No Comments »

After switching to Xcode 6 and the iOS8 SDK I was confronted with a strange error message when trying to test my app on a device. The app was built and deployed to the device but Xcode did not run it. Instead it showed an alert with the following error message:

Could not launch "APP_NAME", process launch failed: Security

The only thing you can do is to press “OK”, but the app still does not run. When you try to run it again from Xcode you just get the same alert.

The solution to this problem is quite simple:

  1. Run the App from Xcode
  2. When the alert shows, press “OK”
  3. Open the app on the device
  4. An alert will be shown, asking you if you want to trust this app. Press “Trust”.

Now you should be able to run the app from Xcode.

Open settings directly from your app

Posted: | Author: | Filed under: iOS | Tags: , | 5 Comments »

Once upon a time it was possible to go to the settings right from your app using:

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs://"]];

That was quite useful when some feature in your app could not be used, because the user disabled something in his settings. In that case you could inform the user that he had to change his settings if he wanted to use that feature and offer to open the settings directly from your app.

Unfortunately Apple decided to not longer allow this after the introduction of iOS 5.1

Good news: This feature is back with iOS8! Apple has added a NSString constant to UIKit that you are supposed to use. To avoid crashes on iOS versions below iOS8 it is a good idea to check if the constant exists on the system version the device is running. You could check if the user is running iOS8 or higher but I prefer to check directly if the constant exits rather than checking the iOS version. Who knows if Apple will decide to remove this constant again in the future…

So, to open the settings, you can use the following snippet:

BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
if (canOpenSettings) {
   NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
   [[UIApplication sharedApplication] openURL:url];
}

Swift:

if let settingsURL = NSURL(string: UIApplicationOpenSettingsURLString) {
    UIApplication.sharedApplication().openURL(settingsURL)
}

If your app has it’s own settings bundle, the settings will be opened showing your app’s settings. If your app does not have a setting bundle, the main settings page will be shown.

Unfortunately there does not seem to be a way to go directly to subpages of the settings (except your own settings bundle). If you’ve found a way to do that, please let me know in the comments!

Update: Linking to a subpage of the Setting seems to work again for system versions greater or equal than iOS8. It is not officially documented by Apple but it seems to work, although I not sure how reliable this is. It works on my iOS 9.1 iPhone but not in the Simulator. So I would not recommend to use this in production.

So, with caution, you can try this to open the Keyboard Settings:

if let settingsURL = NSURL(string: "prefs:root=General&path=Keyboard") {
    UIApplication.sharedApplication().openURL(settingsURL)
}

Or go even one level deeper:

if let settingsURL = NSURL(string: "prefs:root=General&path=Keyboard/KEYBOARDS") {
    UIApplication.sharedApplication().openURL(settingsURL)
}

To make these unofficial URLs work you might have to add prefs to the URL schemes of your project’s Info.plist file.

Working with JSONP in AngularJS

Posted: | Author: | Filed under: Javascript | Tags: , | 3 Comments »

One thing that I really like in AngularJS is how easy it is to load JSONP from the server and work with the result. With just one line of code you have the JSON object “in your hand”:

$http.jsonp('https://myurl.com/getlist?callback=JSON_CALLBACK')
   .success(function (data) {
      $scope.jsonObject = data;
   }
);

Really easy. But at first I could not make it work. The request was returning a valid JSONP response but the Javascript would throw an error:

Uncaught ReferenceError: angularcallbacks_0 is not defined

As usual the reason for this error was quite simple once I found it: When you work with JSONP you need to add the name of the callback function (aka “padding”) to the request. The JSON that comes back from the server will then be padded in a function of the name that you provided. For example:

When you request a JSON file like this:

{"key": "data"}

using JSONP:

https://myurl.com/getlist?callback=myCallback

you will get the following response:

myCallback({"key": "data"});

When you use AngularJS, the callback name must be JSON_CALLBACK.

https://myurl.com/getlist?callback=JSON_CALLBACK

AngularJS changes the callback name internally to make sure that you can use several requests simultaneously. So your response will look like this:

angular.callbacks._0({"key": "data"});

So far so good. But when I looked at the response that I got I noticed that the callback name was missing the dots. That was the reason for the Javascript error. AngularJS was expecting angular.callbacks._0 when all it got was angularcallbacks_0.

As it turned out the PHP on the server side was stripping all dots from request parameters. That was the reason why the JSONP response could not be handled by AngularJS.

How to remove all conflicted files from a Dropbox folder

Posted: | Author: | Filed under: Tools | No Comments »

This surely is trivial to most developers, but I am not exactly a wizard when it comes to bash scripting. So let me just post this as a note to myself.

This is how you remove all files that contain a specific substring in their file name. In this example I use it to remove all the conflict files in a Dropbox folder:

Open your terminal and navigate to the folder that contains the files that should be removed. This folder can also contain subfolders. Files in subfolders will also be removed if they contain the substring “Konflikt”.

Then use the following command:

find . -type f -name "*Konflikt*" -exec rm -f {} \;

As you can see, my system language is German, so Dropbox names all conflicted files with the Keyword “Konflikt”. Just change that to your system language.

Be careful! Once you have removed the files there is no turning back. No “undo” button here!!!

How to avoid the ugly flickering effect when using CSS transitions in iOS

Posted: | Author: | Filed under: CSS, HTML, iOS | 2 Comments »

Recently I used CSS transitions to animate some images inside an UIWebView. Everything worked fine and the transitions where really smooth. I used the translate transition to move the images that where inside a div HTML element:

To move the images I created a CSS class that contained the transition:

.move {
   -webkit-transform: translate(50px,100px); 
}

Then I would add the CSS Class to the

to move the div and the images contained in it.

document.getElementById('image-container').className = "move";

This worked as expected. However, when the images moved, there was an ugly flicker. It turned out that this is caused by a CSS property call “backface-visibility”. Normally this is used, when you do 3D CSS transitions (e.g. 3D rotations). “backface-visibility” determines whether the backside of a HTML element is visible, when it is not facing the screen. As I am not doing any 3D transitions it should not matter how this property is set. Wrong. Obviously in Webkit Browsers it does matter. To fix the ugly flickering you have to add the following to the CSS class:

.move {
   -webkit-transform: translate(50px,100px); 
   -webkit-backface-visibility: hidden;
}

And thats not enough. The flickering became less but it was still there. Only after I also set the “backface-visibility” property on the images themselves, the flickering went away completely:

.move {
   -webkit-transform: translate(50px,100px); 
   -webkit-backface-visibility: hidden;
}

.move img {
   -webkit-backface-visibility: hidden;
}

I don’t know if this is a bug in Webkit or if there is a logical explanation for this behavior, but setting “backface-visiblity” to “hidden” on all animated elements did the trick.

Dismiss keyboard in HTML form displayed in UIWebView inside modal view controller

Posted: | Author: | Filed under: HTML, iOS | Tags: , | 3 Comments »

Recently I encountered a problem with the keyboard while displaying a HTML form inside a UIWebView: The HTML form was a simple form to ask the login credentials from a user. Nothing more than 2 text input fields and a submit button. When the user tapped on an input field the iOS Keyboard came up, as it should. But then, when the user tapped the submit button, the keyboard stayed in placed and was not dismissed. The normal behaviour would be that the keyboard would be dismissed as soon as the textfield loses it’s focus. But somehow this was not happening.

I found several solutions on how to dismiss the keyboard programatically by either using javascript or calling resignFirstResponder on the UIWebView when the form was being submitted, but the keyboard would still not go away.

Then I found the solution to that problem. I turned out that the lingering keyboard was a UI design choice by Apple. The keyboard dismissal is disabled when you present your UIWebView using a modal ViewController with presentation style UIModalPresentationFormSheet!

The solution is quite simple: You have to override your ViewController’s disablesAutomaticKeyboardDismissal method:

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

After that the keyboard will be dismissed as soon as the input fields lose focus (or the form is being submitted).

“Collection was mutated while being enumerated” during CoreData operation on background thread

Posted: | Author: | Filed under: iOS, Objective-C | Tags: , , | 7 Comments »

During my current project I had to move a time consuming CoreData operation to a background thread to avoid a frozen UI. After reading some horror stories about using CoreData on a background thread I was actually surprised how straight forward it was. I used Apple’s sample code ThreadedCoreData as a guidance. When I tested my changes everything went smooth. Until I started to touch my app’s UI while the background process was running. Suddenly the app crashed and the following exception was thrown:

*** Terminating app due to uncaught exception 'NSGenericException',
reason: '*** Collection <__NSCFSet: 0x1f0ec200> was mutated while
being enumerated.'

The exception was being thrown on the background thread during a call to

[NSManagedObjectContext executeFetchRequest:error:]

What happened?

In Apple’s example code the CoreData operations happen inside the main method of a custom subclass of NSOperation. That subclass is initialized using a custom initWithData: method and then added to a NSOperationQueue.

When doing CoreData operations on a background thread it is important that the background thread uses it’s own instance of NSManagedObjectContext. And this NSManagedObjectContext has to be instantiated on the background thread.

And that was the problem.

In Apple’s example the NSManagedObjectContext for the background thread is instantiated in the custom initWithData: method of the custom ParseOperation class. But that method is called on the main thread when instantiating a new ParseOperation object before adding it to the NSOperationQueue. So the NSManagedObjectContext instance is created on the main thread!

The solution was quite simple:

After moving the code that instantiates the NSManagedObjectContext from the initWithData: method (called from the main thread) to the main method (called from the background thread), the problem vanished and the code run smoothly.

So, when using CoreData in a background thread make sure that the background thread has it’s own NSManagedObjectContext instance that was created on the background thread!

Dragging a window to a second monitor in Mountain Lion

Posted: | Author: | Filed under: Tools | 1 Comment »

And now for something completely different: After updating my OS to Mountain Lion, one thing was driving me nuts:

I just could not drag any window (Chrome, Finder etc.) from my MacBook Pro’s display to my secondary monitor (which I arranged on top of my MacBook Pro monitor). It just was blocked by the menu bar.

I took me a while to figure it out but apparently you have to show a little persistence: Just keep on dragging! At first the window is stuck below the menu bar but then just as the mouse is about to reach to top of the secondary monitor, the window jumps to the secondary monitor as well.

Nice one, Apple!

Code Sign Error: Provisioning Profile can’t be found.

Posted: | Author: | Filed under: iOS, Xcode | Tags: | 5 Comments »

Sometimes when you transfer your project to another computer and especially when you create a new developer certificate in the progress, you’ll run into difficulties. When you try to run your app on a device, Xcode will throw the following error:

Code Sign Error: Provisioning Profile '###ID###' can't be found.

The problem is that in your project’s project.pbxproj file the old provisioning profile identifiers are still lingering. You need to clean up that file so that Xcode can build your project without errors.

Here’s how you do that:

1. Close Xcode
2. Right click on your project’s .xcodeproj bundle to show it’s contents.
3. Open the .pbxproj file in a text editor of your choice (make a backup copy first if you feel paranoid)
4. Find all lines in that file that include the word PROVISIONING_PROFILE and delete them.
5. Open Xcode and clean your project
6. Build your project

80F04C2F14BDF2CD00851339 /* Ad Hoc */ = {
   isa = XCBuildConfiguration;
   buildSettings = {
      CODE_SIGN_IDENTITY = "iPhone Distribution: Caramelized GmbH";
      "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
      GCC_PRECOMPILE_PREFIX_HEADER = YES;
      GCC_PREFIX_HEADER = "CaramelReader/Caramelized-Prefix.pch";
      INFOPLIST_FILE = "CaramelReader/Caramelized-Info.plist";
      IPHONEOS_DEPLOYMENT_TARGET = 5.1;
      PRODUCT_NAME = Caramelized;
      ↓ DELETE THIS LINE! ↓
      PROVISIONING_PROFILE = "8B3033A4-0E28-42F8-80FC-70B6C3C473C7"; 
      ↑ DELETE THIS LINE! ↑
      WRAPPER_EXTENSION = app;
   };
   name = "Ad Hoc";
};

How to add a large amount of In-App Purchase items to iTunesConnect

Posted: | Author: | Filed under: iOS, Tools | Tags: , , | No Comments »

Adding In-App Purchase items to your Application in iTunesConnect by hand is a boring and time consuming task. When I realized that I’d have to add about 1000 items for my app I really did not want to do that manually. Luckily there is a tool for mass upload of In-App Purchase items. It is a bit hidden though.

When you log in to iTunesConnect and select “Manage your Apps” there is a section in the footer called Application Loader. That’s the tool you’ll need.

Download Application Loader and the Spreadsheet Example. With Application Loader you can select a text file that contains a list of the In-App Purchase items that you want to add to your app. It is a tab separated list that contains all the metadata that you’d normally add manually when adding an item in iTunesConnect. Have a look at the spreadsheet example to see what format the list should have.

To add the mandatory screenshots I found it easiest to put all the screenshots in one folder and name the screenshot according to the product ID. If your item’s product ID is com.yourdomain.product1 than the screenshot must be named com.yourdomain.product1.jpg.

If you have that text file all you have to do is select the file in Application Loader, select the screenshot folder, hit “next” a couple of times and then “deliver”.

Voilá, that’s it! Do not panic if your new In-App Purchase items do not show up in iTunesConnect right away. Sometimes it takes a couple of hours(!) before the show up.