diff --git a/.buckconfig b/.buckconfig
index 8ebc4558..aeed3a9c 100644
--- a/.buckconfig
+++ b/.buckconfig
@@ -8,7 +8,7 @@
[swift]
version = 4.0
- compiler_flags = -DBUCK -enable-testing -g -Onone -whole-module-optimization $(config custom.other_swift_compiler_flags)
+ compiler_flags = -DBUCK -enable-testing -g -Onone -whole-module-optimization $(config custom.other_swift_compiler_flags) -DDISABLE_SIRI_SHORTCUT
use_filelist = true
[apple]
@@ -41,4 +41,3 @@
code_coverage_cxxflags = -fprofile-instr-generate -fcoverage-mapping
code_coverage_ldflags = -fprofile-instr-generate
code_coverage_swift_compiler_flags = -profile-generate -profile-coverage-mapping
-
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 5b4a20e6..361c7ec0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,7 +10,9 @@ tools/buck
# Xcode
**/xcuserdata/
**/*.xcodeproj/
+!App/SiriShortcut/_IntentsCompiler/IntentsCompiler.xcodeproj
**/*.xcworkspace/
+**/build/
# Make
*.d
diff --git a/App/AppDelegate.swift b/App/AppDelegate.swift
index db787385..ae9514e1 100644
--- a/App/AppDelegate.swift
+++ b/App/AppDelegate.swift
@@ -13,10 +13,42 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
let window = UIWindow(frame: UIScreen.main.bounds)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: ArgType) -> Bool {
-
+
window.makeKeyAndVisible()
window.rootViewController = ViewController()
return true
}
+
+ #if !DISABLE_SIRI_SHORTCUT
+ #if swift(>=4.2)
+ // Xcode 10
+ func application(
+ _ application: UIApplication,
+ continue userActivity: NSUserActivity,
+ restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
+ {
+ return continueWithUserActivity(userActivity)
+ }
+ #endif
+ #endif
+
+ // MARK: Private
+
+ private func continueWithUserActivity(_ userActivity: NSUserActivity) -> Bool {
+ guard #available(iOS 12.0, *) else {
+ return false
+ }
+
+ #if !DISABLE_SIRI_SHORTCUT
+ if let buckPhotoIntent = userActivity.interaction?.intent as? BuckPhotoIntent {
+ print("Launched with BuckPhotoIntent: \(buckPhotoIntent)")
+ return true
+ } else {
+ return false
+ }
+ #else
+ return false
+ #endif
+ }
}
diff --git a/App/BUCK b/App/BUCK
index 10df6e6d..21f1eadf 100644
--- a/App/BUCK
+++ b/App/BUCK
@@ -1,5 +1,5 @@
-load("//Config:configs.bzl", "app_binary_configs", "library_configs", "watch_binary_configs", "message_binary_configs", "pretty", "info_plist_substitutions", "bundle_identifier", "DEVELOPMENT_LANGUAGE")
-load("//Config:buck_rule_macros.bzl", "apple_lib", "apple_test_lib", "apple_test_all")
+load("//Config:configs.bzl", "app_binary_configs", "library_configs", "watch_binary_configs", "message_binary_configs", "intent_binary_configs", "pretty", "info_plist_substitutions", "bundle_identifier", "DEVELOPMENT_LANGUAGE")
+load("//Config:buck_rule_macros.bzl", "apple_lib", "apple_test_lib", "apple_test_all", "intent_interface")
apple_asset_catalog(
name = "ExampleAppAssets",
@@ -57,8 +57,10 @@ apple_library(
swift_version = "4.0",
srcs = [
"ViewController.swift",
+ "ViewController+INUIAddVoiceShortcutViewControllerDelegate.swift",
"AppDelegate.swift",
"LocalizationHelper.swift",
+ ":BuckPhotoIntentInterface",
],
tests = app_tests,
deps = [
@@ -69,10 +71,16 @@ apple_library(
# Resources
"//App/Resources:ExampleAppStringResources",
+ "//App/Resources:IntentsDefinition",
+ "//App/Resources:IntentsStringResources",
"//App/Resources:StoryboardResources",
]
+ first_party_library_dependencies
+ build_phase_scripts,
+ frameworks = [
+ "$SDKROOT/System/Library/Frameworks/Intents.framework",
+ "$SDKROOT/System/Library/Frameworks/IntentsUI.framework",
+ ],
)
apple_binary(
@@ -82,6 +90,7 @@ apple_binary(
"//App/...",
],
configs = app_binary_configs("ExampleApp"),
+ entitlements_file = "ExampleApp.entitlements",
swift_version = "4.0",
srcs = [
"BuckSupportFiles/Dummy.swift",
@@ -148,7 +157,9 @@ apple_bundle(
deps = [
# For "#watch", https://buckbuild.com/rule/apple_bundle.html#deps
":ExampleWatchApp#watch",
- ":ExampleMessageExtension"
+ ":ExampleMessageExtension",
+ ":ExampleIntentExtension",
+ ":ExampleIntentUIExtension",
]
+ prebuilt_frameworks,
)
@@ -158,6 +169,129 @@ apple_package(
bundle = ":ExampleApp",
)
+### Siri Shortcut Begin ###
+
+# Set up `BuckPhotoIntent` by handling the .intentdefinition file.
+intent_interface(
+ "BuckPhotoIntentInterface",
+ "BuckPhoto",
+ "SiriShortcut/_IntentsCompiler/IntentsCompiler.xcodeproj")
+
+# The non-UI code for processing `BuckPhotoIntent`.
+intent_bundle_identifier = bundle_identifier("ExampleApp.IntentExtension")
+intent_binary_name = "ExampleIntentBinary"
+intent_bundle_name = "ExampleIntentExtension"
+intent_info_plist_substitutions = {
+ "DEVELOPMENT_LANGUAGE": "en-us",
+ "EXECUTABLE_NAME": intent_bundle_name,
+ "PRODUCT_BUNDLE_DISPLAY_NAME": intent_bundle_name,
+ "PRODUCT_BUNDLE_IDENTIFIER": intent_bundle_identifier,
+ "PRODUCT_NAME": intent_bundle_name,
+ # The Swift module name for `IntentHandler` is the binary name.
+ "NS_EXTENSION_PRINCIPAL_CLASS": "%s.IntentHandler" % intent_binary_name,
+}
+
+apple_binary(
+ name = intent_binary_name,
+ srcs = glob([
+ "SiriShortcut/ExampleIntent/**/*.swift",
+ ]) + [":BuckPhotoIntentInterface"],
+ configs = intent_binary_configs(intent_info_plist_substitutions),
+
+ # "-e _NSExtensionMain" tell linker this binary is app extension, so it won't fail due to
+ # missing _main "-Xlinker -rpath -Xlinker @executable_path/../../Frameworks" tells the
+ # executable binary to look for frameworks in ExampleApp.app/Frameworks instead of PlugIns, so
+ # that we don't need to have the libSwift*.dylib in ExampleApp.app/PlugIns/*.appex/Frameworks
+ linker_flags = [
+ "-e",
+ "_NSExtensionMain",
+ "-Xlinker",
+ "-rpath",
+ "-Xlinker",
+ "@executable_path/../../Frameworks",
+ ],
+ deps = [
+ "//App/Resources:IntentsDefinition",
+ "//App/Resources:IntentsStringResources",
+ ],
+ frameworks = [
+ "$SDKROOT/System/Library/Frameworks/Intents.framework",
+ ],
+)
+
+apple_bundle(
+ name = intent_bundle_name,
+ binary = ":" + intent_binary_name,
+ extension = "appex",
+ info_plist = "SiriShortcut/ExampleIntent/Info.plist",
+ info_plist_substitutions = intent_info_plist_substitutions,
+ xcode_product_type = "com.apple.product-type.app-extension",
+)
+
+# The UI code for displaying the response to `BuckPhotoIntent`.
+intentui_bundle_identifier = bundle_identifier("ExampleApp.IntentUIExtension")
+intentui_binary_name = "ExampleIntentUIBinary"
+intentui_bundle_name = "ExampleIntentUIExtension"
+intentui_resources_name = intentui_bundle_name + "Resources"
+intentui_info_plist_substitutions = {
+ "DEVELOPMENT_LANGUAGE": "en-us",
+ "EXECUTABLE_NAME": intentui_bundle_name,
+ "PRODUCT_BUNDLE_DISPLAY_NAME": intentui_bundle_name,
+ "PRODUCT_BUNDLE_IDENTIFIER": intentui_bundle_identifier,
+ "PRODUCT_NAME": intentui_bundle_name,
+}
+
+apple_binary(
+ name = intentui_binary_name,
+ srcs = glob([
+ "SiriShortcut/ExampleIntentUI/**/*.swift",
+ ]) + [":BuckPhotoIntentInterface"],
+ configs = intent_binary_configs(intentui_info_plist_substitutions),
+
+ # "-e _NSExtensionMain" tell linker this binary is app extension, so it won't fail due to
+ # missing _main "-Xlinker -rpath -Xlinker @executable_path/../../Frameworks" tells the
+ # executable binary to look for frameworks in ExampleApp.app/Frameworks instead of PlugIns, so
+ # that we don't need to have the libSwift*.dylib in ExampleApp.app/PlugIns/*.appex/Frameworks
+ linker_flags = [
+ "-e",
+ "_NSExtensionMain",
+ "-Xlinker",
+ "-rpath",
+ "-Xlinker",
+ "@executable_path/../../Frameworks",
+ ],
+ deps = [
+ "//App/Resources:IntentsDefinition",
+ "//App/Resources:IntentsStringResources",
+ ],
+ frameworks = [
+ "$SDKROOT/System/Library/Frameworks/Intents.framework",
+ "$SDKROOT/System/Library/Frameworks/IntentsUI.framework",
+ ],
+)
+
+apple_resource(
+ name = intentui_resources_name,
+ dirs = [],
+ # WORKAROUND: Buck CLI requires you to explicitly set the "Module Name" of the
+ # `IntentViewController` class to `ExampleIntentUIBinary` in MainInterface.storyboard.
+ files = glob(["SiriShortcut/ExampleIntentUI/**/*.storyboard"])
+)
+
+apple_bundle(
+ name = intentui_bundle_name,
+ binary = ":" + intentui_binary_name,
+ extension = "appex",
+ info_plist = "SiriShortcut/ExampleIntentUI/Info.plist",
+ info_plist_substitutions = intentui_info_plist_substitutions,
+ xcode_product_type = "com.apple.product-type.app-extension",
+ deps = [
+ ":" + intentui_resources_name,
+ ],
+)
+
+### Siri Shortcut End ###
+
### Watch App Begin ###
# Define the watch app in the same BUCK file as the binary into which the watch app will be installed.
# Xcode is finicky when it comes to how it embeds watch apps into main app bundles. Watch apps are
diff --git a/App/ExampleApp.entitlements b/App/ExampleApp.entitlements
new file mode 100644
index 00000000..21d95c45
--- /dev/null
+++ b/App/ExampleApp.entitlements
@@ -0,0 +1,8 @@
+
+
+
+
+ com.apple.developer.siri
+
+
+
diff --git a/App/Info.plist b/App/Info.plist
index d08e8bd2..b0084189 100644
--- a/App/Info.plist
+++ b/App/Info.plist
@@ -29,6 +29,10 @@
1
LSRequiresIPhoneOS
+ NSUserActivityTypes
+
+ BuckPhotoIntent
+
UILaunchStoryboardName
LaunchScreen
UIRequiredDeviceCapabilities
diff --git a/App/Resources/BUCK b/App/Resources/BUCK
index 96886192..1ec2bc93 100644
--- a/App/Resources/BUCK
+++ b/App/Resources/BUCK
@@ -1,3 +1,5 @@
+load("//Config:buck_rule_macros.bzl", "intentdefinition_resource")
+
apple_resource(
name = "ExampleAppStringResources",
visibility = ["//App:"],
@@ -7,6 +9,15 @@ apple_resource(
]),
)
+apple_resource(
+ name = "IntentsStringResources",
+ visibility = ["//App:"],
+ files = [],
+ variants = glob([
+ "*.lproj/Intents.strings",
+ ]),
+)
+
apple_resource(
name = "StoryboardResources",
visibility = ["//App:"],
@@ -14,3 +25,5 @@ apple_resource(
"*.lproj/*.storyboard",
]),
)
+
+intentdefinition_resource("IntentsDefinition", "./en.lproj/", "Intents", "en")
diff --git a/App/Resources/en.lproj/ExampleApp.strings b/App/Resources/en.lproj/ExampleApp.strings
index 61fd1ae3..48f1a243 100644
--- a/App/Resources/en.lproj/ExampleApp.strings
+++ b/App/Resources/en.lproj/ExampleApp.strings
@@ -1,4 +1,4 @@
-/*
+/*
ExampleApp.strings
ExampleApp
@@ -7,3 +7,4 @@
*/
"Hello, world" = "Hello, world";
+"Show me a buck" = "Show me a buck";
diff --git a/App/Resources/en.lproj/Intents.intentdefinition b/App/Resources/en.lproj/Intents.intentdefinition
new file mode 100644
index 00000000..30ef1282
--- /dev/null
+++ b/App/Resources/en.lproj/Intents.intentdefinition
@@ -0,0 +1,93 @@
+
+
+
+
+ INEnums
+
+ INIntentDefinitionModelVersion
+ 1.0
+ INIntentDefinitionSystemVersion
+ 18E226
+ INIntentDefinitionToolsBuildVersion
+ 10E1001
+ INIntentDefinitionToolsVersion
+ 10.2.1
+ INIntents
+
+
+ INIntentCategory
+ information
+ INIntentDescription
+ Shows a photo of a buck.
+ INIntentDescriptionID
+ WWnWNH
+ INIntentLastParameterTag
+ 0
+ INIntentName
+ BuckPhoto
+ INIntentParameterCombinations
+
+
+
+ INIntentParameterCombinationIsPrimary
+
+ INIntentParameterCombinationSubtitle
+ See a buck.
+ INIntentParameterCombinationSubtitleID
+ Skm7E3
+ INIntentParameterCombinationSupportsBackgroundExecution
+
+ INIntentParameterCombinationTitle
+
+ INIntentParameterCombinationTitleID
+ ejGvr8
+
+
+ INIntentParameters
+
+ INIntentResponse
+
+ INIntentResponseCodes
+
+
+ INIntentResponseCodeFormatString
+ No bucks in the area today.
+ INIntentResponseCodeFormatStringID
+ HfNLHd
+ INIntentResponseCodeName
+ failure
+ INIntentResponseCodeSuccess
+
+
+
+ INIntentResponseCodeFormatString
+ Here is a wild buck.
+ INIntentResponseCodeFormatStringID
+ 0U61v4
+ INIntentResponseCodeName
+ success
+ INIntentResponseCodeSuccess
+
+
+
+ INIntentResponseLastParameterTag
+ 0
+ INIntentResponseParameters
+
+
+ INIntentRestrictions
+ 0
+ INIntentTitle
+ Buck Photo
+ INIntentTitleID
+ 7wFgFZ
+ INIntentType
+ Custom
+ INIntentUserConfirmationRequired
+
+ INIntentVerb
+ View
+
+
+
+
diff --git a/App/Resources/es.lproj/ExampleApp.strings b/App/Resources/es.lproj/ExampleApp.strings
index 017af457..9017fd37 100644
--- a/App/Resources/es.lproj/ExampleApp.strings
+++ b/App/Resources/es.lproj/ExampleApp.strings
@@ -1,4 +1,4 @@
-/*
+/*
ExampleApp.strings
ExampleApp
@@ -7,3 +7,4 @@
*/
"Hello, world" = "Hola, mundo";
+"Show me a buck" = "Muéstrame un venado";
\ No newline at end of file
diff --git a/App/Resources/es.lproj/Intents.strings b/App/Resources/es.lproj/Intents.strings
new file mode 100644
index 00000000..c85fa4be
--- /dev/null
+++ b/App/Resources/es.lproj/Intents.strings
@@ -0,0 +1,10 @@
+"0U61v4" = "Aqui hay un venado salvaje.";
+
+"7wFgFZ" = "Foto de un Venado";
+
+"HfNLHd" = "No hay venados en esta área hoy.";
+
+"Skm7E3" = "Ve un venado.";
+
+"WWnWNH" = "Muestra la foto de un venado.";
+
diff --git a/App/SiriShortcut/ExampleIntent/BuckPhotoIntentHandler.swift b/App/SiriShortcut/ExampleIntent/BuckPhotoIntentHandler.swift
new file mode 100644
index 00000000..a0865fe0
--- /dev/null
+++ b/App/SiriShortcut/ExampleIntent/BuckPhotoIntentHandler.swift
@@ -0,0 +1,24 @@
+// Created by Michael Bachand on 4/27/19.
+// Copyright © 2019 Airbnb Inc. All rights reserved.
+
+import Foundation
+
+#if !DISABLE_SIRI_SHORTCUT
+@available(iOS 12.0, *)
+final class BuckPhotoIntentHandler: NSObject, BuckPhotoIntentHandling {
+
+ func confirm(
+ intent: BuckPhotoIntent,
+ completion: @escaping (BuckPhotoIntentResponse) -> Void)
+ {
+ // In a real app, you would probably want to do some check here to make sure you're ready.
+ completion(BuckPhotoIntentResponse(code: .ready, userActivity: nil))
+ }
+
+ func handle(intent: BuckPhotoIntent, completion: @escaping (BuckPhotoIntentResponse) -> Void) {
+ completion(BuckPhotoIntentResponse(code: .success, userActivity: nil))
+ }
+}
+#else
+final class BuckPhotoIntentHandler {}
+#endif
diff --git a/App/SiriShortcut/ExampleIntent/Info.plist b/App/SiriShortcut/ExampleIntent/Info.plist
new file mode 100644
index 00000000..379d0e6f
--- /dev/null
+++ b/App/SiriShortcut/ExampleIntent/Info.plist
@@ -0,0 +1,44 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ $(PRODUCT_BUNDLE_DISPLAY_NAME)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ XPC!
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ NSExtension
+
+ NSExtensionAttributes
+
+ IntentsRestrictedWhileLocked
+
+ IntentsSupported
+
+ BuckPhotoIntent
+
+
+ NSExtensionPointIdentifier
+ com.apple.intents-service
+ NSExtensionPrincipalClass
+ $(NS_EXTENSION_PRINCIPAL_CLASS)
+
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+
+
diff --git a/App/SiriShortcut/ExampleIntent/IntentHandler.swift b/App/SiriShortcut/ExampleIntent/IntentHandler.swift
new file mode 100644
index 00000000..c018e8e4
--- /dev/null
+++ b/App/SiriShortcut/ExampleIntent/IntentHandler.swift
@@ -0,0 +1,21 @@
+// Created by Michael Bachand on 4/20/19.
+// Copyright © 2019 Airbnb Inc. All rights reserved.
+
+import Intents
+
+class IntentHandler: INExtension {
+
+ override func handler(for intent: INIntent) -> Any {
+ if #available(iOS 12.0, *) {
+ #if !DISABLE_SIRI_SHORTCUT
+ guard intent is BuckPhotoIntent else {
+ fatalError("Unhandled intent type: \(intent)")
+ }
+ #endif
+ return BuckPhotoIntentHandler()
+ } else {
+ fatalError("Unexpectly executing code path on iOS < 12.0")
+ }
+ }
+
+}
diff --git a/App/SiriShortcut/ExampleIntentUI/Base.lproj/MainInterface.storyboard b/App/SiriShortcut/ExampleIntentUI/Base.lproj/MainInterface.storyboard
new file mode 100644
index 00000000..07777937
--- /dev/null
+++ b/App/SiriShortcut/ExampleIntentUI/Base.lproj/MainInterface.storyboard
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/App/SiriShortcut/ExampleIntentUI/Info.plist b/App/SiriShortcut/ExampleIntentUI/Info.plist
new file mode 100644
index 00000000..3499f328
--- /dev/null
+++ b/App/SiriShortcut/ExampleIntentUI/Info.plist
@@ -0,0 +1,42 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ $(PRODUCT_BUNDLE_DISPLAY_NAME)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ XPC!
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ NSExtension
+
+ NSExtensionAttributes
+
+ IntentsSupported
+
+ BuckPhotoIntent
+
+
+ NSExtensionMainStoryboard
+ MainInterface
+ NSExtensionPointIdentifier
+ com.apple.intents-ui-service
+
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+
+
diff --git a/App/SiriShortcut/ExampleIntentUI/IntentViewController.swift b/App/SiriShortcut/ExampleIntentUI/IntentViewController.swift
new file mode 100644
index 00000000..d73dd1bb
--- /dev/null
+++ b/App/SiriShortcut/ExampleIntentUI/IntentViewController.swift
@@ -0,0 +1,31 @@
+// Created by Michael Bachand on 4/20/19.
+// Copyright © 2019 Airbnb Inc. All rights reserved.
+
+import IntentsUI
+
+#if swift(>=4.0)
+final class IntentViewController: UIViewController, INUIHostedViewControlling {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ view.backgroundColor = .gray
+ // Do any additional setup after loading the view.
+ }
+
+ // Prepare your view controller for the interaction to handle.
+ func configureView(for parameters: Set, of interaction: INInteraction, interactiveBehavior: INUIInteractiveBehavior, context: INUIHostedViewContext, completion: @escaping (Bool, Set, CGSize) -> Void) {
+ // Do configuration here, including preparing views and calculating a desired size for presentation.
+ completion(true, parameters, self.desiredSize)
+ }
+
+ var desiredSize: CGSize {
+ guard let hostedViewMaximumAllowedSize = extensionContext?.hostedViewMaximumAllowedSize else {
+ fatalError("Unexpectedly could no extension context")
+ }
+ var result = hostedViewMaximumAllowedSize
+ result.height = 400
+ return result
+ }
+
+}
+#endif
diff --git a/App/SiriShortcut/_IntentsCompiler/IntentsCompiler.xcodeproj/project.pbxproj b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..7bb20353
--- /dev/null
+++ b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler.xcodeproj/project.pbxproj
@@ -0,0 +1,329 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ E43E3E4422700E1C00DBCD82 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = E43E3E4322700E1C00DBCD82 /* Intents.intentdefinition */; };
+ E4D2464522700F1C00587E6F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4D2464422700F1C00587E6F /* LaunchScreen.storyboard */; };
+ E4DA4374227008DC00DCB2E5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4DA4373227008DC00DCB2E5 /* AppDelegate.swift */; };
+ E4DA4379227008DC00DCB2E5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4DA4377227008DC00DCB2E5 /* Main.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ E43E3E4322700E1C00DBCD82 /* Intents.intentdefinition */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.intentdefinition; name = Intents.intentdefinition; path = ../../../Resources/en.lproj/Intents.intentdefinition; sourceTree = ""; };
+ E4D2464422700F1C00587E6F /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
+ E4DA4370227008DC00DCB2E5 /* IntentsCompiler.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IntentsCompiler.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ E4DA4373227008DC00DCB2E5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ E4DA4378227008DC00DCB2E5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ E4DA437F227008DD00DCB2E5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ E4DA436D227008DC00DCB2E5 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ E4DA4367227008DC00DCB2E5 = {
+ isa = PBXGroup;
+ children = (
+ E4DA4372227008DC00DCB2E5 /* IntentsCompiler */,
+ E4DA4371227008DC00DCB2E5 /* Products */,
+ );
+ sourceTree = "";
+ };
+ E4DA4371227008DC00DCB2E5 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ E4DA4370227008DC00DCB2E5 /* IntentsCompiler.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ E4DA4372227008DC00DCB2E5 /* IntentsCompiler */ = {
+ isa = PBXGroup;
+ children = (
+ E4DA4373227008DC00DCB2E5 /* AppDelegate.swift */,
+ E4DA437F227008DD00DCB2E5 /* Info.plist */,
+ E43E3E4322700E1C00DBCD82 /* Intents.intentdefinition */,
+ E4D2464422700F1C00587E6F /* LaunchScreen.storyboard */,
+ E4DA4377227008DC00DCB2E5 /* Main.storyboard */,
+ );
+ path = IntentsCompiler;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ E4DA436F227008DC00DCB2E5 /* IntentsCompiler */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = E4DA4382227008DD00DCB2E5 /* Build configuration list for PBXNativeTarget "IntentsCompiler" */;
+ buildPhases = (
+ E4DA436C227008DC00DCB2E5 /* Sources */,
+ E4DA436D227008DC00DCB2E5 /* Frameworks */,
+ E4DA436E227008DC00DCB2E5 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = IntentsCompiler;
+ productName = IntentsCompiler;
+ productReference = E4DA4370227008DC00DCB2E5 /* IntentsCompiler.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ E4DA4368227008DC00DCB2E5 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 1020;
+ LastUpgradeCheck = 1020;
+ ORGANIZATIONNAME = Airbnb;
+ TargetAttributes = {
+ E4DA436F227008DC00DCB2E5 = {
+ CreatedOnToolsVersion = 10.2;
+ };
+ };
+ };
+ buildConfigurationList = E4DA436B227008DC00DCB2E5 /* Build configuration list for PBXProject "IntentsCompiler" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = E4DA4367227008DC00DCB2E5;
+ productRefGroup = E4DA4371227008DC00DCB2E5 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ E4DA436F227008DC00DCB2E5 /* IntentsCompiler */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ E4DA436E227008DC00DCB2E5 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E4DA4379227008DC00DCB2E5 /* Main.storyboard in Resources */,
+ E4D2464522700F1C00587E6F /* LaunchScreen.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ E4DA436C227008DC00DCB2E5 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E43E3E4422700E1C00DBCD82 /* Intents.intentdefinition in Sources */,
+ E4DA4374227008DC00DCB2E5 /* AppDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ E4DA4377227008DC00DCB2E5 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ E4DA4378227008DC00DCB2E5 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ E4DA4380227008DD00DCB2E5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ 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 = 12.2;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ E4DA4381227008DD00DCB2E5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "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 = gnu11;
+ 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 = 12.2;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ E4DA4383227008DD00DCB2E5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = 5LL7P8E8RA;
+ INFOPLIST_FILE = IntentsCompiler/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.airbnb.IntentsCompiler;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ E4DA4384227008DD00DCB2E5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = 5LL7P8E8RA;
+ INFOPLIST_FILE = IntentsCompiler/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.airbnb.IntentsCompiler;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ E4DA436B227008DC00DCB2E5 /* Build configuration list for PBXProject "IntentsCompiler" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E4DA4380227008DD00DCB2E5 /* Debug */,
+ E4DA4381227008DD00DCB2E5 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ E4DA4382227008DD00DCB2E5 /* Build configuration list for PBXNativeTarget "IntentsCompiler" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ E4DA4383227008DD00DCB2E5 /* Debug */,
+ E4DA4384227008DD00DCB2E5 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = E4DA4368227008DC00DCB2E5 /* Project object */;
+}
diff --git a/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/AppDelegate.swift b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/AppDelegate.swift
new file mode 100644
index 00000000..bef7c804
--- /dev/null
+++ b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/AppDelegate.swift
@@ -0,0 +1,17 @@
+// Created by Michael Bachand on 4/23/19.
+// Copyright © 2019 Airbnb Inc. All rights reserved.
+
+import UIKit
+
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ // Override point for customization after application launch.
+ return true
+ }
+
+}
diff --git a/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/Base.lproj/Main.storyboard b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/Base.lproj/Main.storyboard
new file mode 100644
index 00000000..9a2bae08
--- /dev/null
+++ b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/Base.lproj/Main.storyboard
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/Info.plist b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/Info.plist
new file mode 100644
index 00000000..0af59823
--- /dev/null
+++ b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/Info.plist
@@ -0,0 +1,49 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ NSUserActivityTypes
+
+ BuckPhotoIntent
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/LaunchScreen.storyboard b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/LaunchScreen.storyboard
new file mode 100644
index 00000000..bfa36129
--- /dev/null
+++ b/App/SiriShortcut/_IntentsCompiler/IntentsCompiler/LaunchScreen.storyboard
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/App/SiriShortcut/_IntentsCompiler/README.md b/App/SiriShortcut/_IntentsCompiler/README.md
new file mode 100644
index 00000000..fd85a639
--- /dev/null
+++ b/App/SiriShortcut/_IntentsCompiler/README.md
@@ -0,0 +1,7 @@
+# IntentsCompiler Xcode Project
+
+`IntentDefinitionCodegen` is internal to Xcode. As such, Apple does not expose a standalone command for creating the Swift (or Objective-C) interface from an .intentdefinition.
+
+Airbnb has filed a Radar requesting this functionality.
+
+Until then, we are using this Xcode project to generate code from the .intentdefinition.
diff --git a/App/ViewController+INUIAddVoiceShortcutViewControllerDelegate.swift b/App/ViewController+INUIAddVoiceShortcutViewControllerDelegate.swift
new file mode 100644
index 00000000..e06f1d77
--- /dev/null
+++ b/App/ViewController+INUIAddVoiceShortcutViewControllerDelegate.swift
@@ -0,0 +1,23 @@
+// Created by Michael Bachand on 4/27/19.
+// Copyright © 2019 Airbnb Inc. All rights reserved.
+
+import IntentsUI
+import UIKit
+
+#if !DISABLE_SIRI_SHORTCUT
+@available(iOS 12.0, *)
+extension ViewController: INUIAddVoiceShortcutViewControllerDelegate {
+
+ func addVoiceShortcutViewController(
+ _ controller: INUIAddVoiceShortcutViewController,
+ didFinishWith voiceShortcut: INVoiceShortcut?,
+ error: Error?)
+ {
+ controller.dismiss(animated: true)
+ }
+
+ func addVoiceShortcutViewControllerDidCancel(_ controller: INUIAddVoiceShortcutViewController) {
+ controller.dismiss(animated: true)
+ }
+}
+#endif
diff --git a/App/ViewController.swift b/App/ViewController.swift
index fda0380b..b06ab777 100644
--- a/App/ViewController.swift
+++ b/App/ViewController.swift
@@ -1,6 +1,7 @@
import ASwiftModule
import Cpp1
import CryptoSwift
+import IntentsUI
import Objc1
import ObjcAndSwift
import PromiseKit
@@ -32,6 +33,17 @@ class ViewController: UIViewController {
self.view.addSubview(label)
label.sizeToFit()
label.center = self.view.center
+
+ #if !DISABLE_SIRI_SHORTCUT
+ if #available(iOS 12, *) {
+ let siriButton = INUIAddVoiceShortcutButton(style: .black)
+ siriButton.translatesAutoresizingMaskIntoConstraints = false
+ view.addSubview(siriButton)
+ siriButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
+ siriButton.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor, constant: -24).isActive = true
+ siriButton.addTarget(self, action: #selector(addToSiri(_:)), for: .touchUpInside)
+ }
+ #endif
}
override func viewDidAppear(_ animated: Bool) {
@@ -117,4 +129,19 @@ class ViewController: UIViewController {
print("AFNetworking's version is \(SwiftWithPrecompiledDependencyClass.networkingLibraryVersionNumber)")
}
+
+ @available(iOS 12.0, *)
+ @objc
+ dynamic private func addToSiri(_ sender: Any) {
+ #if !DISABLE_SIRI_SHORTCUT
+ let intent = BuckPhotoIntent()
+ intent.suggestedInvocationPhrase = localizedString("Show me a buck", "Invocation phrase for Siri Shortcut")
+ if let shortcut = INShortcut(intent: intent) {
+ let viewController = INUIAddVoiceShortcutViewController(shortcut: shortcut)
+ viewController.modalPresentationStyle = .formSheet
+ viewController.delegate = self
+ present(viewController, animated: true, completion: nil)
+ }
+ #endif
+ }
}
diff --git a/Config/buck_rule_macros.bzl b/Config/buck_rule_macros.bzl
index 793f34cf..8d8ebce8 100644
--- a/Config/buck_rule_macros.bzl
+++ b/Config/buck_rule_macros.bzl
@@ -260,10 +260,12 @@ def logging_genrule(
)
# Takes in a .mlmodel and produces a Swift interface and a compiled .mlmodelc.
-# - parameter resource_source_name: The expected name of the Swift interface to be included in `srcs`.
+# - parameter resource_source_name: The expected name of the Swift interface to be included in
+# `srcs`.
# - parameter resource_dependency_name: The expected name of the resource to add to `deps`.
-# - parameter model_directory: The relative path to folder where the .mlmodel lives. Must include a trailing slash.
-# - parameter model_name: The name of the .mlmodel. Do not include the .mlmodel suffix.
+# - parameter model_directory: The relative path to the folder where the .mlmodel lives. Must
+# include a trailing slash.
+# - parameter model_name: The name of the .mlmodel. Do not include the ".mlmodel" suffix.
# - parameter swift_version: The expected Swift version for the generated Swift interface file.
def mlmodel_resource(
resource_source_name,
@@ -281,10 +283,10 @@ def mlmodel_resource(
out = "%s.swift" % model_name,
)
- modelc_resource = resource_dependency_name + "_compiled_model"
+ genrule_name = "compile_" + resource_dependency_name
# Create a genrule to compile the mlmodelc from the mlmodel.
logging_genrule(
- name = modelc_resource,
+ name = genrule_name,
srcs = [model_directory + model_name + ".mlmodel"],
bash = 'xcrun coremlc compile "$SRCS" "\$(dirname "$OUT")"',
out = "%s.mlmodelc" % model_name,
@@ -294,7 +296,113 @@ def mlmodel_resource(
native.apple_resource(
name = resource_dependency_name,
dirs = [
- ":" + modelc_resource,
+ ":" + genrule_name,
],
files = [],
)
+
+# Takes in an .intentdefinition and produces the Swift interface for the specified intent.
+# - parameter interface_source_name: The expected name of the Swift interface to be included in
+# `srcs`.
+# - parameter intent_name: The name of the intent in the .intentdefinition for which source should
+# be generated. Do not include an "Intent" suffix.
+# - parameter compiler_xcodeproj: The relative path to the .xcodeproj used to generate the Swift
+# interface of the .intentdefinition. This project should reference the .intentdefinition that
+# contains `intent_name`.
+def intent_interface(
+ interface_source_name,
+ intent_name,
+ compiler_xcodeproj):
+
+ script = """
+ IFS=' ' read -ra SRCS_ARRAY <<< "$SRCS"
+ intents_compiler_xcodeproj="${SRCS_ARRAY[0]}"
+
+ # We cannot upgrade CI to Xcode 10 yet. If we are still in Xcode 9, output a dummy Swift file.
+ # It doesn't matter since Siri Shortcuts don't work in Xcode 9 anyway.
+ # We can delete this alternate code path when https://github.com/airbnb/BuckSample/issues/102
+ # is resolved.
+ if xcodebuild -version | grep "Xcode 1"; then
+ # `IntentDefinitionCodegen` is within Xcode.
+ xcodebuild \
+ -configuration Release \
+ -scheme 'IntentsCompiler' \
+ -project "$intents_compiler_xcodeproj" \
+ -derivedDataPath "$TMP" \
+ CODE_SIGN_IDENTITY="" \
+ CODE_SIGNING_REQUIRED=NO \
+ CODE_SIGNING_ALLOWED=NO
+
+ intent_interface="`find "$TMP" -name %sIntent.swift`"
+
+ if [[ -z "$intent_interface" ]]; then
+ echo "Compiler xcodeproj produced no Swift interface for the provided intent"
+ echo "Are you sure the .intentdefinition defines the intent?"
+ exit 1
+ fi
+ else
+ intent_interface="$TMP/Dummy.swift"
+ echo "class Dummy { }" > "$intent_interface"
+ fi
+
+ cp "$intent_interface" "$OUT"
+ """ % intent_name
+
+ logging_genrule(
+ name = interface_source_name,
+ srcs = [
+ compiler_xcodeproj,
+ ],
+ bash = script,
+ out = "%sIntent.swift" % intent_name,
+ )
+
+# Proceses an .intentdefinition, creating a resource that can be added as a dependency.
+# - parameter resource_dependency_name: The expected name of the resource to add to `deps`.
+# - parameter definition_directory: The relative path to the folder where the .intentdefinition
+# lives. Must include a trailing slash.
+# - parameter definition_name: The name of the .intentdefinition. Do not include the
+# ".intentdefinition" suffix.
+# - parameter localization: A localization abbreviation, such as "en". The processed
+# .intentdefinition will live in a .lproj directory of this name.
+def intentdefinition_resource(
+ resource_dependency_name,
+ definition_directory,
+ definition_name,
+ localization):
+
+ lproj_directory = "%s.lproj/" % localization
+
+ genrule_name = "process_" + resource_dependency_name
+ # Create a genrule to process the .intentdefinition file. As far as we can tell, the
+ # `intentbuilderc` command makes no change to the .intentdefinition file. We nevertheless run it
+ # in an effort to be defensive.
+ logging_genrule(
+ name = genrule_name,
+ srcs = [definition_directory + definition_name + ".intentdefinition"],
+ bash = """
+ lproj_dir=`dirname $OUT`
+ mkdir "$lproj_dir"
+
+ # We cannot upgrade CI to Xcode 10 yet. If we are still in Xcode 9, do not process.
+ # It doesn't matter since Siri Shortcuts don't work in Xcode 9 anyway.
+ # We can delete this alternate code path when
+ # https://github.com/airbnb/BuckSample/issues/102 is resolved.
+ if xcodebuild -version | grep "Xcode 1"; then
+ xcrun intentbuilderc $SRCS $TMP ""
+ else
+ cp $SRCS $TMP
+ fi
+ definition_basename=`basename $SRCS`
+ cp "$TMP/$definition_basename" $OUT
+ """,
+ out = lproj_directory + definition_name + ".intentdefinition",
+ )
+
+ native.apple_resource(
+ name = resource_dependency_name,
+ visibility = ["PUBLIC"],
+ variants = [
+ ":" + genrule_name,
+ ]
+ )
diff --git a/Config/configs.bzl b/Config/configs.bzl
index 3d2934c3..3e5380ac 100644
--- a/Config/configs.bzl
+++ b/Config/configs.bzl
@@ -57,6 +57,7 @@ def app_binary_configs(name):
"ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES": "YES",
"DEVELOPMENT_LANGUAGE": DEVELOPMENT_LANGUAGE,
"PRODUCT_BUNDLE_IDENTIFIER": bundle_identifier(name),
+ "CODE_SIGN_ENTITLEMENTS": (name + ".entitlements"),
}
binary_config = SHARED_CONFIGS + binary_specific_config
binary_config = config_with_updated_linker_flags(binary_config, ALL_LOAD_LINKER_FLAG)
@@ -118,3 +119,10 @@ def message_binary_configs(name):
}
config = config_with_updated_linker_flags(config, ALL_LOAD_LINKER_FLAG)
return configs_with_config(config)
+
+def intent_binary_configs(info_plist_substitutions):
+ config = { }
+ config.update(SHARED_CONFIGS)
+ config.update(info_plist_substitutions)
+ config = config_with_updated_linker_flags(config, ALL_LOAD_LINKER_FLAG)
+ return configs_with_config(config)