遇到的问题
旧版(mui开发) ID:H53FGS6A
新版(uniapp开发) ID:UNI7B7890D
注意:(我们的程序ID是有变化的,如无变化应该不用这么麻烦操作)
旧版的用户登录信息数据升级到新版时会没有,也就是说升级后新版拿不到旧版的登录信息 这样就需要用户重新登录一次,影响用户体验和使用,所以需要做一个兼容的处理
思路
旧版使用plus.storage.setItem()方法保存的数据,用户更新到新版时,拿到旧版数据然后缓存到新版本对应的位置中
要实现这个过渡,最最主要的是知道旧版的数据保存在哪里 新版的数据保存在哪里
经过一番查找最终实现了新旧版本的无缝切换
操作
Android端
在Android端旧版的plus.storage.setItem()保存的数据是在SP文件中,这个文件在应用包名目录下 比如我们的叫做H53FGS6A_storages.xml;
在Android端新版的plus.storage.setItem()保存的数据是在sqlite数据库中的
但是转移数据时我们不需要操作数据库 更新到最新版的uniapp时 程序会自动把缓存在SP文件中的数据转移到数据库中
所以在Android中做的操作就是把旧的sp数据保存到新的sp文件中,然后程序会自动把新的SP文件数据转移到sqlite数据库中,这样当新版APP打开时就读取到旧版缓存的数据了
Android中新的SP文件叫UNI7B7890_storages.xml
然后再新版APP打开时使用SP工具类转移数据即可 如下图
Android 工具类代码:
/**
* SP 更新工具类 之前就旧版(3.4.0之前)缓存保存在 HG88226A_storages.xml文件中
* 现在新版(3.5.0之后)改用uniapp
*/
public class SPUpdateUtil {
private static final String TAG = "SPUpdateUtil";
private static final String OLD_SP_FILE_NAME = "HG88226A_storages";
private static final String NEW_SP_FILE_NAME = "__UNI__78988302D_storages";
/**
* 更新SP信息
* @param context
* 1.拿到旧的sp信息
* 2.遍历旧的信息
* 3.缓存到新的sp文件中
*/
public static void updateSPInfo(Context context){
try {
SharedPreferences oldSP = context.getSharedPreferences(OLD_SP_FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences newSP = context.getSharedPreferences(NEW_SP_FILE_NAME,Context.MODE_PRIVATE);
SharedPreferences.Editor oldEditor = oldSP.edit();
SharedPreferences.Editor newEditor = newSP.edit();
HashMap<String,Object> oldMap = (HashMap<String, Object>) oldSP.getAll();
if (!oldMap.isEmpty()){
for (String key : oldMap.keySet()) {
Log.d(TAG,key+": "+oldMap.get(key));
Object object = oldMap.get(key);
if (object instanceof String) {
newEditor.putString(key, (String) object);
} else if (object instanceof Integer) {
newEditor.putInt(key, (Integer) object);
} else if (object instanceof Boolean) {
newEditor.putBoolean(key, (Boolean) object);
} else if (object instanceof Float) {
newEditor.putFloat(key, (Float) object);
} else if (object instanceof Long) {
newEditor.putLong(key, (Long) object);
} else {
newEditor.putString(key, object.toString());
}
}
//提交数据
newEditor.commit();
//删除旧数据
oldEditor.clear();
oldEditor.commit();
}
//检查数据
/* HashMap<String,Object> newMap = (HashMap<String, Object>) newSP.getAll();
for (String key : newMap.keySet()) {
Log.d("__UNI__78988302D",key+": "+newMap.get(key));
}*/
} catch (Exception e) {
e.printStackTrace();
}
}
}
IOS端
IOS端和Android端的思路一样,其中最主要的是找到旧版和新版数据保存的对应位置
在IOS端旧版的plus.storage.setItem()保存的数据是在一个叫做wxstorage.plist文件当中
在IOS端新版的plus.storage.setItem()保存的数据是也是保存在一个叫做wxstorage.plist的文件当中
只是他们所在的文件路径不一样
文件内容如下:
旧版路径:
注意:是在应用沙盒的Documents目录下
新版路径:
注意:是在应用沙盒的Library目录下
然后我们利用工具类把就数据放到新版plist文件中即可 如下图:
IOS 工具类代码
.m文件
/*
*版本更新工具类
* 之前的mui项目 跟新成uniapp项目 缓存数据位置发生了变化 需要这个工具类吧旧版缓存数据转移过来
* 这样旧版更新新版后 不会出现需要用户重新登录等情况
*/
#import "UpdateUtil.h"
@implementation UpdateUtil
/**
转移数据的方法
*/
+(void)updateStorageInfo{
@try {
NSString *oldPlistPath = @"Pandora/apps/H576788FC6A/data/wxstorage/wxstorage.plist";
NSString *newPlistDic = @"Pandora/apps/__UNI__78988302D/data/wxstorage/";
NSString *newPlistPath = @"Pandora/apps/__UNI__78988302D/data/wxstorage/wxstorage.plist";
NSArray *pathDocumentArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathDocument = [pathDocumentArray objectAtIndex:0];
// /var/mobile/Containers/Data/Application/5817C54A-8C39-4768-A598-EA1357BD785C/Documents
NSLog(@"数据保存路径:%@",pathDocument);
NSArray *pathLibraryArray = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *pathLibrary = [pathLibraryArray objectAtIndex:0];
// /var/mobile/Containers/Data/Application/8789507C-761F-4705-9057-4BBF3E695D3E/Library
NSLog(@"数据保存路径:%@",pathLibrary);
//旧版数据位置
NSString *storageOldFilePath = [pathDocument stringByAppendingPathComponent:oldPlistPath];
//读取旧版中的数据 因为已经知道数据保存的是dict 所有使用 NSMutableDictionary来读取
NSMutableDictionary *oldDict = [NSMutableDictionary dictionaryWithContentsOfFile:storageOldFilePath];
NSLog(@"旧版数据长度%lu",oldDict.count);
if(!oldDict || [oldDict count] == 0){
//不需要转移旧数据 这种情况是新版直接安装的情况
return;
}
//新版数据位置
NSString *storageNewFilePath = [pathLibrary stringByAppendingPathComponent:newPlistPath];
//判断文件是否存在
BOOL exist = [[NSFileManager defaultManager] fileExistsAtPath:storageNewFilePath];
if (!exist) {
//文件不存在
//先创建目录
NSString *storageNewDirectPath = [pathLibrary stringByAppendingPathComponent:newPlistDic];
BOOL dres = [[NSFileManager defaultManager] createDirectoryAtPath:storageNewDirectPath withIntermediateDirectories:YES attributes:nil error:nil];
//在创建文件
BOOL res = [[NSFileManager defaultManager] createFileAtPath:storageNewFilePath contents:nil attributes:nil];
NSLog(@"文件创建结果%@,....%@",dres?@"YES":@"NO",res?@"YES":@"NO");
}
//读取新版中的数据 如果是首次安装使用 新版中应该还没有数据
NSMutableDictionary *newDict = [NSMutableDictionary dictionaryWithContentsOfFile:storageNewFilePath];
//如果没有 创建一个新字典
if (!newDict) {
newDict = [NSMutableDictionary dictionary];
}
//转移数据 把旧数据放到新的字典中去
for (NSString *key in oldDict) {
NSString *value = [oldDict valueForKey:key];
[newDict setValue:value forKey:key];
}
NSLog(@"新版数据长度%lu",newDict.count);
if([newDict count] > 0){
//把新数据设置到文件中
BOOL result = [newDict writeToFile:storageNewFilePath atomically:YES];
if (result) {
NSLog(@"新版数据写入成功");
}
}
//把数据拿出来看下有变化没
// NSMutableDictionary *newAndOldDict = [NSMutableDictionary dictionaryWithContentsOfFile:storageNewFilePath];
// NSLog(@"新版数据确认长度%lu",newAndOldDict.count);
//清空旧文件中的数据
//[oldDict removeAllObjects];
NSDictionary *clearDic = [NSDictionary dictionary];
BOOL oldResult = [clearDic writeToFile:storageOldFilePath atomically:YES];
if (oldResult) {
NSLog(@"旧版清空成功");
}
//NSMutableDictionary *oldoldDict = [NSMutableDictionary dictionaryWithContentsOfFile:storageOldFilePath];
// NSLog(@"旧版数据确认长度%lu",oldoldDict.count);
} @catch (NSException *exception) {
NSLog(@"程序出错%@",exception);
}
}
@end
.h文件
@interface UpdateUtil : NSObject
+(void)updateStorageInfo;
@end