MonoGame在iOS上缺少数据存储IsolatedStorageSettings类的解决办法
MonoGame的价值在于可以将原XNA游戏移植到iOS和Android平台。移植基础是Xamarin。在Xamarin.iOS缺少System.IO.IsolatedStorage.IsolatedStorageSettings类。这个类通常用来存储游戏数据状态,非常重要。下面提供IsolatedStorageSettings在iOS平台的实现代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
namespace System.IO.IsolatedStorage {
public sealed class IsolatedStorageSettings : IDictionary<string, object>, IDictionary,
ICollection<KeyValuePair<string, object>>, ICollection,
IEnumerable<KeyValuePair<string, object>>, IEnumerable {
static private IsolatedStorageSettings application_settings;
static private IsolatedStorageSettings site_settings;
private IsolatedStorageFile container;
private Dictionary<string, object> settings;
// SL2 use a "well known" name and it's readable (and delete-able) directly by isolated storage
private const string LocalSettings = "__LocalSettings";
internal IsolatedStorageSettings (IsolatedStorageFile isf)
{
container = isf;
if (!isf.FileExists (LocalSettings)) {
settings = new Dictionary<string, object> ();
return;
}
using (IsolatedStorageFileStream fs = isf.OpenFile (LocalSettings, FileMode.Open)) {
using (StreamReader sr = new StreamReader (fs)) {
DataContractSerializer reader = new DataContractSerializer (typeof (Dictionary<string, object>));
try {
settings = (Dictionary<string, object>) reader.ReadObject (fs);
} catch (Xml.XmlException) {
settings = new Dictionary<string, object> ();
}
}
}
}
~IsolatedStorageSettings ()
{
// settings are automatically saved if the application close normally
Save ();
}
// static properties
// per application, per-computer, per-user
public static IsolatedStorageSettings ApplicationSettings {
get {
if (application_settings == null) {
application_settings = new IsolatedStorageSettings (
IsolatedStorageFile.GetUserStoreForApplication ());
}
return application_settings;
}
}
// per domain, per-computer, per-user
public static IsolatedStorageSettings SiteSettings {
get {
if (site_settings == null) {
site_settings = new IsolatedStorageSettings (
IsolatedStorageFile.GetUserStoreForSite ());
}
return site_settings;
}
}
// properties
public int Count {
get { return settings.Count; }
}
public ICollection Keys {
get { return settings.Keys; }
}
public ICollection Values {
get { return settings.Values; }
}
public object this [string key] {
get {
return settings [key];
}
set {
settings [key] = value;
}
}
// methods
public void Add (string key, object value)
{
settings.Add (key, value);
}
// This method is emitted as virtual due to: https://bugzilla.novell.com/show_bug.cgi?id=446507
public void Clear ()
{
settings.Clear ();
}
public bool Contains (string key)
{
if (key == null)
throw new ArgumentNullException ("key");
return settings.ContainsKey (key);
}
public bool Remove (string key)
{
return settings.Remove (key);
}
public void Save ()
{
using (IsolatedStorageFileStream fs = container.CreateFile (LocalSettings)) {
DataContractSerializer ser = new DataContractSerializer (settings.GetType ());
ser.WriteObject (fs, settings);
}
}
public bool TryGetValue<T> (string key, out T value)
{
object v;
if (!settings.TryGetValue (key, out v)) {
value = default (T);
return false;
}
value = (T) v;
return true;
}
// explicit interface implementations
int ICollection<KeyValuePair<string, object>>.Count {
get { return settings.Count; }
}
bool ICollection<KeyValuePair<string, object>>.IsReadOnly {
get { return false; }
}
void ICollection<KeyValuePair<string, object>>.Add (KeyValuePair<string, object> item)
{
settings.Add (item.Key, item.Value);
}
void ICollection<KeyValuePair<string, object>>.Clear ()
{
settings.Clear ();
}
bool ICollection<KeyValuePair<string, object>>.Contains (KeyValuePair<string, object> item)
{
return settings.ContainsKey (item.Key);
}
void ICollection<KeyValuePair<string, object>>.CopyTo (KeyValuePair<string, object> [] array, int arrayIndex)
{
(settings as ICollection<KeyValuePair<string, object>>).CopyTo (array, arrayIndex);
}
bool ICollection<KeyValuePair<string, object>>.Remove (KeyValuePair<string, object> item)
{
return settings.Remove (item.Key);
}
ICollection<string> IDictionary<string, object>.Keys {
get { return settings.Keys; }
}
ICollection<object> IDictionary<string, object>.Values {
get { return settings.Values; }
}
bool IDictionary<string, object>.ContainsKey (string key)
{
return settings.ContainsKey (key);
}
bool IDictionary<string, object>.TryGetValue (string key, out object value)
{
return settings.TryGetValue (key, out value);
}
private string ExtractKey (object key)
{
if (key == null)
throw new ArgumentNullException ("key");
return (key as string);
}
void IDictionary.Add (object key, object value)
{
string s = ExtractKey (key);
if (s == null)
throw new ArgumentException ("key");
settings.Add (s, value);
}
void IDictionary.Clear ()
{
settings.Clear ();
}
bool IDictionary.Contains (object key)
{
string skey = ExtractKey (key);
if (skey == null)
return false;
return settings.ContainsKey (skey);
}
object IDictionary.this [object key] {
get {
string s = ExtractKey (key);
return (s == null) ? null : settings [s];
}
set {
string s = ExtractKey (key);
if (s == null)
throw new ArgumentException ("key");
settings [s] = value;
}
}
bool IDictionary.IsFixedSize {
get { return false; }
}
bool IDictionary.IsReadOnly {
get { return false; }
}
void IDictionary.Remove (object key)
{
string s = ExtractKey (key);
if (s != null)
settings.Remove (s);
}
void ICollection.CopyTo (Array array, int index)
{
(settings as ICollection).CopyTo (array, index);
}
bool ICollection.IsSynchronized {
get { return (settings as ICollection).IsSynchronized; }
}
object ICollection.SyncRoot {
get { return (settings as ICollection).SyncRoot; }
}
IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator ()
{
return settings.GetEnumerator ();
}
IEnumerator IEnumerable.GetEnumerator ()
{
return settings.GetEnumerator ();
}
IDictionaryEnumerator IDictionary.GetEnumerator ()
{
return settings.GetEnumerator ();
}
}
}
还需要引用System.Runtime.Serialization.dll