ApplicationShortcuts: Version 1.2, 2016-09-28
Upgraded to Swift 2.3. Demonstrates how to use the UIApplicationShortcutItem class to provide quick access to parts of your application directly from the device's home screen. The sample shows two static shortcuts (defined in the app's Info.plist), and two dynamic shortcuts (defined in code with the UIMutableApplicationShortcutItem class). The dynamic shortcuts can be edited to change the title, subtitle and icon. Signed-off-by: Liu Lantao <liulantao@gmail.com>
This commit is contained in:
parent
f78eaf06a5
commit
c580342ab1
|
@ -0,0 +1,332 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
5345AE1C1B97709700F65A71 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5345AE1E1B97709700F65A71 /* InfoPlist.strings */; };
|
||||
53A5377E1B8CEC2600CBD3C3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A537701B8CEC2600CBD3C3 /* AppDelegate.swift */; };
|
||||
53A5377F1B8CEC2600CBD3C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53A537711B8CEC2600CBD3C3 /* Assets.xcassets */; };
|
||||
53A537801B8CEC2600CBD3C3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53A537731B8CEC2600CBD3C3 /* LaunchScreen.storyboard */; };
|
||||
53A537811B8CEC2600CBD3C3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53A537751B8CEC2600CBD3C3 /* Main.storyboard */; };
|
||||
53A537871B8CEC2600CBD3C3 /* ShortcutDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A5377C1B8CEC2600CBD3C3 /* ShortcutDetailViewController.swift */; };
|
||||
53A537881B8CEC2600CBD3C3 /* ShortcutsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A5377D1B8CEC2600CBD3C3 /* ShortcutsTableViewController.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
5345AE1D1B97709700F65A71 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
5345AE1F1B97709B00F65A71 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
53A537701B8CEC2600CBD3C3 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = ApplicationShortcuts/AppDelegate.swift; sourceTree = SOURCE_ROOT; };
|
||||
53A537711B8CEC2600CBD3C3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ApplicationShortcuts/Assets.xcassets; sourceTree = SOURCE_ROOT; };
|
||||
53A537741B8CEC2600CBD3C3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
53A537761B8CEC2600CBD3C3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Main.storyboard; sourceTree = "<group>"; };
|
||||
53A537791B8CEC2600CBD3C3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ApplicationShortcuts/Info.plist; sourceTree = SOURCE_ROOT; };
|
||||
53A5377C1B8CEC2600CBD3C3 /* ShortcutDetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ShortcutDetailViewController.swift; path = ApplicationShortcuts/ShortcutDetailViewController.swift; sourceTree = SOURCE_ROOT; };
|
||||
53A5377D1B8CEC2600CBD3C3 /* ShortcutsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ShortcutsTableViewController.swift; path = ApplicationShortcuts/ShortcutsTableViewController.swift; sourceTree = SOURCE_ROOT; };
|
||||
EB7B7F951B8645D30063172E /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
EBD4FAAF1B83ED9C009B2114 /* AppShortcuts.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppShortcuts.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
EBD4FAAC1B83ED9C009B2114 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
53A537721B8CEC2600CBD3C3 /* Base.lproj */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5345AE1E1B97709700F65A71 /* InfoPlist.strings */,
|
||||
53A537731B8CEC2600CBD3C3 /* LaunchScreen.storyboard */,
|
||||
53A537751B8CEC2600CBD3C3 /* Main.storyboard */,
|
||||
);
|
||||
name = Base.lproj;
|
||||
path = ApplicationShortcuts/Base.lproj;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
EBD4FAA61B83ED9C009B2114 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EB7B7F951B8645D30063172E /* README.md */,
|
||||
EBD4FAB11B83ED9D009B2114 /* ApplicationShortcuts */,
|
||||
EBD4FAB01B83ED9D009B2114 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EBD4FAB01B83ED9D009B2114 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EBD4FAAF1B83ED9C009B2114 /* AppShortcuts.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EBD4FAB11B83ED9D009B2114 /* ApplicationShortcuts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
53A537701B8CEC2600CBD3C3 /* AppDelegate.swift */,
|
||||
53A5377D1B8CEC2600CBD3C3 /* ShortcutsTableViewController.swift */,
|
||||
53A5377C1B8CEC2600CBD3C3 /* ShortcutDetailViewController.swift */,
|
||||
53A537791B8CEC2600CBD3C3 /* Info.plist */,
|
||||
53A537711B8CEC2600CBD3C3 /* Assets.xcassets */,
|
||||
53A537721B8CEC2600CBD3C3 /* Base.lproj */,
|
||||
);
|
||||
name = ApplicationShortcuts;
|
||||
path = Tabs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
EBD4FAAE1B83ED9C009B2114 /* ApplicationShortcuts */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = EBD4FAC31B83ED9D009B2114 /* Build configuration list for PBXNativeTarget "ApplicationShortcuts" */;
|
||||
buildPhases = (
|
||||
EBD4FAAB1B83ED9C009B2114 /* Sources */,
|
||||
EBD4FAAC1B83ED9C009B2114 /* Frameworks */,
|
||||
EBD4FAAD1B83ED9C009B2114 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ApplicationShortcuts;
|
||||
productName = Tabs;
|
||||
productReference = EBD4FAAF1B83ED9C009B2114 /* AppShortcuts.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
EBD4FAA71B83ED9C009B2114 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0800;
|
||||
ORGANIZATIONNAME = Apple;
|
||||
TargetAttributes = {
|
||||
EBD4FAAE1B83ED9C009B2114 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
LastSwiftMigration = 0800;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = EBD4FAAA1B83ED9C009B2114 /* Build configuration list for PBXProject "ApplicationShortcuts" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = EBD4FAA61B83ED9C009B2114;
|
||||
productRefGroup = EBD4FAB01B83ED9D009B2114 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
EBD4FAAE1B83ED9C009B2114 /* ApplicationShortcuts */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
EBD4FAAD1B83ED9C009B2114 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
53A537811B8CEC2600CBD3C3 /* Main.storyboard in Resources */,
|
||||
5345AE1C1B97709700F65A71 /* InfoPlist.strings in Resources */,
|
||||
53A5377F1B8CEC2600CBD3C3 /* Assets.xcassets in Resources */,
|
||||
53A537801B8CEC2600CBD3C3 /* LaunchScreen.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
EBD4FAAB1B83ED9C009B2114 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
53A537871B8CEC2600CBD3C3 /* ShortcutDetailViewController.swift in Sources */,
|
||||
53A5377E1B8CEC2600CBD3C3 /* AppDelegate.swift in Sources */,
|
||||
53A537881B8CEC2600CBD3C3 /* ShortcutsTableViewController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
5345AE1E1B97709700F65A71 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
5345AE1D1B97709700F65A71 /* Base */,
|
||||
5345AE1F1B97709B00F65A71 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
path = ApplicationShortcuts;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
53A537731B8CEC2600CBD3C3 /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
53A537741B8CEC2600CBD3C3 /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
53A537751B8CEC2600CBD3C3 /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
53A537761B8CEC2600CBD3C3 /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
EBD4FAC11B83ED9D009B2114 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
EBD4FAC21B83ED9D009B2114 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
EBD4FAC41B83ED9D009B2114 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
INFOPLIST_FILE = ApplicationShortcuts/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.ApplicationShortcuts";
|
||||
PRODUCT_NAME = AppShortcuts;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 2.3;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
EBD4FAC51B83ED9D009B2114 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
INFOPLIST_FILE = ApplicationShortcuts/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.ApplicationShortcuts";
|
||||
PRODUCT_NAME = AppShortcuts;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 2.3;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
EBD4FAAA1B83ED9C009B2114 /* Build configuration list for PBXProject "ApplicationShortcuts" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
EBD4FAC11B83ED9D009B2114 /* Debug */,
|
||||
EBD4FAC21B83ED9D009B2114 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
EBD4FAC31B83ED9D009B2114 /* Build configuration list for PBXNativeTarget "ApplicationShortcuts" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
EBD4FAC41B83ED9D009B2114 /* Debug */,
|
||||
EBD4FAC51B83ED9D009B2114 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = EBD4FAA71B83ED9C009B2114 /* Project object */;
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
Copyright (C) 2016 Apple Inc. All Rights Reserved.
|
||||
See LICENSE.txt for this sample’s licensing information
|
||||
|
||||
Abstract:
|
||||
The application delegate class used to manage this sample.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
// MARK: - Types
|
||||
|
||||
enum ShortcutIdentifier: String {
|
||||
case First
|
||||
case Second
|
||||
case Third
|
||||
case Fourth
|
||||
|
||||
// MARK: - Initializers
|
||||
|
||||
init?(fullType: String) {
|
||||
guard let last = fullType.componentsSeparatedByString(".").last else { return nil }
|
||||
|
||||
self.init(rawValue: last)
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var type: String {
|
||||
return NSBundle.mainBundle().bundleIdentifier! + ".\(self.rawValue)"
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Static Properties
|
||||
|
||||
static let applicationShortcutUserInfoIconKey = "applicationShortcutUserInfoIconKey"
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/*
|
||||
The app delegate must implement the window from UIApplicationDelegate
|
||||
protocol to use a main storyboard file.
|
||||
*/
|
||||
var window: UIWindow?
|
||||
|
||||
/// Saved shortcut item used as a result of an app launch, used later when app is activated.
|
||||
var launchedShortcutItem: UIApplicationShortcutItem?
|
||||
|
||||
func handleShortCutItem(shortcutItem: UIApplicationShortcutItem) -> Bool {
|
||||
var handled = false
|
||||
|
||||
// Verify that the provided `shortcutItem`'s `type` is one handled by the application.
|
||||
guard ShortcutIdentifier(fullType: shortcutItem.type) != nil else { return false }
|
||||
|
||||
guard let shortCutType = shortcutItem.type as String? else { return false }
|
||||
|
||||
switch (shortCutType) {
|
||||
case ShortcutIdentifier.First.type:
|
||||
// Handle shortcut 1 (static).
|
||||
handled = true
|
||||
break
|
||||
case ShortcutIdentifier.Second.type:
|
||||
// Handle shortcut 2 (static).
|
||||
handled = true
|
||||
break
|
||||
case ShortcutIdentifier.Third.type:
|
||||
// Handle shortcut 3 (dynamic).
|
||||
handled = true
|
||||
break
|
||||
case ShortcutIdentifier.Fourth.type:
|
||||
// Handle shortcut 4 (dynamic).
|
||||
handled = true
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
// Construct an alert using the details of the shortcut used to open the application.
|
||||
let alertController = UIAlertController(title: "Shortcut Handled", message: "\"\(shortcutItem.localizedTitle)\"", preferredStyle: .Alert)
|
||||
let okAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
|
||||
alertController.addAction(okAction)
|
||||
|
||||
// Display an alert indicating the shortcut selected from the home screen.
|
||||
window!.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
|
||||
|
||||
return handled
|
||||
}
|
||||
|
||||
// MARK: - Application Life Cycle
|
||||
|
||||
func applicationDidBecomeActive(application: UIApplication) {
|
||||
guard let shortcut = launchedShortcutItem else { return }
|
||||
|
||||
handleShortCutItem(shortcut)
|
||||
|
||||
launchedShortcutItem = nil
|
||||
}
|
||||
|
||||
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
|
||||
|
||||
// Override point for customization after application launch.
|
||||
var shouldPerformAdditionalDelegateHandling = true
|
||||
|
||||
// If a shortcut was launched, display its information and take the appropriate action
|
||||
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem {
|
||||
|
||||
launchedShortcutItem = shortcutItem
|
||||
|
||||
// This will block "performActionForShortcutItem:completionHandler" from being called.
|
||||
shouldPerformAdditionalDelegateHandling = false
|
||||
}
|
||||
|
||||
// Install initial versions of our two extra dynamic shortcuts.
|
||||
if let shortcutItems = application.shortcutItems where shortcutItems.isEmpty {
|
||||
// Construct the items.
|
||||
let shortcut3 = UIMutableApplicationShortcutItem(type: ShortcutIdentifier.Third.type, localizedTitle: "Play", localizedSubtitle: "Will Play an item", icon: UIApplicationShortcutIcon(type: .Play), userInfo: [
|
||||
AppDelegate.applicationShortcutUserInfoIconKey: UIApplicationShortcutIconType.Play.rawValue
|
||||
]
|
||||
)
|
||||
|
||||
let shortcut4 = UIMutableApplicationShortcutItem(type: ShortcutIdentifier.Fourth.type, localizedTitle: "Pause", localizedSubtitle: "Will Pause an item", icon: UIApplicationShortcutIcon(type: .Pause), userInfo: [
|
||||
AppDelegate.applicationShortcutUserInfoIconKey: UIApplicationShortcutIconType.Pause.rawValue
|
||||
]
|
||||
)
|
||||
|
||||
// Update the application providing the initial 'dynamic' shortcut items.
|
||||
application.shortcutItems = [shortcut3, shortcut4]
|
||||
}
|
||||
|
||||
return shouldPerformAdditionalDelegateHandling
|
||||
}
|
||||
|
||||
/*
|
||||
Called when the user activates your application by selecting a shortcut on the home screen, except when
|
||||
application(_:,willFinishLaunchingWithOptions:) or application(_:didFinishLaunchingWithOptions) returns `false`.
|
||||
You should handle the shortcut in those callbacks and return `false` if possible. In that case, this
|
||||
callback is used if your application is already launched in the background.
|
||||
*/
|
||||
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: Bool -> Void) {
|
||||
let handledShortCutItem = handleShortCutItem(shortcutItem)
|
||||
|
||||
completionHandler(handledShortCutItem)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
shortcutTitle1 = "Search";
|
||||
shortcutSubtitle1 = "Will search for an item";
|
||||
|
||||
shortcutTitle2 = "Share";
|
||||
shortcutSubtitle2 = "Will share an item";
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11178" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="h4K-im-1MF">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11144"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Shortcuts-->
|
||||
<scene sceneID="HLU-Zl-7DP">
|
||||
<objects>
|
||||
<tableViewController storyboardIdentifier="LaunchScreenTable" id="rp5-JB-a3T" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="jtZ-Ls-Rdk">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="rp5-JB-a3T" id="6bw-hc-wS9"/>
|
||||
<outlet property="delegate" destination="rp5-JB-a3T" id="O6h-eq-PaT"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Shortcuts" id="eDo-Rb-NK3"/>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="DQR-xt-Izu" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="785" y="413"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="mZs-3N-4em">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="LaunchScreenNav" id="h4K-im-1MF" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="IiZ-A6-yAa">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="rp5-JB-a3T" kind="relationship" relationship="rootViewController" id="t47-xq-IlE"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="rs8-Ue-yE9" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-20" y="414"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,199 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11178" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="IWh-cd-MEY">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11144"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--ShortcutItemDetail-->
|
||||
<scene sceneID="2kk-kx-Tj5">
|
||||
<objects>
|
||||
<tableViewController storyboardIdentifier="ShortcutDetail" useStoryboardIdentifierAsRestorationIdentifier="YES" id="GEw-BJ-3Vb" userLabel="ShortcutItemDetail" customClass="ShortcutDetailViewController" customModule="AppShortcuts" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="oCG-GJ-XTg">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<sections>
|
||||
<tableViewSection headerTitle="TITLE" id="Akh-wo-mZh">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="smf-Bz-68K">
|
||||
<rect key="frame" x="0.0" y="120" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="smf-Bz-68K" id="qIR-BA-ZVS">
|
||||
<frame key="frameInset" width="375" height="43"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Title" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="SOV-FH-uE9">
|
||||
<color key="textColor" red="0.0" green="0.0" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="GEw-BJ-3Vb" id="mLH-i3-hTy"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="SOV-FH-uE9" firstAttribute="leading" secondItem="qIR-BA-ZVS" secondAttribute="leading" constant="15" id="BPa-7v-ew6"/>
|
||||
<constraint firstAttribute="trailing" secondItem="SOV-FH-uE9" secondAttribute="trailing" constant="15" id="Gt4-qK-EW6"/>
|
||||
<constraint firstAttribute="bottom" secondItem="SOV-FH-uE9" secondAttribute="bottom" constant="2" id="Rd7-ox-43b"/>
|
||||
<constraint firstItem="SOV-FH-uE9" firstAttribute="top" secondItem="qIR-BA-ZVS" secondAttribute="top" constant="7" id="crl-og-wcV"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="SUBTITLE" id="Eig-AM-ryd">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="ZpT-Yw-DVl">
|
||||
<rect key="frame" x="0.0" y="221" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ZpT-Yw-DVl" id="NXX-UF-tLO">
|
||||
<frame key="frameInset" width="375" height="43"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Title" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="0Qq-Fe-aiz">
|
||||
<color key="textColor" red="0.0" green="0.0" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="GEw-BJ-3Vb" id="M0s-6o-W1S"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="0Qq-Fe-aiz" secondAttribute="bottom" constant="2" id="8jd-kn-1Uj"/>
|
||||
<constraint firstItem="0Qq-Fe-aiz" firstAttribute="leading" secondItem="NXX-UF-tLO" secondAttribute="leading" constant="15" id="Y3L-vB-uUK"/>
|
||||
<constraint firstItem="0Qq-Fe-aiz" firstAttribute="top" secondItem="NXX-UF-tLO" secondAttribute="top" constant="7" id="ile-Kf-YpT"/>
|
||||
<constraint firstAttribute="trailing" secondItem="0Qq-Fe-aiz" secondAttribute="trailing" constant="15" id="zXE-09-G5c"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="ICON" id="Sbn-Ds-ZUw">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="123" id="cjY-6r-rSI">
|
||||
<rect key="frame" x="0.0" y="322" width="375" height="123"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="cjY-6r-rSI" id="Fqw-Yc-YPr">
|
||||
<frame key="frameInset" width="375" height="122"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ysH-Tl-DdL">
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="GEw-BJ-3Vb" id="O1n-ov-vzw"/>
|
||||
<outlet property="delegate" destination="GEw-BJ-3Vb" id="SyU-qj-KF4"/>
|
||||
</connections>
|
||||
</pickerView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="ysH-Tl-DdL" secondAttribute="bottom" id="kLI-8V-F5x"/>
|
||||
<constraint firstItem="ysH-Tl-DdL" firstAttribute="top" secondItem="Fqw-Yc-YPr" secondAttribute="topMargin" constant="6" id="kSg-X8-sfh"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="ysH-Tl-DdL" secondAttribute="trailing" id="lkB-dl-9es"/>
|
||||
<constraint firstAttribute="leadingMargin" secondItem="ysH-Tl-DdL" secondAttribute="leading" id="xzA-Tj-FDN"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="GEw-BJ-3Vb" id="wPU-Vk-mun"/>
|
||||
<outlet property="delegate" destination="GEw-BJ-3Vb" id="7KB-nf-2JB"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" id="72M-zG-D7M">
|
||||
<barButtonItem key="leftBarButtonItem" title="Cancel" id="Wg1-Gx-Nzw">
|
||||
<connections>
|
||||
<segue destination="Aaj-4d-d5m" kind="unwind" identifier="ShortcutDetailCancelled" unwindAction="cancel:" id="Znr-N3-kET"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="done" id="niZ-q1-T49">
|
||||
<connections>
|
||||
<segue destination="7ye-q1-REg" kind="unwind" identifier="ShortcutDetailUpdated" unwindAction="done:" id="okd-5n-xee"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="doneButton" destination="niZ-q1-T49" id="MiO-Q1-G67"/>
|
||||
<outlet property="pickerView" destination="ysH-Tl-DdL" id="bZH-ao-vqI"/>
|
||||
<outlet property="subtitleTextField" destination="0Qq-Fe-aiz" id="ebA-gA-kLZ"/>
|
||||
<outlet property="titleTextField" destination="SOV-FH-uE9" id="XkP-0l-3tp"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="XW5-Qg-RSe" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<exit id="Aaj-4d-d5m" userLabel="Exit" sceneMemberID="exit"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1699" y="-690"/>
|
||||
</scene>
|
||||
<!--ShortcutItemsTableViewController-->
|
||||
<scene sceneID="e3g-S6-Dq3">
|
||||
<objects>
|
||||
<tableViewController storyboardIdentifier="ShortcutsTableViewController" title="Third View Controller" useStoryboardIdentifierAsRestorationIdentifier="YES" id="0nb-dB-Thb" userLabel="ShortcutItemsTableViewController" customClass="ShortcutsTableViewController" customModule="AppShortcuts" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="CtH-SO-5Mi">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="CellID" textLabel="v39-LU-kIp" detailTextLabel="bQL-nM-M0m" style="IBUITableViewCellStyleSubtitle" id="tcO-Gg-0gM">
|
||||
<frame key="frameInset" minY="92" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tcO-Gg-0gM" id="usU-hY-H3V">
|
||||
<frame key="frameInset" width="342" height="43"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="v39-LU-kIp">
|
||||
<frame key="frameInset" minX="15" minY="5" width="32" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="bQL-nM-M0m">
|
||||
<frame key="frameInset" minX="15" minY="25" width="41" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="GEw-BJ-3Vb" kind="show" identifier="ShowShortcutDetail" id="f4U-Br-Wkx"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="0nb-dB-Thb" id="b6i-pz-Z4O"/>
|
||||
<outlet property="delegate" destination="0nb-dB-Thb" id="zcO-wS-Eaq"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Shortcuts" id="ogi-vv-V8e"/>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="wV3-ZN-AWJ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
<exit id="7ye-q1-REg" userLabel="Exit" sceneMemberID="exit"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="792" y="-690"/>
|
||||
</scene>
|
||||
<!--ShortCutsNavController-->
|
||||
<scene sceneID="4ji-UO-XKX">
|
||||
<objects>
|
||||
<navigationController storyboardIdentifier="RootViewController" automaticallyAdjustsScrollViewInsets="NO" useStoryboardIdentifierAsRestorationIdentifier="YES" id="IWh-cd-MEY" userLabel="ShortCutsNavController" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" id="y6E-Kx-dxS"/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="zs5-f8-XoS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
<connections>
|
||||
<segue destination="0nb-dB-Thb" kind="relationship" relationship="rootViewController" id="aEf-WQ-82y"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="8mE-55-YlQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="32" y="-690"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,83 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIApplicationShortcutItems</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UIApplicationShortcutItemIconType</key>
|
||||
<string>UIApplicationShortcutIconTypeSearch</string>
|
||||
<key>UIApplicationShortcutItemSubtitle</key>
|
||||
<string>shortcutSubtitle1</string>
|
||||
<key>UIApplicationShortcutItemTitle</key>
|
||||
<string>shortcutTitle1</string>
|
||||
<key>UIApplicationShortcutItemType</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).First</string>
|
||||
<key>UIApplicationShortcutItemUserInfo</key>
|
||||
<dict>
|
||||
<key>firstShorcutKey1</key>
|
||||
<string>firstShortcutKeyValue1</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UIApplicationShortcutItemIconType</key>
|
||||
<string>UIApplicationShortcutIconTypeShare</string>
|
||||
<key>UIApplicationShortcutItemSubtitle</key>
|
||||
<string>shortcutSubtitle2</string>
|
||||
<key>UIApplicationShortcutItemTitle</key>
|
||||
<string>shortcutTitle2</string>
|
||||
<key>UIApplicationShortcutItemType</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).Second</string>
|
||||
<key>UIApplicationShortcutItemUserInfo</key>
|
||||
<dict>
|
||||
<key>secondShortcutKey1</key>
|
||||
<string>secondShortcutValue1</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UIStatusBarTintParameters</key>
|
||||
<dict>
|
||||
<key>UINavigationBar</key>
|
||||
<dict>
|
||||
<key>Style</key>
|
||||
<string>UIBarStyleDefault</string>
|
||||
<key>Translucent</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
Copyright (C) 2016 Apple Inc. All Rights Reserved.
|
||||
See LICENSE.txt for this sample’s licensing information
|
||||
|
||||
Abstract:
|
||||
The detail view controller for viewing and editing shortcut information (localized title, localized subtitle, and icon)
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
class ShortcutDetailViewController: UITableViewController {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
@IBOutlet weak var titleTextField: UITextField!
|
||||
@IBOutlet weak var subtitleTextField: UITextField!
|
||||
@IBOutlet weak var pickerView: UIPickerView!
|
||||
@IBOutlet weak var doneButton: UIBarButtonItem!
|
||||
|
||||
var pickerItems = ["Compose", "Play", "Pause", "Add", "Location", "Search", "Share"]
|
||||
|
||||
/// Used to share information between this controller and its parent.
|
||||
var shortcutItem: UIApplicationShortcutItem?
|
||||
|
||||
/// The observer token for the `UITextFieldDidChangeNotification`.
|
||||
var textFieldObserverToken: NSObjectProtocol?
|
||||
|
||||
// MARK: - Object Life Cycle
|
||||
|
||||
deinit {
|
||||
guard let token = textFieldObserverToken else { return }
|
||||
NSNotificationCenter.defaultCenter().removeObserver(token)
|
||||
}
|
||||
|
||||
// MARK: - View Life Cycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Initialize the UI to reflect the values of the `shortcutItem`.
|
||||
guard let selectedShortcutItem = shortcutItem else {
|
||||
fatalError("The `selectedShortcutItem` was not set.")
|
||||
}
|
||||
|
||||
title = selectedShortcutItem.localizedTitle
|
||||
|
||||
titleTextField.text = selectedShortcutItem.localizedTitle
|
||||
subtitleTextField.text = selectedShortcutItem.localizedSubtitle
|
||||
|
||||
// Extract the raw value representing the icon from the userInfo dictionary, if provided.
|
||||
guard let iconRawValue = selectedShortcutItem.userInfo?[AppDelegate.applicationShortcutUserInfoIconKey] as? Int else { return }
|
||||
|
||||
// Select the matching row in the picker for the icon type.
|
||||
let iconType = iconTypeForSelectedRow(iconRawValue)
|
||||
|
||||
// The `iconType` returned may not align to the `iconRawValue` so use the `iconType`'s `rawValue`.
|
||||
pickerView.selectRow(iconType.rawValue, inComponent:0, animated:false)
|
||||
|
||||
let notificationCenter = NSNotificationCenter.defaultCenter()
|
||||
textFieldObserverToken = notificationCenter.addObserverForName(UITextFieldTextDidChangeNotification, object: nil, queue: nil) { [weak self] _ in
|
||||
guard let strongSelf = self else { return }
|
||||
|
||||
// You cannot dismiss the view controller without a valid shortcut title.
|
||||
let titleTextLength = strongSelf.titleTextField.text?.characters.count ?? 0
|
||||
strongSelf.doneButton.enabled = titleTextLength > 0
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UITextFieldDelegate
|
||||
|
||||
func textFieldShouldReturn(textField: UITextField) -> Bool {
|
||||
textField.resignFirstResponder()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// MARK: - UIPickerViewDataSource
|
||||
|
||||
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||
return pickerItems.count
|
||||
}
|
||||
|
||||
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
|
||||
return pickerItems[row]
|
||||
}
|
||||
|
||||
/// Constructs a UIApplicationShortcutIconType based on the integer result from our picker.
|
||||
func iconTypeForSelectedRow(row: Int) -> UIApplicationShortcutIconType {
|
||||
return UIApplicationShortcutIconType(rawValue: row) ?? .Compose
|
||||
}
|
||||
|
||||
// MARK: - UIStoryboardSegue Handling
|
||||
|
||||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
||||
guard let selectedShortcutItem = shortcutItem else {
|
||||
fatalError("The `selectedShortcutItem` was not set.")
|
||||
}
|
||||
|
||||
if segue.identifier == "ShortcutDetailUpdated" {
|
||||
// In the updated case, create a shortcut item to represent the final state of the view controller.
|
||||
let iconType = iconTypeForSelectedRow(pickerView.selectedRowInComponent(0))
|
||||
|
||||
let icon = UIApplicationShortcutIcon(type: iconType)
|
||||
|
||||
shortcutItem = UIApplicationShortcutItem(type: selectedShortcutItem.type, localizedTitle: titleTextField.text ?? "", localizedSubtitle: subtitleTextField.text, icon: icon, userInfo: [
|
||||
AppDelegate.applicationShortcutUserInfoIconKey: pickerView.selectedRowInComponent(0)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
Copyright (C) 2016 Apple Inc. All Rights Reserved.
|
||||
See LICENSE.txt for this sample’s licensing information
|
||||
|
||||
Abstract:
|
||||
The primary view controller listing the mutable shortcuts registered for this sample.
|
||||
*/
|
||||
|
||||
import UIKit
|
||||
|
||||
class ShortcutsTableViewController: UITableViewController {
|
||||
// MARK: - Properties
|
||||
|
||||
/// Pre-defined shortcuts; retrieved from the Info.plist, lazily.
|
||||
lazy var staticShortcuts: [UIApplicationShortcutItem] = {
|
||||
// Obtain the `UIApplicationShortcutItems` array from the Info.plist. If unavailable, there are no static shortcuts.
|
||||
guard let shortcuts = NSBundle.mainBundle().infoDictionary?["UIApplicationShortcutItems"] as? [[String: NSObject]] else { return [] }
|
||||
|
||||
// Use `flatMap(_:)` to process each dictionary into a `UIApplicationShortcutItem`, if possible.
|
||||
let shortcutItems = shortcuts.flatMap { shortcut -> [UIApplicationShortcutItem] in
|
||||
// The `UIApplicationShortcutItemType` and `UIApplicationShortcutItemTitle` keys are required to successfully create a `UIApplicationShortcutItem`.
|
||||
guard let shortcutType = shortcut["UIApplicationShortcutItemType"] as? String,
|
||||
let shortcutTitle = shortcut["UIApplicationShortcutItemTitle"] as? String else { return [] }
|
||||
|
||||
// Get the localized title.
|
||||
var localizedShortcutTitle = shortcutTitle
|
||||
if let localizedTitle = NSBundle.mainBundle().localizedInfoDictionary?[shortcutTitle] as? String {
|
||||
localizedShortcutTitle = localizedTitle
|
||||
}
|
||||
|
||||
/*
|
||||
The `UIApplicationShortcutItemSubtitle` key is optional. If it
|
||||
exists, get the localized version.
|
||||
*/
|
||||
var localizedShortcutSubtitle: String?
|
||||
if let shortcutSubtitle = shortcut["UIApplicationShortcutItemSubtitle"] as? String {
|
||||
localizedShortcutSubtitle = NSBundle.mainBundle().localizedInfoDictionary?[shortcutSubtitle] as? String
|
||||
}
|
||||
|
||||
return [
|
||||
UIApplicationShortcutItem(type: shortcutType, localizedTitle: localizedShortcutTitle, localizedSubtitle: localizedShortcutSubtitle, icon: nil, userInfo: nil)
|
||||
]
|
||||
}
|
||||
|
||||
return shortcutItems
|
||||
}()
|
||||
|
||||
/// Shortcuts defined by the application and modifiable based on application state.
|
||||
lazy var dynamicShortcuts = UIApplication.sharedApplication().shortcutItems ?? []
|
||||
|
||||
// MARK: - UITableViewDataSource
|
||||
|
||||
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
return ["Static", "Dynamic"][section]
|
||||
}
|
||||
|
||||
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return section == 0 ? staticShortcuts.count : dynamicShortcuts.count
|
||||
}
|
||||
|
||||
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCellWithIdentifier("CellID", forIndexPath: indexPath)
|
||||
|
||||
let shortcut: UIApplicationShortcutItem
|
||||
|
||||
if indexPath.section == 0 {
|
||||
// Static shortcuts (cannot be edited).
|
||||
shortcut = staticShortcuts[indexPath.row]
|
||||
cell.accessoryType = .None
|
||||
cell.selectionStyle = .None
|
||||
}
|
||||
else {
|
||||
// Dynamic shortcuts.
|
||||
shortcut = dynamicShortcuts[indexPath.row]
|
||||
}
|
||||
|
||||
cell.textLabel?.text = shortcut.localizedTitle
|
||||
cell.detailTextLabel?.text = shortcut.localizedSubtitle
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
// MARK: - Navigation
|
||||
|
||||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
||||
// Supply the `shortcutItem` matching the selected row from the data source.
|
||||
if segue.identifier == "ShowShortcutDetail" {
|
||||
guard let indexPath = tableView.indexPathForSelectedRow,
|
||||
let controller = segue.destinationViewController as? ShortcutDetailViewController else { return }
|
||||
|
||||
controller.shortcutItem = dynamicShortcuts[indexPath.row]
|
||||
}
|
||||
}
|
||||
|
||||
override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
|
||||
// Block navigating to detail view controller for static shortcuts (which are not editable).
|
||||
guard let selectedIndexPath = tableView.indexPathForSelectedRow else { return false }
|
||||
|
||||
return selectedIndexPath.section > 0
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
// Unwind segue action called when the user taps 'Done' after navigating to the detail controller.
|
||||
@IBAction func done(sender: UIStoryboardSegue) {
|
||||
// Obtain the edited shortcut from our source view controller.
|
||||
guard let sourceViewController = sender.sourceViewController as? ShortcutDetailViewController,
|
||||
let selected = tableView.indexPathForSelectedRow,
|
||||
let updatedShortcutItem = sourceViewController.shortcutItem else { return }
|
||||
|
||||
// Update our data source.
|
||||
dynamicShortcuts[selected.row] = updatedShortcutItem
|
||||
|
||||
// Update the application's `shortcutItems`.
|
||||
UIApplication.sharedApplication().shortcutItems = dynamicShortcuts
|
||||
|
||||
tableView.reloadRowsAtIndexPaths([selected], withRowAnimation: .Automatic)
|
||||
}
|
||||
|
||||
// Unwind segue action called when the user taps 'Cancel' after navigating to the detail controller.
|
||||
@IBAction func cancel(sender: UIStoryboardSegue) {}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
shortcutTitle1 = "Search";
|
||||
shortcutSubtitle1 = "Will search for an item";
|
||||
|
||||
shortcutTitle2 = "Share";
|
||||
shortcutSubtitle2 = "Will share an item";
|
|
@ -0,0 +1,42 @@
|
|||
Sample code project: ApplicationShortcuts: Using UIApplicationShortcutItem
|
||||
Version: 1.2
|
||||
|
||||
IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2016 Apple Inc. All Rights Reserved.
|
|
@ -0,0 +1,20 @@
|
|||
# Application Shortcuts: Using UIApplicationShortcutItem
|
||||
|
||||
## Summary
|
||||
|
||||
Demonstrates how to use the UIApplicationShortcutItem class in your application so users can quickly access parts of an application through “Quick actions” from the Home screen.
|
||||
It implements four different shortcuts, two static defined (UIApplicationShortcutItem) in your Info.pist, two dynamic or mutable (UIMutableApplicationShortcutItem) defined through code. The mutable shortcuts can be edited to change that title, subtitle and icon.
|
||||
|
||||
IMPORTANT: This sample should be run on an iPhone 6s or 6s Plus device. The iOS simulator will allow use of the shortcuts through its Hardware -> Touch Pressure menu, which requires a Trackpad.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Build
|
||||
|
||||
iOS 10.0 SDK, Xcode 8.0
|
||||
|
||||
### Runtime
|
||||
|
||||
iOS 9.0
|
||||
|
||||
Copyright (C) 2015-2016 Apple Inc. All rights reserved.
|
Loading…
Reference in New Issue