How to use SiriKit for sending data using Web Service? - ios

I am exploring SiriKit and I want to use it for sending data to web server. Basically, I want to send some data whenever user says "Hey Siri, send data using SomeApplication". Here 'SomeApplication' is the name of my app. I googled a bit, but I came to know that I can only use the intents given by SiriKit, I can't create my own. Please help me if there is some way to do this.

That’s true that you can’t create your own intents but there’s a trick that you can play. You can use the Messaging intent and instead of sending text message, you can make your service call from there.
In the IntentHandler.swift file, modify the code of resolveRecipients method to create a custom contact. This would result in showing a messaging UI but would skip the step of asking for recipient. Instead, Siri would directly ask for the message that you would receive in resolveContent method. Get it from there and call your web service. As simple as that.
Here's the code
func resolveRecipients(for intent: INSendMessageIntent, with completion: #escaping ([INPersonResolutionResult]) -> Void) {
let resolutionResults = [INPersonResolutionResult.success(with: INPerson.init(personHandle: INPersonHandle.init(value: "Raw", type: .unknown), nameComponents: PersonNameComponents.init(), displayName: "Raw", image: INImage.init(), contactIdentifier: "Raw", customIdentifier: "Raw"))]
completion(resolutionResults)
}
For detailed example, you can checkout this Git Repo for SiriKitDemo

Related

Get user attributes AWS Amplify iOS SDK

I'm building an iOS app with the SDK Amplify so I have my users registered on AWS.
I already have my sign in/sign up flow working but the problem is that with the newest version of the SDK I have absolutely no idea of how can I get attributes of a registered user like his family name, email address etc...
With this new SDK everything seems to work around the AWSMobileClientclass but I see nothing from this class that can help me to get what I want.
The official documentation is anemic and doesn't cover or even point to my use case.
If somebody can give me some hint or even some good ressources I'll be very thankful!
Hi YoanGJ and future guests,
Based on your comment you were looking for some sample code.
AWSMobileClient.sharedInstance().getUserAttributes { (attributes, error) in
if let attributes = attributes {
XCTAssertTrue(attributes.count == 3, "Expected 3 attributes for user.")
XCTAssertTrue(attributes["email_verified"] == "false", "Email should not be verified.")
}else if let error = error {
XCTFail("Received un-expected error: \(error.localizedDescription)")
}
getAttrExpectation.fulfill()
}
This excerpt shows how you could call getUserAttributes and it comes from the integration tests found here.
The method was missing from the initial release and has since been added. You can use the getUserAttributes with the following API in the latest SDK version 2.8.x:
public func getUserAttributes(completionHandler: #escaping (([String: String]?, Error?) -> Void))
You can find the source code here:
https://github.com/aws-amplify/aws-sdk-ios/blob/master/AWSAuthSDK/Sources/AWSMobileClient/AWSMobileClientExtensions.swift#L532
Thanks,
Rohan
For a note:
Make sure you did configure attribute read and write permission accordingly in your Cognito user pool App client to access your user attributes using getUserAttributes.
To configure attributes read and write permissions in user pool,
User pool -> General settings -> App clients -> Choose your app client
-> Show details -> Set attribute read and write permissions
Thanks!

Can you insert multiple attachments to iMessage with insertAttachment call?

I'm building an iOS app with an iMessage extension. I am successfully using the insertAttchment call from within the iMessage app to attach a media file to a text message for the user to send, however, I would like to attach two or three attachments at one time, before the user taps send.
Does anyone know if this is possible, and how it would be accomplished?
Here is the code I successfully use to attach one media file:
func didClickItem(_ controller: ItemViewController, itemUrl: URL) {
if let conversation = self.activeConversation {
conversation.insertAttachment(itemUrl, withAlternateFilename: "", completionHandler: nil)
}

Can we use SiriKit for anything else than the 6 types of services it is supposed to support? [duplicate]

I have watched SiriKit in wwdc and read document.
https://developer.apple.com/library/prerelease/content/documentation/Intents/Conceptual/SiriIntegrationGuide/
Add SiriKit support only if your app implements one of the following
types of services:
Audio or video calling
Messaging Payments
Searching photos
Workouts
Ride booking
I am still wondering whether I can do for other services (since my app will be for enterprise app).
My service will be very simple searching only like "Find SQ212 in myapp".
Can it be done? I afraid that sirkit can't support intent for other servies.
No, you can't. That's why it says "only if your app implements one of the following types of services".
You won't get the 'find foo in bar' syntax; each respective service has its own syntax - like "start a workout in MyApp" or "Book a ride to place with MyApp". See https://developer.apple.com/sirikit/ for examples.
I would expect a workaround using the SiriKit API to result in your app being rejected if submitted to the general app store, and I would expect it to be extremely fragile if it passed App Review or didn't go through it in the first place.
I found this article on making Sirikit Extensions that aren't default ones provided by Apple on swifting.io.
Using INVocabulary
From the Apple documentation:
The INVocabulary object lets you augment your app’s fixed vocabulary with terms that are both unique to your app and to the current user of your app. Registering custom terms provides Siri with the hints it needs to apply those terms appropriately to the corresponding intent objects. You may register only specific types of custom terms, such as the name of a contact, the name of a user’s workout, a custom tag applied to a photo, or a user-specific payment type.
public enum INVocabularyStringType : Int {
case contactName
case contactGroupName
case photoTag
case photoAlbumName
case workoutActivityName
case carProfileName
}
INMessage
Here they use INSearchForMessagesIntent to setup an index search for finding support.
struct SupportMe{
static let systems = [
INPerson(personHandle: INPersonHandle(value: "MyNotes",
type: INPersonHandleType.unknown),
nameComponents: nil,
displayName: "MyNotes",
image: nil,
contactIdentifier: "MyNotes",
customIdentifier: "MyNotes")]
static let articles = [
INMessage(identifier: "MyNotesPassword",
content: "Retrieving password in MyNotes app. To retrieve
password use 'forgot password' button that is located below
sign in button. Then type email address that your account has
been assigned to and press reset password",
dateSent: Date(),
sender: SupportMe.systems[0],
recipients: [SupportMe.systems[0]])]
}
extension IntentHandler: INSearchForMessagesIntentHandling{
func handle(searchForMessages intent: INSearchForMessagesIntent,
completion: (INSearchForMessagesIntentResponse) -> Void){
let userActivity = NSUserActivity(activityType: String(INSearchForMessagesIntent.self))
let response = INSearchForMessagesIntentResponse(code: .success,
userActivity: userActivity)
response.messages = [SupportMe.articles[0]]
completion(response)
}
}

SiriKit support for general services

I have watched SiriKit in wwdc and read document.
https://developer.apple.com/library/prerelease/content/documentation/Intents/Conceptual/SiriIntegrationGuide/
Add SiriKit support only if your app implements one of the following
types of services:
Audio or video calling
Messaging Payments
Searching photos
Workouts
Ride booking
I am still wondering whether I can do for other services (since my app will be for enterprise app).
My service will be very simple searching only like "Find SQ212 in myapp".
Can it be done? I afraid that sirkit can't support intent for other servies.
No, you can't. That's why it says "only if your app implements one of the following types of services".
You won't get the 'find foo in bar' syntax; each respective service has its own syntax - like "start a workout in MyApp" or "Book a ride to place with MyApp". See https://developer.apple.com/sirikit/ for examples.
I would expect a workaround using the SiriKit API to result in your app being rejected if submitted to the general app store, and I would expect it to be extremely fragile if it passed App Review or didn't go through it in the first place.
I found this article on making Sirikit Extensions that aren't default ones provided by Apple on swifting.io.
Using INVocabulary
From the Apple documentation:
The INVocabulary object lets you augment your app’s fixed vocabulary with terms that are both unique to your app and to the current user of your app. Registering custom terms provides Siri with the hints it needs to apply those terms appropriately to the corresponding intent objects. You may register only specific types of custom terms, such as the name of a contact, the name of a user’s workout, a custom tag applied to a photo, or a user-specific payment type.
public enum INVocabularyStringType : Int {
case contactName
case contactGroupName
case photoTag
case photoAlbumName
case workoutActivityName
case carProfileName
}
INMessage
Here they use INSearchForMessagesIntent to setup an index search for finding support.
struct SupportMe{
static let systems = [
INPerson(personHandle: INPersonHandle(value: "MyNotes",
type: INPersonHandleType.unknown),
nameComponents: nil,
displayName: "MyNotes",
image: nil,
contactIdentifier: "MyNotes",
customIdentifier: "MyNotes")]
static let articles = [
INMessage(identifier: "MyNotesPassword",
content: "Retrieving password in MyNotes app. To retrieve
password use 'forgot password' button that is located below
sign in button. Then type email address that your account has
been assigned to and press reset password",
dateSent: Date(),
sender: SupportMe.systems[0],
recipients: [SupportMe.systems[0]])]
}
extension IntentHandler: INSearchForMessagesIntentHandling{
func handle(searchForMessages intent: INSearchForMessagesIntent,
completion: (INSearchForMessagesIntentResponse) -> Void){
let userActivity = NSUserActivity(activityType: String(INSearchForMessagesIntent.self))
let response = INSearchForMessagesIntentResponse(code: .success,
userActivity: userActivity)
response.messages = [SupportMe.articles[0]]
completion(response)
}
}

how to send verification code by sms in swift 2

i build a register form for my app and i need to send the user a verifiation code by sms in order to complete the registration proccess.
i tried to use MFMessageComposeViewController but its open the dialog sms on the device so the user can see the code.
i also checked the web for 3party of sending sms but there is a problem with the country code. i know its posible becuse whatsapp do it to confirm the user.
what it the right way to do it?
this is the topic the i tried:
Sending SMS in iOS with Swift
The best way to achieve this is by creating some views for allowing the user to enter the phone number with the country code which can be used by a server to send a request for initiating the OTP verification. To achieve this you need to:
Create View Controllers.
Upload Phone Number and Country code to the server.
Validate the requests by verifying the OTP.
As mentioned by Dan, you can use Digits in Fabric for that purpose, and create custom views for a great UX.
On the other hand, you can also use a service called as SendOTP from MSG91 - you can use it for internal testing and development ideas as they provide you with 5,000 free OTP SMS. The service has a complete set of APIs which you can implement on the backend as well on the app front. Also, they provide a framework so that you don't need to create the views, but only presentViewController and call delegate methods for knowing what happened during the verification process - such as Cancelled or Verified or Failed.
Swift implementation of the same looks like this:
class OTPFrame: UIViewController, sendOTPAuthenticationViewControllerDelegate {
func loadOTPFramework() {
SendOTP.sharedManager().startWithApiId("yourAppID")
let frameworkPath: NSString = NSBundle.mainBundle().privateFrameworksPath!
let frameworkBundlePath: NSString = frameworkPath.stringByAppendingPathComponent("SendOTPFramework.framework")
let frameworkBundle : NSBundle
= NSBundle(path: frameworkBundlePath as String)!
let authenticationViewController: AuthenticationViewController = AuthenticationViewController(nibName: "AuthenticationViewController", bundle: frameworkBundle)
authenticationViewController.delegate = self self.presentViewController(authenticationViewController, animated: true, completion: nil)
}
func authenticationisSuccessfulForMobileNumber(mobNo: String!, withCountryCode countryCode: String!) {
print("Success")
}
func canceledAuthentication() {
print("Cancelled")
}
func authenticationisFailedForMobileNumber(mobNo: String!, withCountryCode countryCode: String!) {
print("Failed")
}
}
Disclaimer: I, in no way, endorse the services mentioned above - you are free to choose whatever you like.
Thank You!
I would give digits a try! It's part of the Twitter Fabric package and it's very simple to use. The user enters their phone number and Fabric takes care of validating the number.

Resources