I am developing a Line-of-Business app for a client. The client specified the devices that were supposed to be used (some Dell tablet with Windows 8.1). Now, that the development is almost done and we were ready to release the first phase of the application, the client informed us that they have changed their mind and all those Dell tablets will run windows 10. I upgraded one tablet that I used for development and testing to Windows 10 as well. The tablet uses a RESTful Web API to access data stored in a repository. Obviously, the URL of the Web API must be configured in the settings of the app before the app can retrieve any data from the repository.
So I create the App Package to sideload the app on the tablet. The installation works properly, the app starts well for the first time. I go into the settings, set the URL and close the app.
When I try to restart, the app gets stuck showing the Splash Screen. If I try to access the Settings, I am informed that the settings for my app are not available at that time. The only way to get out of this is to uninstall the app and reinstall it again.
This is the code I use to save and retrieve the settings:
public void SaveSetting<T>(string settingName, T value)
{
ApplicationData.Current.LocalSettings.Values[settingName] = value;
}
public T GetSetting<T>(string settingName)
{
var localSettings = ApplicationData.Current.LocalSettings.Values;
if (localSettings.ContainsKey(settingName))
{
var value = localSettings[settingName];
if (value is T)
{
return (T)value;
}
}
// else, in all other cases
return default(T);
}
An interesting thing I noticed is that sometimes, depending on what I try to save in the settings, the app starts. For example, I was playing with it and tried to save some garbage instead of the correct URL. So instead of "http://x.x.x.x:nnnnn" I saved "a". The app started correctly, I got past the splash screen but obviously, I couldn't get any data.
Any ideas as to what exactly is happening? Did the access method for local settings change in Windows 10?
I have been scratching my head over this for the past couple of days. Initially, I thought it is a matter of permissions to create the Local Settings file, so I dedicated a lot of energy trying to find a solution from that perspective. However, as I said, if I dump some garbage in the settings, it works, so it's not a matter of permissions. Could it be that and IP address like "x.x.x.x" needs to be saved in a different way than as a string?
Any advice would be highly appreciated.
TIA,
Eddie
After I added some logging to my application I was able to prove that the app had no issues reading the settings. It's what it tried to do with them that it did not work. The URL read from the settings was correct but when the app tried to make calls to the Web API, the calls threw an exception and the app stopped working. So this shouldn't have been a question in the first place.
Thanks, Eddie
Related
I'm studying React Native right now, and I'm trying to figure out how to enable the reception of Push Notifications even when the app is closed, just as Facebook does.
I'm a web developer, so I'm not used to mobile apps' "Manifest" logic. Where should I start from?
Thank you!
It seems that since you are a web developer, mobile app is not yet familiar with you. Actually, setting up push notification will require a few more official steps (differently on iOS and Android), and after everything is set, the push notification will happen between Apple server (or Google server) and smartphone's OS (which is iOS or Android), so the push notifications will come to the phone no matter what (without knowing/caring your app is opened or closed ^^)
In the programming code of our app, we can do our logics when the notifications come based on 2 cases: users is using the app or app is not running (not running means users are not using your app, and it is either staying awake in the background or users have exited it completely - e.g. pressing Home button twice on iPhone, and swiping the app away)
Actually, If you want your app to stay awake in the background, you can add some settings to the "manifest"-like files (of course differently on iOS & Android). However, my experiences taught me that keeping the app awake will encourage the users to complain and delete our app (my previous app's user once complained about his iPhone's battery was consumed greatly because of my app ^^)
If you really want to keep your app awake, you can set it in the settings, then in the push notifications' data, you can include extra parameters, and finally in the function of receiving push-notifications in your app, you can do anything with those parameters!
In short, you may just need to config push-notification properly for your app, and Apple/Google will do the rest, either your app is running in background or totally closed, it will receive the notifications. Hope you can find a good solution based on my explanation. If there's still something unclear, feel free to post here some more details on your needs, thanks!
This is the library I'm using with my previous react-native project: (they also have tutorial there ^^)
https://github.com/zo0r/react-native-push-notification
ADDED EXPLANATION: (based on author's needs):
The goal is: the user will register/login in the app, and will subscribe to some future events.
=> whenever users open the app, data will be sent to Apple/Google server to get a token, and you will use this token together with user's subscribe data to send all to your own push-server (you can use PHP or node.js server or whatever)
When an event gets updated a notif. should be sent to all the users who are going to that event. So a notif. aimed to certain users only.
=> like the above answer, data will be sent every time users open app (or change settings, you can do it in your logic of the app, because data will be kept your own push-server, which means on that server, you can even see user list, and can aim to certain users - it depends on what data will be sent to the users from the smartphone, but users may refuse inputting too much information like name, age or email, but it's up to your service's need ^^)
By clicking on it, the app will open and a certain page of the app (pre-existing) will be shown.
=> by default, when an notif. is clicked, the app will be opened for sure, and here once again, you can add extra parameters to the notifications (which is the landing page you need, then in the function of you app, just go there - but it may get extra logics for this. Besides, when to push notification, and which data should be pushed etc. will be controlled by your own server)
It seems like the most complicated part will be the "sending to certain users" one!
=> I explained this already, but you're right, actually it's complicated, because you need to create your own server with lots of API and logics based on your needs, and it need a few more steps (complicated one because you need to register many things with Apple & Google, then adding their Certificates into your own server etc.)
Hopefully you will achieve it, I suggest you play around and truly understand how push-notifications work first (for both sides - your own server and your application) - Good luck, though ^^
I'm updating an app from Windows Phone Silverlight 8.1 to WP Runtime 8.1 and got an issue with the "PhoneProductId" in the Package.appxmanifest:
1) Either I provide the Id from the old Silverlight version of the app. Then I can update it in the console via "AppDeployCmd.exe" /targetdevice:de /update MyApp_1.2.3.4_AnyCPU.appxbundle" with no user data being lost. But when I run MapRouteFinder.GetDrivingRouteAsync(...) I get an InvalidCredentials-error, since I haven't provided the proper Map Service Application Id, which in RT needs to replace the PhoneProductId (in Silverlight, it needed to be provided via c#, alongside the Authentication Token).
2) Or I provide the Map Service Application Id and can use MapRouteFinder.GetDrivingRouteAsync properly. But then I can neither /update the app (error message "Application is not installed" in the console) because of different PhoneProductIds in the two app versions. I also can't /install it without first uninstalling it ("Could not register package").
Anybody got a way out of this dilemma?
I've now uploaded soulution number 2 to the store, with GetDrivingRouteAsync working before the upload. The update did work, without any user data being lost, so no problem here.
However, when using the version from the store, GetDrivingRouteAsync is again not working (same problem as in solution number 1).
Seems to be exactly the same issue as this one:
https://stackoverflow.com/questions/32891052/invalid-credentials-with-getdrivingrouteasync-only-when-i-create-packages-for-st
I'm having an white screen of death when trying to debug my silverlight application. The problem is that I don't know what causes it and I don't get any type of information from either Visual Studio or the browser itself (IE9). Breakpoints won't be hit as App() in the App.xml.cs doesn't get fired either.
The application works fine on my own laptop, but I'm trying to make final adjustments to it on the server which will host the application once it's done. The problem occures on this server.
Would there be any way to get information about what's causing it or did someone experience simulair issues?
hit F12 in IE and go to network and start capturing. You should see your error there if something went wrong downloading and also if there was a problem with the Silverlight plugin (check Console or Script tag).
There could be a number of reasons for this including problems with database connectivity, WCF services, and many other factors. One thing that might help you get some information is a product called Fiddler. If you are able to download and install that on your development machine, you can have it running when you try and access your application on the server. It will give you messages for every step of your application initialization, including database authentication, service authentication, the xap file transfer, etc.
My problem was related to init params not loading up from the web project's .aspx page, try having a look at this if you are having "white death screen" issues.
User starts up a silverlight application in their browser by navigating to a given URL.
User then opens another browser and starts up the same silverlight application by navigating to the same URL.
Can the second instance of the application detect that there is already an instance running on the same computer?
Can it detect itself if both applications are running within the same browser instance?
I would expect the answer to be 'no' but thought that i would ask it anyway. Otherwise i believe that i will have to setup a webservice and have each instance register itself and send requests to other instances from the same IP. does that sound reasonable?
I think you may be looking for LocalMessageSender and LocalMessageReceiver. I believe these are new classes in Silverlight 3 allowing two Silverlight applications running on the same local computer to communicate.
More detail: Communication Between Local Silverlight-Based Applications (msdn)
This will work, I've done it myself. This code from the Microsoft site demonstrates how you set up a LocalMessage 'receiver". If it throws an error, it is because another instance of the Silverlight app is already running.
public Receiver()
{
InitializeComponent();
LocalMessageReceiver messageReceiver =
new LocalMessageReceiver("receiver",
ReceiverNameScope.Global, LocalMessageReceiver.AnyDomain);
messageReceiver.MessageReceived += messageReceiver_MessageReceived;
try
{
messageReceiver.Listen();
}
catch (ListenFailedException)
{
output.Text = "Cannot receive messages." + Environment.NewLine +
"There is already a receiver with the name 'receiver'.";
}
}
I think you're right you can't do it cross-application, but you can do it within a single browser instance using cookies or Isolated Storage.
I have a silverlight business aplication that gets data from silverlight enabled webservice.
When I run the application in dev environment, it works fine.
when i deploy the application and the Asp.net web development server is working, then to the application works fine.
But when I stop the development server, the application can't access a service.
My questions are:
When I deploy a silverlight business application, doesn't the service get deployed and get started.
The endpoint address in my ServiceReferences.Clientconfig file is endpoint address="http://localhost:9702/MyWebservice.scv. Do I need to change this?
The enpoint address in the web.config is blank.
Appreciate your help
Because the WCF client code is declared as a "partial" class, what I've been doing to this point is creating another c# partial class file to host a GetClient() method on it. You'll notice that the code is taking into account the port that the service is on... in a few of the environments that I've posted or will be posting to, as well as the development environment, the application is not always on port 80.
Namespace Project.Service
{
public partial class ServiceClient
{
public static ServiceClient GetClient()
{
return new ServiceClient("CustomBinding_Service",
new System.ServiceModel.EndpointAddress(new Uri(string.Format("{0}://{1}:{2}/Services/Service.svc",
Application.Current.Host.Source.Scheme, Application.Current.Host.Source.Host, Application.Current.Host.Source.Port), UriKind.Absolute)));
}
}
}
Hope this helps someone!
Yes you are going to want to change your endpoint address. I recommend doing it in the silverlight code when creating the connection to the WCF service. The service itself lives on the web server, whereas the silverlight application lives on the clients computer. If the web server stops, the web service stops but the silverlight app can keep running.
edit:
To do this in code, as long as the path is always in the same domain as the app you can use do like so:
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None) //Use whatever security you need here
{
MaxReceivedMessageSize = int.MaxValue,
MaxBufferSize = int.MaxValue
};
Client client = new Client(binding, new EndpointAddress(new Uri(Application.Current.Host.Source, "../MyService.svc")));
Thanks so much for your help. I tried your approach to create the client code but that didn't work. And that's because the problem seems to be somewhere else.
So I installed fiddler to see the traffic.
Fiddler showed that the service was being accessed but the http response code was 302 showing that there was some redirection involved.
The address of my application is like this http:///Silverlightapp/(S(oirppxrwzhlf2a2vbia1ui45))/Default.aspx#/Home and it is hosted on IIS 6.
So I had to employ a workaround by installing the service on machine with IIS7 (and there was no session id involved like in the above url).I still kept the silverlight application hosted on IIS 6.
Anyway, in summary, to anyone who reads the thread, I did the following to troubleshoot and solve issue(temporarily)
Changed the end point address in the ServiceReferences.ClientConfig file. When you add the service using discover option in VS, the endpoint address is of the localhost and this must be changed.
Registered the service model using ServiceModelReg -i command. (this solved my problem that my applicaiton was only working from development server and not IIS)
-Put the CrossDomain and ClientAccessPolicy files in c:]inetpub\wwwroot folders.
-Used fiddler to look at http response codes. I had to do no configuration in fiddler.
Changed the binarymessageEncoding to textMessageEncoding iin the web.config file of the silverlight web project that also hosted the ecf service. I did this becasue adding a silverlight enabled wcf service creates a custom binding configuration in the web.config file by default uses binary encoding. I needed text encoding to see errors in fidder. But this didn't help much becasue I only saw the name of the operation in the Inspector>xml tab in fiddler. This was the same even after my issues was resolved by workaround.
Thanks for the help
Don't do it in code. Otherwise you won't be able to change it later without recompiling the application (when the address will need to change, perhaps years down the road when you've lost the source code :)
Change the address in ServiceReferences.ClientConfig to where the service is actually hosted... e.g. http://example.com/myVdir/MyWebservice.svc
If later on you need to change the address without recompiling:
- Open the .xap file (it's just a zip file with a different extension)
- Find the .ClientConfig file and change the address
- Put it back together as a .zip file and rename to .xap
Also, I can't remember anymore whether the .ClientConfig supports relative addresses (e.g. just "MyWebService.svc"), but if it does it may be a good solution as well.