Passing data from Siri to other apps in Objective-C? - objective-c

We are implementing Sirikit for one of our application. We are able to send message using SiriKit intent INSendMessageIntent. Upon “Send” Siri command handling, we need to pass some of the information to other application.
We have figured out [self.extensionContext openURL] to open application from intentViewController. As we observed that, there is configureWithInteraction of IntentViewController which gets called every time Siri processes each user command. Since we need to open application only on “Send” Siri command, we are not able to identify current processing state i.e. “Send”.
OR is there anyway to call openURL from intentHandler?
We are completing IntentResponse as mentioned below.
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:#“com.xxxxxx.xxx.myapp”];
INSendMessageIntentResponse *response = [[INSendMessageIntentResponse alloc] initWithCode:INSendMessageIntentResponseCodeSuccess userActivity:userActivity];
NSLog(#"response is %#",response);
completion(response);
We are expecting following function from containing app’s delegate to be called when action gets completed (i.e.INSendMessageIntentResponse is passed to completion handler)
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler

Several years passed ... but anyway, maybe it will help someone.
You can pass parameters with user activity you created.
[userActivity addUserInfoEntries: ]

Related

Access contents of Watchkit extension's host's mainBundle

I'm writing a WatchKit extension and I'd like to read a file out of the host application's [NSBundle mainBundle]. I've tried [NSBundle bundleWithIdentifier:] but that just returns nil.
I have several potential workarounds, but nothing that would be as simple as "just read what you need from the host's mainBundle".
Is there a way of doing this?
The host app and your WatchKit extension can share files in only one of two ways, as far as I know:
Shared app group
Including a file in both targets
They run in separate processes and aren't accessible to each other outside of approved methods.
I ran into a similar problem like yours. The main host app has a particular pList that I needed to read, and I couldn't read from watch extension because they are isolated.
So in the watch I invoked the openParentApplication method
and in the main application my handler was something along the lines of
-(void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
{
NSString *request = [userInfo objectForKey:#"request"];
if ([request isEqualToString:ReadFile])
{
//read the file. and then i like to put it into a NSDictionary
NSDictionary *responseDictionary = //whatever
reply(responseDictionary);
}
else{ reply(nil); }
}
And then the contents were returned to me in the callback closure on the watch of the openParentApplication. Seems to work. Though your situation could be different in which case this method might not be viable.
From the Apple WatchKit programming guide:
To share preferences data between apps, create an NSUserDefaults object using the identifier of the shared group. The initWithSuiteName: method of NSUserDefaults creates an object that allows access to the shared user defaults data. Both processes can access this data and write changes to it.
Your main app can write a NSDictionary/NSArray to the shared prefs, and then the watch kit can pull it out, without starting the main app - however, the main app will have to be run at least once to update the shared prefs.

Application got stuck on downloading

I am working on an iPhone app, which downloads Focus list of items on each app start (6 items with images).
I'm using 1 NSMutableURLRequest for downloading 6 items textual information in a loop, then in the same method block with different for loop I'm using :
NSURL * imageURL = [NSURL URLWithString: strUrl];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
for getting images of all 6 items. Code is working fine, if I wait till this process completes and update my list on home view.
If I try to navigate then my app stuck till its in process of download. I called complete method on Background thread, but still it got stuck for the process completion.
How can I code for this, so user can experience all navigation without stuck and when he'll come back can get the 6 items in view ?
Thanks in advance.
You could use NSURLConnections asynchronous request to do the downloads in the background
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler`
That way the download won't block your code. You can also do the completion work on background thread (as long as its not working with the UI, that code ALWAYS needs to be on the main thread).

Testing internet connection on iPad app using ios5

I have been searching through the forum regarding how to check whether there is internet or not in my ipad app. I just created a simple webview project with other view controllers and I need to display a UIAlert message when the internet is not available. In my case it is displaying the message when I run the app. When I run the app with internet and then deactivate the internet, it does not show the UIAlert message, that is if I switch between the views, it does not any more show the no internet connection.
I have followed this way of implementation in my project: (sorry my mistake this is the link I followed) http://mozymac.com/forums/f54/how-check-if-there-internet-connection-iphone-os-devices-595/ [This is the new edited question]
Apart from that I went through some of the previous questions in Stackoverflow forum like for ex: How to check for an active Internet connection on iOS or OSX?
But everybody has their own version. If any one has a much more updated method for ios5, xcode 4.2.1 of how to accomplish this then would be helpful for me.
Thanks
Is there a reason why you want to check for internet connection before actually trying to load a request in the UIWebView?
Best practice is to just start loading, and use your UIWebViewDelegate/NURLConnectionDelegate to inspect the NSError to see what is wrong. In case of network failure you will receive an error with a domain equal to NSURLErrorDomain. The error code will indicate what the problem is, see the NSError codes enum.
And only after the first error start your reachability to see when the internet connection becomes available again. Or easier, just let the user retry.
Using the Reachability code will actually cause some overhead. It takes time to check if the internet is available, which you could just have used to set up the actual connection as well.
Example
Since you are using a UIWebView you should implement the following delegate method to be notified of errors.
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
if (![[error domain] isEqualToString:NSURLErrorDomain]) {
// not a nsurl error, take other appropriate action
return;
}
NSInteger code = [error code];
// show appropriate error to user, based on code
}
In this delegate method you should do whatever is needed to achieve what you want. You could retry the request yourself, show a message to the user or start listening for reachability changes using the code from the Reachability example provided by Apple.
Apple has one, it's called Reachability. Here's the link to it.
http://developer.apple.com/library/ios/ipad/#samplecode/Reachability/Introduction/Intro.html
Best way to check internet connection is Reachibility application
link
Or else
+ (BOOL)isNetworkAvailable
{
CFNetDiagnosticRef diag;
diag = CFNetDiagnosticCreateWithURL (NULL, (CFURLRef)[NSURL URLWithString:#"www.apple.com"]);
CFNetDiagnosticStatus status;
status = CFNetDiagnosticCopyNetworkStatusPassively (diag, NULL);
CFRelease (diag);
if ( status == kCFNetDiagnosticConnectionUp )
{
//NSLog (#"Connection is up");
return YES;
} else {
NSLog (#"Connection is down");
return NO;
}
}

Download mutiple files in background thread

I am making an iPad app where you can download files (like PDF, doc, etc) and view them offline.
I already have the view part and you can download a file to the document directory.
As it is now you need to wait for the download to be finished to move on.
This can be solved by putting it in a thread, but what happens when the user downloads multiple files or even download the same file multiple times?
My idea is to make a download queue, with a view for the progress.
Workflow:
The user opens a document and press download, the user gets a message that the download is started and can be viewed in the offline documents view.
The user downloads 3 more documents.
When the user goes to the offline document view the user sees a table view with 4 filled cells. 2 documents are done loading and 2 other are still downloading because there is a download/status bar shown in the table view cell.
The downloaded documents can be viewed or deleted.
The downloads in progress can not be watched (yet) but can be cancelled.
I want to make a threaded download class where you can add urls to be downloaded. the class has methods to cancel and delete document-downloads, but also has methods to return the progress.
If possible the class can handle simultaneous downloads.
The problem is, I don't know where to start?
NSURLConnection is already asynchronous. All you need to do is to create NSURLConnection instances, associate them with your data structures, and have at it.
Here's an example where I assume you have one UIView per item. If you use a table view you can't count on view instances, but instead associate a download with an NSIndexPath, or something else.
#implementation MyDownloadView
- (void)startDownload {
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[req setHTTPMethod:#"GET"];
// Set headers etc. if you need
[[[NSURLConnection alloc] initWithRequest:req delegate:self] autorelease];
[req release];
self.responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Alternatively, store to a file so you don't run out of memory
[self.responseData appendData:data];
}
#end
Then implement the other NSURLConnection delegate methods to do what you need.
I've written an open source example that has pretty much all features you want, canceling a download is currently only available in code, but it's pretty easy to add a button for that.
I'm using asi-http-request for managing the downloads, and they are displayed in a grid view (AQGridView) instead of a UITableView, but i think you get the idea.
Download progress is managed via KVO.
See PSPDFDownload.m for a start. Download the full demo here
Full disclosure: This demo uses PSPDFKit for faster pdf display. But the Kiosk example is exactly what you need, and you don't need to use PSPDFKit for pdf display. There's even an example code path that uses Apple's QuickLook.

UIWebView capture post

I am looking for a starting point on a project that needs to display a UIWebView on an iPad. THe catch is that the HTML will be generated by the pad and displayed in the UIWebView, and will contain many input controls.
What is needed is a way to grab the contents of these controls after the user has completed entry similar to how I would do it on a server. I need to grab this entered data on the iPad without an actual submit.
Does anyone know the starting point for this type of interaction?
You can do this by implementing the UIWebViewDelegate delegate's shouldStartLoadWithRequest method:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSData* data = request.HTTPBody;
NSString* s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if([s length] == 0)
return YES;
else
return NO;
}
It works fine with a post.
Within the previously posted article it also mentioned the UIWebViewDelegate method,
webView:shouldStartLoadWithRequest:navigationType:
This gets invoked on the delegate before a link is followed. I haven't tried it, but this method might be invoked when submitting the form. Use a GET method. Easier than having to loop out of the app and back.
It can be done in simple way..
we know HTTP request contains -
Method (GET,POST..etc)
HTTP header
HTTP body
we can check header field value for Conent-type if it is x-www-form-urlencoded
then form field values are sending thru them as key=value pairs
then we can catch therse paires in
webView:shouldStartLoadWithRequest:navigationType: - in request parameter as
[request HTTPBody], similarly we can get method [HTTPMethod]..etc
if it is simply GET method then all pairs will be in request itself.
:) hope it helps
Here's a way to do it:
Register a custom URL scheme for your App (see here f.e. http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html)
When the user touches your save/submit/whatever button you read out the values of all needed form-fields, construct a url that matches your URL scheme and redirect to this URL with JavaScript (window.location) and work with the data in Objective-C and do what you have to do.
Example URL could be: myapp://value_of_field1/value_of_field2/...
See the linked tutorial on how to register a custom scheme and how to retrieve the data in Obj-C.