I am developing a Today's Extension of an app. I am having some problems regarding App Groups that are used as shared containers between extension and containing app.
Where is the App Group data stored?
How to see what data is stored in the App Group?
Shared Containers is simply a UserDefault dictionary that is shared between Extensions in an App. To store data in the container Init your container using the suiteName UserDefault:
let SharedDefaults = UserDefaults.init(suiteName: "group.com.YOURGROUP")!
TheN to set a value, in this case a String:
SharedDefaults.set("something", forKey: "aKey")
And to retrieve the information (from either the Extension or App) use:
let myString = SharedDefaults.string(forKey: "aKey")
This explains how to to print the contents of the UserDefaults: Easy way to see saved NSUserDefaults?
Related
I am writing an app which uses CoreData using NSPersistentContainer to save data.
While I am developing the app, I would like to:
examine the data directly
back up the data
see what happens when I change the bundle id
I assume the data is physically stored somewhere, but I’m not sure where to look.
By default NSPersistentContainer stores the database inside app container under directory Libray/Application Support
To locate the full path, in simulator, you can print the applicationSupportDirectory using urls(for:in:) function of the default FileManager:
print(FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first?.path ?? "nil")
If you are running your app on an actual device you can download the application container following this answer.
For sandboxed apps the location goes like this:
~/Library/Containers/…/Data/Library/Application Support/…
I created first simple iOS app using Xamarin & Sqlite database as backend. Everything works fine, now my next step is to figure out how to make data stored in sqlite available on more than 1 user's devices. Since sqlite database is stored locally on user's device, do i need to code and syncing or just rely on user to enable icloud and data just sync itself? My understanding on this is still entirely muddy. If I need to write code to do syncing, could you give some example code? You help is greatly appreciated. -Thanks
Below is code i used to create database:
var fileName = "TrackItem.db3";
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var libraryPath = Path.Combine(documentsPath, "..", "Library");
sqlite is only used for loclly, try using firebase
This may be a dead horse, but I need to be able to supply a local folder full of images OUTSIDE my Xamarin application - not as resources, not requiring compilation to add more images - and display those images in the application, in Image objects. My main target platform is Windows 10. Others nice to have, not required.
Xamarin Forms Image normally takes either a File name (no path) or a URI. I can't get either method to locate and display images from the local file system. I must be doing something basic wrong.
Non-working sample:
Image i = new Image();
i.Source = ImageSource.FromFile(some.png); // Needs to be from folder on local disk
grid.Children.Add(i, c, r);
Most articles I find explain how to bundle images WITH the application as part of the source; again I need to display them in the application from a folder WITHOUT bundling them with the application. Users should be able to add more images to the folder and they would work in the app without recompiling/reinstalling - like an image gallery.
EDIT: I am able to successfully read a text file using PCLStorage https://github.com/dsplaisted/pclstorage. Is there a way to wire that to Xamarin forms image?
You would need to write a platform specific class to read the images and return a stream that could be consumed by StreamImageSource. Then you can use DependencyService to expose this behavior to your Forms PCL.
Alternatively, you could use PCLStorage
var f = await FileSystem.Current.LocalStorage.GetFileAsync (path);
Stream s = await f.OpenAsync (FileAccess.Read);
image.Source = ImageSource.FromStream(() => s);
Basically, you can't. If you don't bundle the images with your application, you somehow have to transfer the images to the application. Most common case is that you serve these images on a web server somewhere, where the application downloads the images from that web server.
Is it possible for extensions access the containing-app's container directory?
For iOS5-based app, i don't want to move all my old data into shared-contatiner, i wish that main-app can remain the same, and the extension just read & write the old data directly, that will be perfect!~
Your widget may never access the containing app's data directly, only if the containing app puts that data into a shared container using app groups. The documentation (including the WWDC videos) is pretty clear about this.
There's a high chance that your iOS-5-based app needs major changes anyway to work nicely on iOS 8.
I have a Windows Phone app that relies on an XML data file that comes packaged with the app. When the app is ran the first time on a phone, I load the file into isolated storage. Once the file is loaded into isolated storage, the app uses the isolated storage version of data. In the next version of my app (the Marketplace update), the XML file will have more elements, how do I update the data file once per app update (new version on the Marketplace)?
I thought I could change the file name in the isolated storage, but that would leave trash behind. I could also check for exceptions when I load the XML file, but are there any other, more elegant ways? I do not want to check for the old file in the isolated storage every time my app runs.
The ideal scenario would be to put a piece of code that would be executed once when the new version of the app is loaded onto the phone, is there a way to do that?
To my knowledge there isn't an "out of the box" event that will run a single time at the first run of an app after it was installed/updated.
You'd have to flag the run your self, like you are already stating (save the current version, compare version at each run of the app to see if app was updated!)
I think I now understand what you want.
Add the XML file as a resource.
Use GetResourceStream to get the content of the XML.
Note that the name for the resource would be something like /DllName;component/Folder/ResourceName
Here is what I did:
In the constructor method of my DataLayer class, I added the following code:
private bool AppIsOld
{
get
{
string storedVersion = GetStoredAppVersion(); //stored previously "seen" version
string currentVersion = GetCurrentlyRunningAppVersion();
return !(storedVersion == currentVersion);
}
}
private string GetCurrentlyRunningAppVersion()
{
var asm = Assembly.GetExecutingAssembly();
var parts = asm.FullName.Split(',');
return parts[1].Split('=')[1].ToString();
}
And then I run the following check:
if (AppIsOld)
RefreshResources(); //do whatever to refresh resources
The code for GetCurrentlyRunningAppVersion() function is taken from here.
This solution is not what I had in mind because it runs every time the class constructor is called while I wanted something that would run once upon version update.