zoukankan      html  css  js  c++  java
  • iOS Salesforce SDK 小知识

     Salesforce SDK 能做许多任务,因此也比较繁杂,又分了原生,js等多个调用方法。

    关键点总结:

    1. SFSmartStore 中的 - (id) initWithName:(NSString*)name user:(SFUserAccount *)user isGlobal:(BOOL)isGlobal 函数,是关键入口点函数。
    2. SFSmartStore 中默认把FMDB 和 SQLChiper都引入了,因此FMDB可以调用自身的setKey函数对数据库进行加密操作(不引入SQLChiper库,FMDB就无法使用这个函数)。如果不使用SFSmartStore的类方法+ (void)setEncryptionKeyBlock:(SFSmartStoreEncryptionKeyBlock)newEncryptionKeyBlock;对_encryptionKeyBlock(返回一个加密用的key)进行指定,SFSmartStore就会使用com.salesforce.smartstore.encryption.keyLabel 作为默认的key。如果不需要使用加密功能,只需要把_encryptionKeyBlock的返回值设置为空字符串(oc里就是@"")。
    3. SFSmartStore 其实就是对FMDB的一层封装!
    4. SFSmartStore 里的 Soup就是 表 的意思,一般的使用方法如下:

      

    navigator.smartstore.registerSoup("myAgents",
        [{path:'name', type:'string'},
         {path:'address', type:'string'}]);
    navigator.smartstore.upsertSoupEntries("myAgents",
        [{name:'James Bond',
          address:'1 market st',
          agentNumber:"007"}]);
    先使用registerSoup注册一个soup,第一个参数指定了soup的名字,第二个参数指定了需要被index 的列(不是主键的意思,该列的内容可以重复)就是所谓的indexSpecs,不被index的列无法把该列作为关键字进行查询,排序等操作。
    之后使用upsertSoupEntries向soup插入或更新具体数据,第一个参数还是soup名,第二个参数是具体的数据条目数组,就是所谓的entries数组。理论上说,Entry中的属性和indexSpecs并没有什么包含关系,但是在真实环境里,indexSpecs应该是Entry属性集的一个子集。

    再看看查询方法,SFSmartStore 提供了好多的查询方法应对不同需求,比如下面这个:
     var querySpec;
    
        if (query === "") {
            querySpec = smartstore.buildAllQuerySpec("LastName", "ascending", 100);
        }
        else {
            var queryParts = query.split(/ /);
            var queryFirst = queryParts.length == 2 ? queryParts[0] : query;
            var queryLast = queryParts.length == 2 ? queryParts[1] : query;
            var queryOp = queryParts.length == 2 ? "AND" : "OR";
            var match = "{contacts:FirstName}:" + queryFirst + "* " + queryOp + " {contacts:LastName}:" + queryLast + "*";
            querySpec = smartstore.buildMatchQuerySpec(null, match, "ascending", 100, "LastName");
        }
        var that = this;
    
        lastStoreQuerySent++;
        var currentStoreQuery = lastStoreQuerySent;
    
        smartstore.querySoup(false,
            "contacts",
            querySpec,
            (cursor) => {
                console.log("Response for #" + currentStoreQuery);
                if (currentStoreQuery > lastStoreResponseReceived) {
                    lastStoreResponseReceived = currentStoreQuery;
                    var contacts = cursor.currentPageOrderedEntries;
    
                    successCallback(contacts, currentStoreQuery);
                }
                else {
                    console.log("IGNORING Response for #" + currentStoreQuery);
                }
            },
            (error) => {
                console.log("Error->" + JSON.stringify(error));
                errorCallback(error);
            });

    总结一下就是先构建查询用的字符串,再利用build方法创建出querySpec对象,最后利用相应的query方法查询,结果就是一个数组,数组里的每个元素就是需要的数据对象。

    另外还有一种特别的查询,叫 smart query

    querySpec = smartstore.buildSmartQuerySpec("select {Person:_soup} from {Person}", 100);
        
        smartstore.runSmartQuery(false, querySpec, (cursor)=> {
    
            var persons = cursor.currentPageOrderedEntries;
    
            var person = persons[0];
       
    
        }, (error)=> {
        });

    这里的_soup是固定的,必须这样写。

    这个查询结果也是一个数组,但是数组下还是数组,在第二层数组里才是数据对象。截图如下:

    这个问题也是困扰了我很久,不太明白其中的意义。

    下面是这些问题的官方文档,其实,文档说的也不是很明白。。。

    https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/offline_query.htm


    再简单说下smartsync的用法,smartsync使用时的关键参数有2个,一个是从服务器抓取数据的sql语句,第二个是要存到本地的soup名字。看一段demo
    function syncDown(callback) {
        if (syncInFlight) {
            console.log("Not starting syncDown - sync already in fligtht");
            return;
        }
    
        console.log("Starting syncDown");
        syncInFlight = true;
        var fieldlist = ["Id", "FirstName", "LastName", "Title", "Email", "MobilePhone", "Department", "HomePhone", "LastModifiedDate"];
        var target = {type: "soql", query: "SELECT " + fieldlist.join(",") + " FROM Contact LIMIT 10000"};
        smartsync.syncDown(false,
            target,
            "contacts",
            {mergeMode: smartsync.MERGE_MODE.OVERWRITE},
            (sync) => {
                syncInFlight = false;
                syncDownId = sync._soupEntryId;
                console.log("sync==>" + sync);
                emitSmartStoreChanged();
                if (callback) callback(sync);
            },
            (error) => {
                syncInFlight = false;
            }
        );
    
    }

    再来看一下SmartStore不使用加密时,数据库的结构:首先是name表,这里的name就是soup的name,也就是所谓的表名,通过他们对应的id,就可以找到对应的数据表,比如id=1,那么TABLE_1就是它对应的数据表。

    再看一下:

    这里的index表就是索引表,也就是能够被当做条件进行查询和排序的列的名字,所有的soup的的index都放在一张表里。


    下载了SalesforceMobileSDK-iOS-master之后,里面有一个叫做SmartSyncExplorer的 Demo工程,这个工程里有一套salesforce推荐的同步方法,其中比较重要的是如图的几个类。

    这几个类是SmartStore和SmartSync的具体利用实例,通过这种结构能够更有条理,更方便地使用这2个库。

    具体的分析如下:

    这里经常被使用的类是SObjectDataManager,它提供了以下主要方法:

    refreshLocalData:从本地数据库读取新数据

    refreshRemoteData:从salesforce上的数据库读取新数据到本地数据库,并读取数据

    updateRemoteData:从本地数据库上传数据到salesforce数据库

     这几个方法在使用时,就需要其他几个类的配合,比如

    SObjectData:是soup数据库和oc的接口类,用oc类的方式表示了soup中的数据。其中,soupDict属性就是把SObject中的所有属性和值格式化为一个字典,之后保存这个字典到相应表的soup列里,成为真正保存数据的地方。注意,这里面的property的get和set方法,都被重写了,没有利用每个属性所对应的存储空间,统一使用soupDict中的值。

    SObjectDataSpec:是SObjectData中的关键属性,描述了这个SObjectData所需要的主要信息,主要信息如下:

     self.objectType //salesforce中对应的object名字
            
     self.objectFieldSpecs //soup表对应的数据结构数组,里面是SObjectDataFieldSpec类型
    
     self.updateObjectFieldSpecs //上传数据到服务器时,需要上传的字段数组,,里面是SObjectDataFieldSpec类型
     self.indexSpecs //索引数组,里面是SFSoupIndex类型
    
            
     self.soupName  //本地数据库soup表名
     self.orderByFieldName //排序字段名




    
    
    
  • 相关阅读:
    【郑轻邀请赛 G】密室逃脱
    【郑轻邀请赛 C】DOBRI
    【郑轻邀请赛 F】 Tmk吃汤饭
    【郑轻邀请赛 I】这里是天堂!
    【郑轻邀请赛 B】base64解密
    【郑轻邀请赛 A】tmk射气球
    【郑轻邀请赛 H】 维克兹的进制转换
    解决adb command not found以及sdk环境配置
    adb shell 命令详解,android, adb logcat
    Unexpected exception 'Cannot run program ... error=2, No such file or directory' ... adb'
  • 原文地址:https://www.cnblogs.com/breezemist/p/5804165.html
Copyright © 2011-2022 走看看