Since I've updated my xamarin installation to xamarin 4, saving local properties is not working across sessions on iOS.
so if I have
Application.Current.Properties.Add("key", value);
Application.Current.SavePropertiesAsync();
It's not saving anything when the app is closed & restarted.
Any pointers?
This was fixed by not saving the complex objects as it is, but serializing them to string using JsonConvert & then storing the string instead.
This works all the time.
When you want to retrieve the object back again, just deserialize the string to the object type.
This seems to be a bug in Xamarin Forms 2, revert back to the latest v1 to get it working again.
See http://forums.xamarin.com/discussion/56461/persisting-data-locally-device-cache#latest
You should NOT use Xamarin Forms 2 yet, it is not production ready yet and should be considered alpha, don't believe Xamarins marketing.
Related
I am using Akavache standard approach on iOS (actually, it's .NET Standard project for Android/iOS), but the issue appears with iOS only.
I save some value during the app lifecycle:
await BlobCache.Secure.InsertObject("user", user);
And on the app new session this:
var user = await BlobCache.Secure.GetObject<UserModel>("user");
But the object is not available (with KeyNotFoundException exception).
Recently I also was trying to call BlobCache.Secure.Flush().Wait() right after the object saving, but there is still no effect.
The issue happens with iOS only. Android is fine.
The issue happens with both Secure and UserAccount objects.
The data is not available even after "gentle" BlobCache.Shutdown().Wait() on the application closing. So, have no idea even where to search the solution now.
Any thoughts why might cause this issue and how I can solve it?
There's another issue people have had is that the SqlLite cache is getting linked out. If you check the type on LocalMachine and it's of type MemoryCache that won't be resilient.
Just add the linker static class somewhere in your project (even if it's a PCL or Standard lib).
That worked for me.
Did you set the ApplicationName property on BlobCache? On iOS this seems more of a necessity than on Android it seems.
We are developing web app, that uses framework that uses indexedDB. All was going fine, but then we tested it on iPad and suddenly it didn't load the page at all. Thought it would be some minor issue, but after some tests we found out, that the app is crashing on:
TypeError: null is not an Object validating 'request'
It crashes on the line :
var request = indexedDB.open("FMVare",415);
This stores null in the request variable so then after that there is:
request.onerror(...)
Which will get us the error message, written above.
I spent one day looking for a fix, but only found that iOS implemetation of indexedDb is "buggy". But I cant even open a database, so there probably is problem somewhere else. My colleague also told me, that it was working fine like 1 month before, but the file with this implementation (according to git) didn't change... ever.
I tried using pollyfill to change it to the WebSQL, again it worked everywhere except iPad browsers (Safari, Chrome). This time it was throwing different error, which I only could google as far as some SQL syntax error, which obviously couldn't be the case, if it is working everywhere else.
I have tried some suggestions, which said to replace in that pollyfill indexedDB with _indexedDB etc. but again, it worked everywhere but iPad.
When I log the variable request, it returns null. If I log indexedDB or window.indexedDB, it returns IDBFactory object, so it's there, but the .open method is failing, without calling .onerror or .onsucess method.
Since I really found many people complaining about indexedDB bad implementation on iOS, it means they were able to use it. So what could be the problem in my iPad? I mean I can try update to iOS 9, but that's not exactly what are we trying to achieve.
I tried deleting cache, changing version number(greater and smaller), creating different database (different name), pollyfill... but still can't get it working, everytime i call indexedDB.open(databasename), it returns null and crashes.
Any ideas?
EDIT:
The error I'm getting with shim is
Error in sysdb transaction - when creating dbVersions.
Then I get the SQLError object with
"code: 5"
and
"message: could not prepare statement (1 not authorized)"
The error happens in createSysDB(success, failure) function of the shim.
UPDATE:
I tried an app on iPad called WebView Rendering so i could try if WKWebView would be capable of running my app. And it was! So the problem really was the UIWebView support of IndexedDB.
Seems very strange to me though, that you can't use IndexedDB on iOS Safari even after update on latest iOS version.
I am trying to master Code Data migration, its going to be important for supporting my app. The reason I need the migration is to preserve data. My app is used for psychological research and collection reaction time data. I have a game session and every game session has ordered set of moves. Every move has some properties. One of this properties is interval: Date. In the store version 1 it was named date and in the version 2 I renamed it to the interval and changed property's model version identifier to date.
App is not crashing on startup but when I am trying to view my old logs it crashes. I have UITextView and I display all my logs like this:
textView.text = "Interval = \(move.interval)"
If I create new game session and will view its log - the app works.
What is the best way to protect my users? Should I add additional logic inside my app for this? How can I display the old data after property was renamed?
Update:
There's no messages in the console, the app stops working with the line of code for updating the UITextView, it is highlighted in green with error message:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
I tried again from scratch and instead of renaming the variable, I created new one. This time app didn't crashed. I am sorry it is not real answer but it helped me to move on.
Lessons I learned:
Do not confuse Core Data Model Identifier in Xcode inspector and renaming ID. There's one model identifier (I left it empty) and renaming ID for every property.
If you have Core Data generated class with NSNumber, do not try to display them in console like this: label.text = "number = \(object.number)"
Do it like this:
label.text = "number = \(object.number.integerValue)"
This one gave me the same crash message, however it is not a problem if you're using NSDate.
I still have a problem when renaming variable. When I applied my commit again today I am getting the crash right on the start with the Can't find model for source store message. App in the simulator changed, so it looks like I can't reproduce this problem any more and instead have a new one.
Update
I had more practice and I think I was able to fix the crash described above.
I added next data model version - version 3 and introduced new variable. I did it like before, with switching current version from 2 to 3. Then app started to crash on launch with Can't find model for source store. I noticed that when I'm removing introduced variable the app is not crashing. I figure out that my Core Data couldn't migrate to version 3 because it already was on version 3:
I changed version from 2 to 3. I didn't change Core Data model.
I changed my code, fixed some bugs unrelated to Core Data.
Built and ran the project in the simulator. Note, now the app in the simulator has data version 3.
Changed Core Data model, built on simulator. It crashed after this step.
What I did to fix this:
Delete introduced variable. You can live generated classes as it is.
Change current version to previous. In my case, from 2 to 3.
Run the app and quit it.
Change Core Data current version and add new variable.
Run the app — it works.
Update 2
I met with this problem again and my answer didn't helped. Still, event after everything I described above.
I found this answer which this time finally fixed the issue. The secret was that new attributes should not be optional and they should have default values.
I'm having a web reference which is being used by both a Xamarin IOS application, Xamaring Android application, and a Windows Store application.
And this all worked very well, until I updated Xamarin.
Now, there is a field that But it works fine for the Android and Windows applications.
I have tried to update the web reference multiple times, with no luck. I have also tried to debug the web service locally, to see if it returns the same , which it does.
When I receive it in my Windows Store app., it looks like this:
And in my IOS app., it looks like this:
It is always the StructureId that is never set, for some reason. And it was not like that before I updated Xamarin.
Anyone who knows what I am doing wrong, or have stumbled onto the same kind of problem ?
That looks like the linker removed unused members. Defaults have not changed (it's not related to your update) but you should check that your application is being built with Link SDK (and not Link all).
If you want a smaller executable and set Link all to achieve this then you'll need to add [Preserve] attributes on the structure you're serializing (e.g. used in web services).
I was able to make it work. I am not sure if it cached anything, or what, but it helped to add some "noise" on the webservice call.
I just added DateTime.Now.Ticks to my webservice URL in Reference.cs, so it would always be a new URL call:
this.Url = "http://somewebsitename.com/ReportService/ReportService.asmx?v=" + DateTime.Now.Ticks;
I received the source for an application from a guy to make a few changes in the app. The data model version was, say, App3. I had to add about 3-4 more data model versions in the process. So the active model version when I sent him was App7
I built the project (it was running properly on my mac)
I sent him the zip and when he ran, he got the error "Can't find model for source store"
I had him create the latest data model again, based on the data model App3 and make it the same as App7 and set it as the current version.
He still has the error and I can't figure out why? Are the intermediate data model version causing issues? Is it required to delete the sqlite file in the application support->iphone simulator folder? I am all over the place with this. Please help!
You need to have both model files and have some sort of versioning in place. The new model that you made will no longer work with his data file unless you specify to Core Data that you want it to update the data.
Versioning isn't that easy, but if your changes are small enough, you might be able to get away with automatic versioning. Read the guide and see:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/Introduction.html
In my understanding, it will. But really that is not the thing to do if ultimately the versioning is going to happen on existing live apps too.
For the light-weight migration to work, you need to send him all the intermediate versions of the model as well since the migration takes place stage by stage through all versions.
And you have to make sure that you have made no modification (even accidentally) to the base version App3.