BlackBerry - Handling Custom Protocols - blackberry

I'm currently developing a BlackBerry application where I need to be able to open the application by clicking a link in an email or web page. The link would contain a string of text that would also need to be made available to the application at runtime.
The iPhone OS allows you to do this through custom protocols (ex. appname://some-other-text) quite easily. Is there similar functionality available in the BlackBerry SDK, or is this going to turn into a pipe dream?

I have done something like this by registering a custom BrowserContentProvider (using a unique, custom MIME type). You then use a URL that returns an web page with the custom MIME type, which will trigger your BrowserContentProvider implementation. Part of this implementation can consist of code that launches your application (or bring it to the foreground if already running).
There's another class called ContentHandler that you may want to look into as well. I haven't used it, but it appears to be able to spawn custom handlers based on certain filename-matching conditions.

Related

Can I make a background data fetch in an external library?

I am currently making a SDK that would require fetching data in the background. For an example, let's say that the SDK provides some weather data that needs to be relatively fresh to be useful. At some point, the data is outdated and needs to be refreshed. The problem is, that the app might be often used in places with poor internet connection, or with no internet access at all. This brings me to the idea that maybe I should fetch the data in background, when the internet is accessible.
The SDK is packaged into a XCFramework, and distributed using Swift Package Manager. When I try adding capabilities to my target, Xcodes gives me a screen that states "No matches, Capabilities are not supported for SDK".
Is it even possible to make a background data fetch without the access to app capabilities? Or does this responsibility fall to the client app for my SDK? Sorry if the answer is obvious, I've tried searching online for a direct response to my problem, and wasn't able to find a clear answer.
An SDK/framework can't request such capabilities, but it can contain the code necessary to do all the work. You need to expose a function that the client can call to run this code.
E.g.
Inside your framework
public func setupBackgroundDataFetching() {
// create background task
}
Then inside your README, you need to tell users that they have to enable this capability and call:
let weatherSDK = WeatherSDK()
weatherSDK.setupBackgroundDataFetching()
Inside their AppDelegate. Depending on your use case you may need to have the function take in some parameters, or make a singleton class and have this as a static/class func, etc. But the basic idea is the same, wrap up the code and ask the client to invoke it
Example:
Heres the repo of a crash reporting tool I use: https://github.com/getsentry/sentry-cocoa
You'll notice their README contains installation/usage guide which asks users to run a setup method in their AppDelegate, which takes in a configuration. Based on this configuration, they can setup anything they need once the app starts, such as a background task if needed

Alternative to custom protocols (URI schemes)

I have been extensively using a custom protocol on all our internal apps to open any type of document (CAD, CAM, PDF, etc.), to open File Explorer and select a specific file, and to run other applications.
Years ago I defined one myprotocol protocol that executes C:\Windows\System32\wscript.exe passing the name of my VBScript and whatever argument each request has. The first argument passed to the script describe the type of action (OpenDocument, ShowFileInFileExplorer, ExportBOM, etc.), the following arguments are passed to the action.
Everything worked well until last year, when wscript.exe stopped working (see here for details). I fixed that problem by copying it to wscript2.exe. Creating a copy is now a step in the standard configuration of all our computers and using wscript2.exe is now the official configuration of our custom protocol. (Our anti-virus customer support couldn't find anything that interacts with wscript.exe).
Today, after building a new computer, we found out that:
Firefox doesn't see wscript2.exe. If I click on a custom protocol link, then click on the browse button and open the folder, I only see a small subset of .exe files, which includes wscript.exe, but doesn't include wscript2.exe (I don't know how recent this problem is because I don't personally use FireFox).
Firefox sees wscript.exe, but it still doesn't work (same behavior as described in my previous post linked above)
Chrome works with wscript2.exe, but now it always asks for confirmation. According to this article this seems to be the new approach, and things could change again soon. Clicking on a confirmation box every time is a big no-no with my users. This would slow down many workflows that require quickly clicking hundreds of links on a page and, for example, look at a CAD application zooming to one geometry in a large drawing.
I already fixed one problem last year, I am dealing with another one now, and reading that article scares me and makes me think that more problems will arise soon.
So here is the question: is there an alternative to using custom protocols?
I am not working on a web app for public consumption. My custom protocol requires the VBScript file, the applications that the script uses and tons of network shared folders. They are only used in our internal network and the computers that use them are manually configured.
First of all, that's super risky even if it's on internal network only. Unless computers/users/browsers are locked out of internet, it is possible that someone guesses or finds out your protocol's name, sends link to someone in your company and causes a lot of trouble (possibly loss too).
Anyway...
Since you are controlling software on all of the computers, you could add a mini-server on every machine, listening to localhost only, that simply calls your script. Then define host like secret.myprotocol to point to that server, e.g., localhost:1234.
Just to lessen potential problems a bit, local server would use HTTPS only, with proper certificate, HSTS and HPKP set to a very long time (since you control software, you can refresh those when needed). The last two, just in case someone tries to setup the same domain and, for whatever reason, host override doesn't work and user ends up calling a hostile server.
So, links would have to change from myprotocol://whatever to https://secret.myprotocol/whatever.
It does introduce new attack surface ("mini-server"), but should be easy enough to implement, to minimize size of that surface :). "Mini-server" does not even have to be real www server, a simple script that can listen on socket and call wscript.exe would do (unless you need to pass more info to it).
Real server has more code that can have bugs in it, but also allows to add more things, for example a "pass through" page, that shows info "Opening document X in 3 seconds..." and a "cancel" button.
It could also require session login of some kind (just to be sure it's user who requests action, and not something else).
The title of this blog post says it all: Browser Architecture: Web-to-App Communication Overview.
It describes a list of Web-to-App Communication techniques and links to dedicated posts for some of them.
The first in the list is Application Protocols, which I have been using for years already, and it started to crumble in the last year or so (hence my question).
The fifth is Local Web Server, which is the one described by ahwayakchih.
UPDATE (this update follows the update on the blog post above mentioned)
Apparently I wasn't the only one thinking that this change in behavior was a regression, so a workaround has been issued: the old behavior (showing a checkbox that allows to remember the answer) can be restored by adding these keys to the registry:
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge]
"ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
"ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Chromium]
"ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001

MVVMCROSS Changing Language in iOS

I'm trying to implement a multilanguage support with mvvmcross in iOS. The "languages" are stored in a .resx file in the core (Portable Library Class).
So on the android side it works great......I have just to call the recreathe()-Method to rebuild the views.
Is there some similiar method I can call in iOS or in the MVVMCROSS-Library? I experimented a lot with several methods, but without any success.
I know how to make it manually:
Remove all Subviews
Create new instances for each removed subview
Do the bindings again
Add the views back to subviews
But honestly this just can't be the way it goes.
Has anyone a much more sleek suggestion?
if your views use binding (like I described here ) to display the localized version of the string values, the only thing you need to do is to call
RaisePropertyChanged(string.empty) or RaiseAllPropertiesChanged() on the view-models
When user changes the language, you could broadcast a message (using MvmCross messenger) which all the language aware view-models listen to, and on handling this message have the view-models can then call RaisePropertyChanged(string.empty) or RaiseAllPropertiesChanged() on the view-models

Is it possible for dynamic branding of the application

I have the application that will connect to different servers. Each server is like different client and I want my app to look different (as far as I can) depending on which server it is connected to. I thought that I can have a ZIP that on handshake will be returned from destination server and use details from it e.g. Images, settings etc.
Is it possible, if so what is the limit?
Edit
I'm thinking about the images for logo etc. and some color lists that I can then use with fallback to defaults.
You can make all resources (images, string files, NIBs, storyboard...) be downloaded from the client server.
Also, there are several project developed exactly for dynamic design using CSS-like mechanisms:
http://www.pixate.com
http://www.freestyle.org
https://github.com/robertwijas/UISS
https://github.com/tombenner/nui
There are some project to run Javascript as well. This may allow you customise some business logic.
http://www.bignerdranch.com/blog/javascriptcore-example/
https://github.com/kishikawakatsumi/JavaScriptBridge
So, yes. It's possible, but you'll find some limitation, like the root view controller, the app delegate, etc.. You'll have to be creative.
I've never done something similar, so I can help any further then this.
It's possible for almost all elements of the application except:
Application name
Application icons
Application splash
screens
Those 3 items are bundled into application and can't be changed in runtime.
Rest of the items have so called appearance selectors that can be used to implement dynamic branding.
It is definitely possible, as I have worked on an App like this myself. We did it basically the same way you described. On startup the user selects a server to connect to and we download a zip file that contains all the assets for that client. After the download, the UI is loaded with the custom images. You can customize any UI element the system lets you, which is pretty much everything, except for minor details like the system StatusBar. You're gonna need some helper classes that make your life easier and support methods like, for example, [UIButton themedButtonWithImage:].
Well, it's possible — in one extreme, you could have an app which consists entirely of a UIWebView (plus some mechanism for selecting which server the app is talking to) that gets almost all it's content from the server.
There are performance considerations if you do (internet connection reliability, cost, and speed), and Apple may object to certain things being done on any app distributed through the app store, but assuming you follow their guidelines or distribute outside the store, the only limits that I know of are the app icon, the startup screen, and the app identifier, which have to be included in the bundle.

Am I not understanding UIActivityViewController, or does the implementation currently suck?

I'm trying to move my app to use UIActivityViewController, rather than UIActionSheet, so that I get the fancy graphical sharing buttons rather than the textual buttons. (My app is targeted at iOS 6 only.)
After trying to work with it for a couple nights, it seems either I am totally misunderstanding how to use it, or the current implementation by Apple is terrible:
You can't specify a different message for different services. If I want something that will work across: Mail, Facebook, Messages AND Twitter, it's going to need to be 140 characters max, to work on Twitter. Is there a way to set custom content for each type of activity?
There appears to be no way to set a subject line or recipient for Mail messages. I've read the docs, they make it sound like this might be possible with an NSURL that uses the mailto: protocol, but in my tests, those URLs just get shoved into the message body. Is there actually a way to set the subject line and optionally, the recipients?
If I want to work around these shortcomings, and do my own custom activities by subclassing UIActivity, I have to use a custom image/icon. Therefore, I can't mimic the Mail activity with Apple's official icon, and e.g. implement my own custom activity backend that actually lets me set the subject line, recipients, custom body, etc. Am I wrong, is there a way to use Apple's service icons, but have a chance to customize the behavior? (The only callback I see is one that runs AFTER the activity has been completed, right?)
I hope I'm wrong!
Is there a way to set custom content for each type of activity?
Yes, I guess you should subclass UIActivityItemProvider and override method –activityViewController:itemForActivityType: with your logic (e.g. trim string to 140 chars for Twitter).
Then pass an instance of this class to -[UIActivityViewController initWithActivityItems:applicationActivities:].
Is there actually a way to set the subject line and optionally, the recipients?
You are right, the mailto scheme should be able to set these fields. If it is not working, I consider this as bug. (Didn't try this myself, but I will give it a check.)
Is there a way to use Apple's service icons, but have a chance to customize the behavior?
I think you can't do this. (Unless you want to hack those system activities.)
You are better off using a custom component that behaves like UIAcitvityController as it is quite limited, as you noted.
This is one example: https://github.com/hjnilsson/REActivityViewController , I just forked it from https://github.com/romaonthego/REActivityViewController to allow you to set the email subject field.

Resources