How do you use the confirm phase of a SiriKit custom intent? - ios

Experimenting with the Xcode 10 beta, I've created a custom Siri Intent and it's working well. My Intents Extension successfully receives the intents and handles them in turn.
There is no validation of any sort needed on the parameters of the intent, once it is triggered it will request data from the network. I can do this in (void)handle....
I've noticed in my automatically generated Intent class, a list of possible response codes.
typedef NS_ENUM(NSInteger, SMSCheckTeamIntentResponseCode) {
SMSCheckTeamIntentResponseCodeUnspecified = 0,
SMSCheckTeamIntentResponseCodeReady,
SMSCheckTeamIntentResponseCodeContinueInApp,
SMSCheckTeamIntentResponseCodeInProgress,
SMSCheckTeamIntentResponseCodeSuccess,
SMSCheckTeamIntentResponseCodeFailure,
SMSCheckTeamIntentResponseCodeFailureRequiringAppLaunch,
SMSCheckTeamIntentResponseCodeSuccessPlayingNow = 100
}
The failure, success, and success (playing now) responses are defined in my Intents file. The others, such as ready, and in progress, are not, but I'd still like to tell Siri that my extension is "in progress" using the (void)confirm... method.
SMSCheckTeamIntentResponse * const response = [[SMSCheckTeamIntentResponse alloc] initWithCode:SMSCheckTeamIntentResponseCodeInProgress userActivity:nil];
completion(response);
At the moment, when I call this in the confirm method, Siri says something went wrong with my app, and the extension exits.
Does anyone know how to successfully use these response codes?

Related

ZKTeco SDK EnableCustomizeAttState

I would like to set the Check-In state and the Check-Out state in an SCR100 access control device, to analyze the logs more easily.
First I need to enable customized state values.
But when I use this function, I get -2001 error, which says: Return Fail to execute command.
Here is my code:
If app.AxCZKEM1.EnableCustomizeAttState(iMachineNumber, 0, 1) = True Then
operationSucced = app.AxCZKEM1.RefreshData(iMachineNumber) 'the data in the device should be refreshed
MsgBox("Check-In state written")
Else
app.AxCZKEM1.GetLastError(idwErrorCode)
MsgBox("Operation failed,ErrorCode=" +str(idwErrorCode))
End If
The SDK manual says:
This function is a customization function. To use this function, the
extension function must be enabled for the machine and the machine must
support the attendance status definition function.
But I didn't find any description about the mentioned extension function.
I had a software which used these states, so I know that the device supports changing the states. Did anyone successfully changed these states?

RevenueCat: How to get the purchaseToken in iOS

I need the purchaseToken for our server. This field exsits in the Android API,
/**
* Token that uniquely identifies a purchase.
*/
val purchaseToken: String,
And it is received upon purchase. But iOS API of the purchase function below doesn't send it back
func purchase(package: Package) async throws -> PurchaseResultData
When I debug, I see a similar data inside this:
purchaseResultData.customerInfo.allPurchases.first?.value["id"]
But allPurchases is private so I can't get it this way.
Any ideas?
I notice that PurchaseResultData is a typealias for
typealias PurchaseResultData = (transaction: StoreTransaction?,
customerInfo: CustomerInfo,
userCancelled: Bool)
Instead of checking the customerInfo for the purchaseToken, maybe the transaction object has this information as I can see that the type StoreTransaction has a property called productIdentifier
So maybe try
purchaseResultData.transaction.productIdentifier
Update with some other ideas
Maybe try looking at the transaction identifier
Maybe exploring the store kit objects, namely SK1Transaction and SK2Transaction which are properties of StoreTransaction
I have not used this specific API, but it seems like allPurchasedProductIdentifiers is a public property within CustomerInfo so I wonder if this is different from the allPurchases you tried

On Xcode 11, how can I configure an Intent to run in the background?

TL;DR
On iOS 13 and Xcode 11, how can I configure an Intent to run in the background and just return the result, so it can be used as the input for other actions in the Shortcuts app?
Details of what I'm trying to achieve
My app has a list of songs that I want to expose via Shortcuts (actually, metadata about the song, not the song itself). The idea is to give advanced users a way to integrate this database of music with other apps or actions they want. For example, one may find useful to get a list of upcoming music for the next month, and use it to create Calendar events for each song. Having access to this list on the Shortcuts app can enable them to do this.
I have created an Intent called "List All Unread Music Releases" and defined its response as a list of objects that contains information about each song. The problem is, when I go to the Shortcuts app, create a new shortcut using this Intent, and run it, it opens my app instead of running in the background.
Steps I've done to create and configure Intents
Here's a high level definition of what I did to configure Intents in the project. The next section will have the actual source code and screenshots.
Created a new SiriKit Intent Definition File.
Created a new Intent.
Defined it's Title, Description, Parameters, and disabled the "Intent is eligible for Siri Suggestions" checkbox.
Defined the response property as an Array (because it's going to be a list of songs), and configured the Output to be this array property.
Created a new Intents Extension, with the checkbox "Include UI Extension" disabled. The idea here is to process the user request in the background and return a list with the results - no UI required.
In the Intents Extension target, defined the IntentsSupported array inside Info.plist with the name of the intent created in step 2.
Made the IntentHandler class implement the protocol generated for the intent created in step 2.
Code samples and screenshots
My SiriKit Intent Definition File and the GetUnreadReleases Intent:
The GetUnreadReleases Intent response:
The Intents Extension IntentHandler class:
import Intents
class IntentHandler: INExtension, GetUnreadReleasesIntentHandling {
func handle(intent: GetUnreadReleasesIntent, completion: #escaping (GetUnreadReleasesIntentResponse) -> Void) {
let response = GetUnreadReleasesIntentResponse(code: .success, userActivity: nil)
let release1 = IntentRelease(identifier: "1", display: "Teste 1")
release1.name = "Name test 1"
release1.artist = "Artist test 1"
response.releases = [release1]
completion(response)
}
func resolveMediaType(for intent: GetUnreadReleasesIntent, with completion: #escaping (IntentMediaTypeResolutionResult) -> Void) {
if intent.mediaType == .unknown {
completion(.needsValue())
} else {
completion(.success(with: intent.mediaType))
}
}
override func handler(for intent: INIntent) -> Any {
// This is the default implementation. If you want different objects to handle different intents,
// you can override this and return the handler you want for that particular intent.
return self
}
}
The Intents Extension Info.plist file:
Conclusion
So, I would like this intent to run in the background, assemble the list of songs based on the user defined parameters, and return this list to be used as an input to other actions in the Shortcuts app.
It looks like previous versions of the Intents editor (Xcode < 11 / iOS < 13.0) had a checkbox "Supports background execution" that did just that, but I can't find it anymore on Xcode 11.
Thanks to edford from Apple Developer Forums, I was able to make it work. In the intents definition file, the "Intent is eligible for Siri Suggestions" checkbox must be checked for the background execution to work.

For plug in running on iOS

What I want to implement is as follow:
A-app (calling app) : request the return value of a-string sent as parameter : request(a-string) -> b-string.
B-app (plug-in installed separately by me or others, it plays the role of dictionary or database ) : search a-string from database and return the result (b-string).
With successful experiences of plug-in on android and with Apple's confident rhetoric of plug-in, I thought plug-in, of course, run on iOS. After a lot of hard work, however, I finally found out:
* Note : The creation and use of loadable bundles is not supported in iOS.*
Nonetheless, not giving up, I finally made it with custom URl and pasteboard:
A-app : write a-string and false state to pasteboard & call B-app via custom URL.
B-app : viewDidLoad runs following func and thereafter exit program ; func { read pasteboard and search from database & write the result(b-string) and true state to pasteboard }
A-app : while-loop detects whether state is false or true. if true, catch b-string from pasteboard.
Anyway it works but it's too long thus almost useless. Do you have any idea for better solutions? Why doesn't Apple allow plug-in for iOS? Any responses are welcome. Thank you.
I can't answer why Apple doesn't allow plug-ins, but I can offer some advice on what you're trying to achieve.
The common pattern for sending data back to your application is to implement a callback url, so the A-app would also implement a custom URI and add that to the uri sent to B-app.
B-app would then process the uri as you have already implemented, but then instead of exiting, it simply sends the data you requested in the uri passed to it.
See http://x-callback-url.com for more details and example implementations.

App launched with custom URL scheme. How do I return data to the calling app when done?

I am taking an Android programming course at my University only I have been allowed by the teacher to do IOS but I have to implement the same projects. This project is to have two apps. The first app is a color picker from a previous assignment. The second app is to call the colorpicker and allow the user to choose a color and when done return it too the second app to be displayed.
I have defined a custom URL scheme in my ColorPicker which works fine. In my second app I have a changeColor button that has the following IBAction method.
- (IBAction)colorChangePressed:(UIButton *)sender {
UIApplication *test = [ UIApplication sharedApplication ];
BOOL found =
[ test openURL:[ NSURL URLWithString:#"colorPicker://" ] ];
if (found) NSLog( #"Resource was found" );
else NSLog(#"unable to locate resource" );
}
This indeed launches the color picker app and it behaves as expected. My question is, after the color has been selected how do I return to the calling app with the selected color? I will add a finished button in my colorPicker to be clicked when the user is done selecting the color and I will capture the values I need but I can't figure out how to get this data back to the calling app. Is there some protocol/delegate pattern I need to implement?
The complete code is on git hub at. https://github.com/jnels124/CS390H
Thanks in advance for any insight as to how to solve my problem.
You need to have both apps with unique schemes. Encode the scheme of app1 and use it as a part of app1->app2 URL. When app2 is finished, you'll have a app2->app1 URL, use itto open app1 and send it required information (encoded).
It is similar as if you've put a String extra to app2 Intent with the name of app1 Intent, but instead of Intent you use URL and parse it as needed.
I defined a custom scheme in the other project as stated in the first answer but I was unsure how to generate the query string in the called URL and return it to the calling application to be parsed. I had this resolved in the following post.
Syntax for passing NSArray to other application with custom URL Scheme

Resources