Merge pull request #1479 from morozkin/sirikit_new

Add Siri support for calls
This commit is contained in:
manuroe 2017-08-31 17:18:27 +02:00 committed by GitHub
commit d9dcd2ab6b
9 changed files with 612 additions and 2 deletions

30
Podfile
View file

@ -5,7 +5,6 @@ source 'https://github.com/CocoaPods/Specs.git'
target "Riot" do
# Different flavours of pods to MatrixKit
# The tagged version on which this version of Riot has been built
pod 'MatrixKit', '0.6.2'
@ -74,5 +73,34 @@ pod 'cmark', :inhibit_warnings => true
end
target "SiriIntents" do
pod 'GoogleAnalytics'
# The Google WebRTC stack
pod 'WebRTC', '58.17.16937'
# OLMKit for crypto
pod 'OLMKit'
#pod 'OLMKit', :path => '../olm/OLMKit.podspec'
pod 'Realm', '~> 2.8.1'
# The tagged version on which this version of Riot share extension has been built
pod 'MatrixKit/AppExtension', '0.6.2'
# The lastest release available on the CocoaPods repository
#pod 'MatrixKit/AppExtension'
# The develop branch version
#pod 'MatrixSDK', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop'
#pod 'MatrixKit/AppExtension', :git => 'https://github.com/matrix-org/matrix-ios-kit.git', :branch => 'develop'
# The one used for developing both MatrixSDK and MatrixKit
# Note that MatrixSDK must be cloned into a folder called matrix-ios-sdk next to the MatrixKit folder
#pod 'MatrixSDK', :path => '../matrix-ios-sdk/MatrixSDK.podspec'
#pod 'MatrixKit/AppExtension', :path => '../matrix-ios-kit/MatrixKit.podspec'
# Remove warnings from "bad" pods
pod 'OLMKit', :inhibit_warnings => true
pod 'cmark', :inhibit_warnings => true
end

View file

@ -76,6 +76,11 @@
32D392191EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32D392171EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.xib */; };
32FD0A3D1EB0CD9B0072B066 /* BugReportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32FD0A3B1EB0CD9B0072B066 /* BugReportViewController.m */; };
32FD0A3E1EB0CD9B0072B066 /* BugReportViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32FD0A3C1EB0CD9B0072B066 /* BugReportViewController.xib */; };
7A5A792D23877A47F33ADF07 /* libPods-SiriIntents.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 372FB22949C5652FF01D9793 /* libPods-SiriIntents.a */; };
9297595D1F2C8D4500535D3B /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9297595C1F2C8D4500535D3B /* Intents.framework */; };
92E963B51F28D907008FDAF5 /* IntentHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 92E963B41F28D907008FDAF5 /* IntentHandler.m */; };
92E963B91F28D907008FDAF5 /* SiriIntents.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 92E963B11F28D906008FDAF5 /* SiriIntents.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
E2EAC1A4FBD6FE5228584591 /* libPods-Riot.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D8737F782E108CFD6908691 /* libPods-Riot.a */; };
92324BE31F4F66D3009DE194 /* IncomingCallView.m in Sources */ = {isa = PBXBuildFile; fileRef = 92324BE21F4F66D3009DE194 /* IncomingCallView.m */; };
92324BE61F4F6A60009DE194 /* CircleButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 92324BE51F4F6A60009DE194 /* CircleButton.m */; };
A27ECCE3FC4971745D2CB78D /* libPods-RiotShareExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7246451C668D6782166E22EC /* libPods-RiotShareExtension.a */; };
@ -527,6 +532,13 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
92E963B71F28D907008FDAF5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F094A99A1B78D8F000B1FBBF /* Project object */;
proxyType = 1;
remoteGlobalIDString = 92E963B01F28D906008FDAF5;
remoteInfo = SiriIntents;
};
242661F51F12B1BA00D3FC08 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F094A99A1B78D8F000B1FBBF /* Project object */;
@ -544,6 +556,17 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
92E963BD1F28D907008FDAF5 /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
92E963B91F28D907008FDAF5 /* SiriIntents.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
24CBEC5D1F0EAD310093EABB /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -554,7 +577,7 @@
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
};
3233F7481F3497E2006ACA81 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -645,6 +668,16 @@
32FD0A3A1EB0CD9B0072B066 /* BugReportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugReportViewController.h; sourceTree = "<group>"; };
32FD0A3B1EB0CD9B0072B066 /* BugReportViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugReportViewController.m; sourceTree = "<group>"; };
32FD0A3C1EB0CD9B0072B066 /* BugReportViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = BugReportViewController.xib; sourceTree = "<group>"; };
372FB22949C5652FF01D9793 /* libPods-SiriIntents.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SiriIntents.a"; sourceTree = BUILT_PRODUCTS_DIR; };
47EC817AA9DA11B39694B1E0 /* Pods-SiriIntents.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SiriIntents.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SiriIntents/Pods-SiriIntents.debug.xcconfig"; sourceTree = "<group>"; };
7D8737F782E108CFD6908691 /* libPods-Riot.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Riot.a"; sourceTree = BUILT_PRODUCTS_DIR; };
9297595B1F2C8A9A00535D3B /* SiriIntents.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = SiriIntents.entitlements; sourceTree = "<group>"; };
9297595C1F2C8D4500535D3B /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; };
92E963B11F28D906008FDAF5 /* SiriIntents.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SiriIntents.appex; sourceTree = BUILT_PRODUCTS_DIR; };
92E963B31F28D907008FDAF5 /* IntentHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IntentHandler.h; sourceTree = "<group>"; };
92E963B41F28D907008FDAF5 /* IntentHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IntentHandler.m; sourceTree = "<group>"; };
92E963B61F28D907008FDAF5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E22DCA997BE673CD67E839B9 /* Pods-SiriIntents.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SiriIntents.release.xcconfig"; path = "Pods/Target Support Files/Pods-SiriIntents/Pods-SiriIntents.release.xcconfig"; sourceTree = "<group>"; };
7246451C668D6782166E22EC /* libPods-RiotShareExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RiotShareExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; };
765F5104DB3EC39713DEB3A4 /* Pods-RiotShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotShareExtension.release.xcconfig"; path = "Pods/Target Support Files/Pods-RiotShareExtension/Pods-RiotShareExtension.release.xcconfig"; sourceTree = "<group>"; };
839BB91240D350D5607D55BA /* Pods-Riot.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Riot.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Riot/Pods-Riot.debug.xcconfig"; sourceTree = "<group>"; };
@ -1229,6 +1262,15 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
92E963AE1F28D906008FDAF5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9297595D1F2C8D4500535D3B /* Intents.framework in Frameworks */,
7A5A792D23877A47F33ADF07 /* libPods-SiriIntents.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
24CBEC4B1F0EAD310093EABB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -1401,12 +1443,37 @@
5FC42FA41F5186AFFB6A2404 /* Frameworks */ = {
isa = PBXGroup;
children = (
9297595C1F2C8D4500535D3B /* Intents.framework */,
7D8737F782E108CFD6908691 /* libPods-Riot.a */,
372FB22949C5652FF01D9793 /* libPods-SiriIntents.a */,
FD9D0BDE9232898950554DD5 /* libPods-Riot.a */,
7246451C668D6782166E22EC /* libPods-RiotShareExtension.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
92E963B21F28D907008FDAF5 /* SiriIntents */ = {
isa = PBXGroup;
children = (
92E963B31F28D907008FDAF5 /* IntentHandler.h */,
92E963B41F28D907008FDAF5 /* IntentHandler.m */,
92E963B61F28D907008FDAF5 /* Info.plist */,
9297595B1F2C8A9A00535D3B /* SiriIntents.entitlements */,
);
path = SiriIntents;
sourceTree = "<group>";
};
E1451F540F8BC02A7FB7AA31 /* Pods */ = {
isa = PBXGroup;
children = (
1129C74A281B080432B1A1A1 /* Pods-Riot.debug.xcconfig */,
F9D678EF54918C036FDEDBF9 /* Pods-Riot.release.xcconfig */,
47EC817AA9DA11B39694B1E0 /* Pods-SiriIntents.debug.xcconfig */,
E22DCA997BE673CD67E839B9 /* Pods-SiriIntents.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
7471DF3720D498384A068DA7 /* Pods */ = {
isa = PBXGroup;
children = (
@ -2287,6 +2354,7 @@
children = (
F083BB081E7009EC00A9B29C /* Riot */,
F083BB021E7005FD00A9B29C /* RiotTests */,
92E963B21F28D907008FDAF5 /* SiriIntents */,
24CBEC4F1F0EAD310093EABB /* RiotShareExtension */,
F094A9A31B78D8F000B1FBBF /* Products */,
7471DF3720D498384A068DA7 /* Pods */,
@ -2299,6 +2367,7 @@
children = (
F094A9A21B78D8F000B1FBBF /* Riot.app */,
F094A9BE1B78D8F000B1FBBF /* RiotTests.xctest */,
92E963B11F28D906008FDAF5 /* SiriIntents.appex */,
24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */,
);
name = Products;
@ -2317,6 +2386,25 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
92E963B01F28D906008FDAF5 /* SiriIntents */ = {
isa = PBXNativeTarget;
buildConfigurationList = 92E963BA1F28D907008FDAF5 /* Build configuration list for PBXNativeTarget "SiriIntents" */;
buildPhases = (
B1481C3FD667495EEBD83C1D /* [CP] Check Pods Manifest.lock */,
92E963AD1F28D906008FDAF5 /* Sources */,
92E963AE1F28D906008FDAF5 /* Frameworks */,
92E963AF1F28D906008FDAF5 /* Resources */,
D7AE9EDB223D9ED53DF15ABF /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = SiriIntents;
productName = SiriIntents;
productReference = 92E963B11F28D906008FDAF5 /* SiriIntents.appex */;
productType = "com.apple.product-type.app-extension";
};
24CBEC4D1F0EAD310093EABB /* RiotShareExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 24CBEC5C1F0EAD310093EABB /* Build configuration list for PBXNativeTarget "RiotShareExtension" */;
@ -2344,6 +2432,9 @@
F094A99E1B78D8F000B1FBBF /* Sources */,
F094A99F1B78D8F000B1FBBF /* Frameworks */,
F094A9A01B78D8F000B1FBBF /* Resources */,
44C35695CFA4F9799C449367 /* [CP] Copy Pods Resources */,
381DA4CC07D2104BFA23E45A /* [CP] Embed Pods Frameworks */,
92E963BD1F28D907008FDAF5 /* Embed App Extensions */,
24CBEC5D1F0EAD310093EABB /* Embed App Extensions */,
7FFD40AA75DB32D83350D225 /* [CP] Embed Pods Frameworks */,
68D6013FA64A4507DC9DB95B /* [CP] Copy Pods Resources */,
@ -2352,6 +2443,7 @@
buildRules = (
);
dependencies = (
92E963B81F28D907008FDAF5 /* PBXTargetDependency */,
242661F61F12B1BA00D3FC08 /* PBXTargetDependency */,
);
name = Riot;
@ -2386,6 +2478,16 @@
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = matrix.org;
TargetAttributes = {
92E963B01F28D906008FDAF5 = {
CreatedOnToolsVersion = 8.3.3;
DevelopmentTeam = 7J4U792NQT;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.ApplicationGroups.iOS = {
enabled = 1;
};
};
};
24CBEC4D1F0EAD310093EABB = {
CreatedOnToolsVersion = 8.3.2;
DevelopmentTeam = 7J4U792NQT;
@ -2407,6 +2509,9 @@
com.apple.Push = {
enabled = 1;
};
com.apple.Siri = {
enabled = 1;
};
};
};
F094A9BD1B78D8F000B1FBBF = {
@ -2435,12 +2540,20 @@
targets = (
F094A9A11B78D8F000B1FBBF /* Riot */,
F094A9BD1B78D8F000B1FBBF /* RiotTests */,
92E963B01F28D906008FDAF5 /* SiriIntents */,
24CBEC4D1F0EAD310093EABB /* RiotShareExtension */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
92E963AF1F28D906008FDAF5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
24CBEC4C1F0EAD310093EABB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -2974,9 +3087,47 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RiotShareExtension/Pods-RiotShareExtension-resources.sh\"\n";
showEnvVarsInLog = 0;
};
B1481C3FD667495EEBD83C1D /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
D7AE9EDB223D9ED53DF15ABF /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SiriIntents/Pods-SiriIntents-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
92E963AD1F28D906008FDAF5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
92E963B51F28D907008FDAF5 /* IntentHandler.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
24CBEC4A1F0EAD310093EABB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -3155,6 +3306,10 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
92E963B81F28D907008FDAF5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 92E963B01F28D906008FDAF5 /* SiriIntents */;
targetProxy = 92E963B71F28D907008FDAF5 /* PBXContainerItemProxy */;
242661F61F12B1BA00D3FC08 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 24CBEC4D1F0EAD310093EABB /* RiotShareExtension */;
@ -3299,6 +3454,26 @@
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
92E963BB1F28D907008FDAF5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 47EC817AA9DA11B39694B1E0 /* Pods-SiriIntents.debug.xcconfig */;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CODE_SIGN_ENTITLEMENTS = SiriIntents/SiriIntents.entitlements;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 7J4U792NQT;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = SiriIntents/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.SiriIntents;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
24CBEC5A1F0EAD310093EABB /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 12AA0005C8B3D8D8162584C5 /* Pods-RiotShareExtension.debug.xcconfig */;
@ -3321,6 +3496,27 @@
};
name = Debug;
};
92E963BC1F28D907008FDAF5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = E22DCA997BE673CD67E839B9 /* Pods-SiriIntents.release.xcconfig */;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CODE_SIGN_ENTITLEMENTS = SiriIntents/SiriIntents.entitlements;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 7J4U792NQT;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = SiriIntents/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.SiriIntents;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
24CBEC5B1F0EAD310093EABB /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 765F5104DB3EC39713DEB3A4 /* Pods-RiotShareExtension.release.xcconfig */;
@ -3515,6 +3711,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
92E963BA1F28D907008FDAF5 /* Build configuration list for PBXNativeTarget "SiriIntents" */ = {
isa = XCConfigurationList;
buildConfigurations = (
92E963BB1F28D907008FDAF5 /* Debug */,
92E963BC1F28D907008FDAF5 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
24CBEC5C1F0EAD310093EABB /* Build configuration list for PBXNativeTarget "RiotShareExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View file

@ -1557,6 +1557,9 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
// Get modular widget events in rooms histories
[[MXKAppSettings standardAppSettings] addSupportedEventTypes:@[kWidgetEventTypeString]];
// Use shared container to share data with app extensions
sdkOptions.applicationGroupIdentifier = @"group.im.vector";
// Disable long press on event in bubble cells
[MXKRoomBubbleTableViewCell disableLongPressGestureOnEvent:YES];

View file

@ -49,6 +49,8 @@
<string>The microphone is used to take videos, make calls.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>The photo library is used to send photos and videos.</string>
<key>NSSiriUsageDescription</key>
<string>Siri is used to perform calls even from the lock screen.</string>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>

View file

@ -11,6 +11,8 @@
<string>applinks:riot.im</string>
<string>applinks:www.riot.im</string>
</array>
<key>com.apple.developer.siri</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.im.vector</string>

41
SiriIntents/Info.plist Normal file
View file

@ -0,0 +1,41 @@
<?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>CFBundleDisplayName</key>
<string>SiriIntents</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>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsRestrictedWhileLocked</key>
<array/>
<key>IntentsSupported</key>
<array>
<string>INStartAudioCallIntent</string>
<string>INStartVideoCallIntent</string>
</array>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.intents-service</string>
<key>NSExtensionPrincipalClass</key>
<string>IntentHandler</string>
</dict>
</dict>
</plist>

View file

@ -0,0 +1,21 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import <Intents/Intents.h>
@interface IntentHandler : INExtension
@end

298
SiriIntents/IntentHandler.m Normal file
View file

@ -0,0 +1,298 @@
/*
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#import "IntentHandler.h"
#import "MXKAccount.h"
#import "MXKAccountManager.h"
#import "MXFileStore.h"
#import "MXSession.h"
@interface IntentHandler () <INStartAudioCallIntentHandling, INStartVideoCallIntentHandling>
@end
@implementation IntentHandler
- (instancetype)init
{
self = [super init];
if (self)
{
[MXSDKOptions sharedInstance].applicationGroupIdentifier = @"group.im.vector";
}
return self;
}
- (id)handlerForIntent:(INIntent *)intent
{
return self;
}
#pragma mark - INStartAudioCallIntentHandling
- (void)resolveContactsForStartAudioCall:(INStartAudioCallIntent *)intent withCompletion:(void (^)(NSArray<INPersonResolutionResult *> * _Nonnull))completion
{
[self resolveContacts:intent.contacts withCompletion:completion];
}
- (void)confirmStartAudioCall:(INStartAudioCallIntent *)intent completion:(void (^)(INStartAudioCallIntentResponse * _Nonnull))completion
{
INStartAudioCallIntentResponse *response = nil;
MXKAccount *account = [MXKAccountManager sharedManager].activeAccounts.firstObject;
if (account)
{
#if defined MX_CALL_STACK_OPENWEBRTC || defined MX_CALL_STACK_ENDPOINT || defined MX_CALL_STACK_JINGLE
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass(INStartAudioCallIntent.class)];
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeReady userActivity:userActivity];
#else
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeFailureCallingServiceNotAvailable userActivity:nil];
#endif
}
else
{
// User hasn't logged in
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeFailureRequiringAppLaunch userActivity:nil];
}
completion(response);
}
- (void)handleStartAudioCall:(INStartAudioCallIntent *)intent completion:(void (^)(INStartAudioCallIntentResponse * _Nonnull))completion
{
INStartAudioCallIntentResponse *response = nil;
INPerson *person = intent.contacts.firstObject;
if (person && person.customIdentifier)
{
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass(INStartAudioCallIntent.class)];
userActivity.userInfo = @{ @"roomID" : person.customIdentifier };
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeContinueInApp
userActivity:userActivity];
}
else
{
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeFailure userActivity:nil];
}
completion(response);
}
#pragma mark - INStartVideoCallIntentHandling
- (void)resolveContactsForStartVideoCall:(INStartVideoCallIntent *)intent withCompletion:(void (^)(NSArray<INPersonResolutionResult *> * _Nonnull))completion
{
[self resolveContacts:intent.contacts withCompletion:completion];
}
- (void)confirmStartVideoCall:(INStartVideoCallIntent *)intent completion:(void (^)(INStartVideoCallIntentResponse * _Nonnull))completion
{
INStartVideoCallIntentResponse *response = nil;
MXKAccount *account = [MXKAccountManager sharedManager].activeAccounts.firstObject;
if (account)
{
#if defined MX_CALL_STACK_OPENWEBRTC || defined MX_CALL_STACK_ENDPOINT || defined MX_CALL_STACK_JINGLE
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass(INStartVideoCallIntent.class)];
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeReady userActivity:userActivity];
#else
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeFailureCallingServiceNotAvailable userActivity:nil];
#endif
}
else
{
// User hasn't logged in
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeFailureRequiringAppLaunch userActivity:nil];
}
completion(response);
}
- (void)handleStartVideoCall:(INStartVideoCallIntent *)intent completion:(void (^)(INStartVideoCallIntentResponse * _Nonnull))completion
{
INStartVideoCallIntentResponse *response = nil;
INPerson *person = intent.contacts.firstObject;
if (person && person.customIdentifier)
{
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass(INStartVideoCallIntent.class)];
userActivity.userInfo = @{ @"roomID" : person.customIdentifier };
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeContinueInApp
userActivity:userActivity];
}
else
{
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeFailure userActivity:nil];
}
completion(response);
}
#pragma mark - Private
- (void)resolveContacts:(nullable NSArray<INPerson *> *)contacts withCompletion:(void (^)(NSArray<INPersonResolutionResult *> * _Nonnull))completion
{
if (contacts.count == 0)
{
completion(@[[INPersonResolutionResult needsValue]]);
return;
}
else
{
// We don't iterate over array of contacts from passed intent
// since it's hard to imagine scenario with several callee
// so we just extract the first one
INPerson *callee = contacts.firstObject;
// If this method is called after selection of the appropriate user, it will hold userId of an user to whom we must call
NSString *selectedUserId;
// Check if the user has selected right room among several direct rooms from previous resolution process run
if (callee.customIdentifier.length)
{
// If callee will have the same name as one of the contact in the system contacts app
// Siri will pass us this contact in the intent.contacts array and we must provide the same count of
// resolution results as elements count in the intent.contact.
// So we just pass the same result at all iterations
NSMutableArray *resolutionResults = [NSMutableArray array];
for (NSInteger i = 0; i < contacts.count; ++i)
[resolutionResults addObject:[INPersonResolutionResult successWithResolvedPerson:callee]];
completion(resolutionResults);
return;
}
else
{
// This resolution process run after selecting appropriate user among suggested user list
selectedUserId = callee.personHandle.value;
}
MXKAccount *account = [MXKAccountManager sharedManager].activeAccounts.firstObject;
if (account)
{
MXFileStore *fileStore = [[MXFileStore alloc] initWithCredentials:account.mxCredentials];
[fileStore asyncRoomsSummaries:^(NSArray<MXRoomSummary *> * _Nonnull roomsSummaries) {
// Contains userIds of all users with whom the current user has direct chats
// Use set to avoid duplicates
NSMutableSet<NSString *> *directUserIds = [NSMutableSet set];
// Contains room summaries for all direct rooms connected with particular userId
NSMutableDictionary<NSString *, NSMutableArray<MXRoomSummary *> *> *roomSummaries = [NSMutableDictionary dictionary];
for (MXRoomSummary *summary in roomsSummaries)
{
// TODO: We also need to check if joined room members count equals 2
// It is pointlessly to save rooms with 1 joined member or room with more than 2 joined members
if (summary.isDirect)
{
NSString *diretUserId = summary.directUserId;
// Collect room summaries only for specified user
if (selectedUserId && ![diretUserId isEqualToString:selectedUserId])
continue;
// Save userId
[directUserIds addObject:diretUserId];
// Save associated with diretUserId room summary
NSMutableArray<MXRoomSummary *> *userRoomSummaries = roomSummaries[diretUserId];
if (userRoomSummaries)
[userRoomSummaries addObject:summary];
else
roomSummaries[diretUserId] = [NSMutableArray arrayWithObject:summary];
}
}
[fileStore asyncUsersWithUserIds:directUserIds.allObjects success:^(NSArray<MXUser *> * _Nonnull users) {
// Find users whose display name contains string presented us by Siri
NSMutableArray<MXUser *> *matchingUsers = [NSMutableArray array];
for (MXUser *user in users)
{
if (!user.displayname)
continue;
if (!NSEqualRanges([callee.displayName rangeOfString:user.displayname options:NSCaseInsensitiveSearch], (NSRange){NSNotFound,0}))
{
[matchingUsers addObject:user];
}
}
NSMutableArray<INPerson *> *persons = [NSMutableArray array];
if (matchingUsers.count == 1)
{
MXUser *user = matchingUsers.firstObject;
// Provide to the user a list of direct rooms to choose from
NSArray<MXRoomSummary *> *summaries = roomSummaries[user.userId];
for (MXRoomSummary *summary in summaries)
{
INPersonHandle *personHandle = [[INPersonHandle alloc] initWithValue:user.userId type:INPersonHandleTypeUnknown];
// For rooms we try to use room display name
NSString *displayName = summary.displayname ? summary.displayname : user.displayname;
INPerson *person = [[INPerson alloc] initWithPersonHandle:personHandle
nameComponents:nil
displayName:displayName
image:nil
contactIdentifier:nil
customIdentifier:summary.roomId];
[persons addObject:person];
}
}
else if (matchingUsers.count > 1)
{
// Provide to the user a list of users to choose from
// This is the case when there are several users with the same name
for (MXUser *user in matchingUsers)
{
INPersonHandle *personHandle = [[INPersonHandle alloc] initWithValue:user.userId type:INPersonHandleTypeUnknown];
INPerson *person = [[INPerson alloc] initWithPersonHandle:personHandle
nameComponents:nil
displayName:user.displayname
image:nil
contactIdentifier:nil
customIdentifier:nil];
[persons addObject:person];
}
}
if (persons.count == 0)
{
completion(@[[INPersonResolutionResult unsupported]]);
}
else if (persons.count == 1)
{
completion(@[[INPersonResolutionResult successWithResolvedPerson:persons.firstObject]]);
}
else
{
completion(@[[INPersonResolutionResult disambiguationWithPeopleToDisambiguate:persons]]);
}
} failure:nil];
} failure:nil];
}
}
}
@end

View file

@ -0,0 +1,10 @@
<?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>com.apple.security.application-groups</key>
<array>
<string>group.im.vector</string>
</array>
</dict>
</plist>