Showing posts with label iOS. Show all posts
Showing posts with label iOS. Show all posts

Wednesday, October 7, 2015

canOpenURL Restrictions In iOS 9

iOS 9 has introduced a lesser-known limitation: It is not possible for apps to check if they can open an arbitrary URL anymore. Instead, only specific URL schemes can be checked: those that are included in the application's whitelist.

To create the whitelist, add an new array key called LSApplicationQueriesSchemes to Info.plist, then populate the array with all the schemes the app will test. Here is an example with the "uber" URL scheme:

<key>LSApplicationQueriesSchemes</key>
<array>
  <string>uber</string>
</array>


Note 1: The LSApplicationQueriesSchemes array items should only contain scheme names (without the trailing "://"), however canOpenURL still expects full URLs, like

BOOL uberInstalled = [app canOpenURL:[NSURL URLWithString:@"uber://"]];

Note 2: openURL is not affected by this change.

A nice writeup of the issue can be found here: http://awkwardhare.com/post/121196006730/quick-take-on-ios-9-url-scheme-changes.

Saturday, May 23, 2015

Xcode Automated Build Numbering, Now For Watch Apps, Too

If your iOS project contains a watch extension, Xcode mandates the build numbers in the main app's and the extension's Info.plist files to match. This can be problematic if the build number is auto-generated from the number of Git changes for example.

Below is a build number generator script that ensures all extensions get the same build number as the main app.

First, replace MyApp, MyTodayWidget etc. with the actual app and extension names from your project. Then in Xcode, add the script to the main app build phases as a "New Run Script Phase", after the "Copy Bundle Resources" phase.


# Set the build number to the count of Git commits
buildNumber=$(git rev-list HEAD | wc -l | tr -d ' ')

# Enlist app name and extension names
app="MyApp"
todayExtension="MyTodayWidget"
watchKitExtension="MyWatchExtension"
watchKitApp="MyWatchApp"

# Ensure extension build numbers are the same as the main app
appDir="${app}.app"
todayExtensionDir="${appDir}/PlugIns/${todayExtension}.appex"
watchKitExtensionDir="${appDir}/PlugIns/${watchKitExtension}.appex"
watchKitAppDir="${watchKitExtensionDir}/${watchKitApp}.app"
plistDirs=( "$appDir" "$todayExtensionDir" "$watchKitExtensionDir"  "$watchKitAppDir" )

for dir in "${plistDirs[@]}"
do
    plist=${dir}/Info.plist
    echo "Updating ${TARGET_BUILD_DIR}/$plist"
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${TARGET_BUILD_DIR}/${plist}"

done