0

私の会社には、Salesforceと直接インターフェースするiOSアプリがありますが、大きな欠点が1つあります。ユーザーが不正な文字をアップロードしようとすると、アプリがハングしたり、不正な値を返したり、その他の異常な動作が発生したりします。

神秘的なインターウェブ(ありがとう、MailDrop)で、文字列をフィルタリングし、それらの不正な文字をスラッシュでエスケープする、非常に便利なコードを見つけました。次に、値を文字列で返し、アップサーティング/クエリの準備が整います。

しかし、私が本当に問題を抱えているのは、これをアプリケーションで機能させることです。データは辞書に保存され、さまざまな方法(サーバーへのクエリ、または手動入力)で、アプリケーションのライフサイクルのさまざまな時点で書き込まれます。この気の利いた「escapeSosl」を最も効率的な方法で呼び出す方法がよくわかりません。Core Dataに書き込むたびにこれらの文字をエスケープできる方法はありますか?私が最も恐れているのは、アプリを調べてこれを何百回も呼び出すことです。

エスケープ方法は次のとおりです。

- (NSString *)escapeSosl:(NSString *)src {
        // from docs, these are all reserved
        NSArray *reserved = [NSArray arrayWithObjects:@"\\", @"&", @"|", @"!", @"{", @"}", @"[", @"]", @"^", @"~", @"*:", @":", @"'" ,@"\"", @"+", @"-", nil];
        NSMutableString *s = [NSMutableString stringWithString:src];
        NSString *r;
        NSEnumerator *e = [reserved objectEnumerator];
        while (r = [e nextObject])
            [s replaceOccurrencesOfString:r withString:[NSString stringWithFormat:@"\\%@", r] options:NSLiteralSearch range:NSMakeRange(0, [s length])];
        return s;
    }

私が複雑だと思うのは、これらの脱出のタイミングと、それをそれぞれの状況にどのように適用するかです。たとえば、アプリは、手動で入力された場所、または逆ジオコーディングによって検出された場所を使用して、Salesforceにアカウントを照会します。Salesforceサーバーにデータを要求するアプリの例を次に示します。

-(void)checkServerForLeadMatchingAddressOnAccount:(SFAccount *)account {

currentAccount = account;

//Parse the account location data, removing the last word in the `street` object
NSString *street = account.shippingStreetAddress;
NSMutableArray *streetArray = [[street componentsSeparatedByString:@" "] mutableCopy];
[streetArray removeLastObject];
street = [streetArray componentsJoinedByString:@" "];
street = [street stringByAppendingString:@"_%"];

NSString *city = account.shippingCity;
NSString *state = account.shippingState;
NSString *zip = account.shippingZIP;

//Check for a matching lead on the server. User the callback methods to proceed (either create new data on the server or download to the device

NSLog(@"is connected: %i", self.isConnectedToServer);

if (self.isConnectedToServer){
    requestCheckForLead = [[SFRestAPI sharedInstance] requestForQuery:[NSString stringWithFormat:@"SELECT ID, Company, Name, Street, City, State, PostalCode, Phone FROM Lead WHERE PostalCode = '%@' AND Street LIKE '%@' AND City = '%@' AND State = '%@'", zip, street, city, state]];
    [[SFRestAPI sharedInstance] send:requestCheckForLead delegate:self];
    openTasks++;
} else {
    NSLog(@"I can't connect");
    [self.serverDelegate serverObjectManager:self communicationSuccessful:NO withResponse:@"Could not connect to the server."];
}

文字をエスケープする可能性のあるもう1つの領域は、サーバーへのアップロードを開始する直前です。アップロードされるものには、アカウント、アカウントの連絡先(1:1 rel。)、アカウントのオポチュニティ(1:1 rel。)、オポチュニティの現在のサービスレベル(1:many rel。)などがあります。

アカウントに関連付けられた連絡先の例を次に示します。文字列と辞書参照の両方を使用しますが、lastNameからfirstNameを解析するための追加のロジックがいくつかあります。これらの操作のタイミングを気にする必要がないようにデータをエスケープしたいと思います。

NSMutableDictionary *contactDict = [NSMutableDictionary new];

if (myAccount.contact.email) {
    [contactDict setObject:myAccount.contact.email forKey:@"Email"];
} else {
    [contactDict setObject:@"" forKey:@"Email"];
}

if (myAccount.contact.name) {
    //Split name in two
    NSArray *nameArray = [myAccount.contact.name componentsSeparatedByString:@" "];

    NSString *firstName = [nameArray objectAtIndex:0];
    NSString *lastName = [nameArray lastObject];


    [contactDict setObject:firstName forKey:@"firstName"];
    [contactDict setObject:lastName forKey:@"lastName"];
} else {
    [contactDict setObject:@"" forKey:@"firstName"];
    [contactDict setObject:@"" forKey:@"lastName"];
}

if (myAccount.contact.phone){
    [contactDict setObject:myAccount.contact.phone forKey:@"Phone"];
} else {
    [contactDict setObject:@"" forKey:@"Phone"];
}

updateContactRequest = [[SFRestAPI sharedInstance] requestForUpdateWithObjectType:@"Contact" objectId:myAccount.createdContactID fields:contactDict];
[[SFRestAPI sharedInstance] send:updateContactRequest delegate:self];

したがって、これは少し大きな質問のように思えるかもしれませんが、コアデータに書き込まれるときはいつでも、上記の「escapeSosl」コードに似たものを使用して、これらのさまざまな辞書の文字をエスケープする方法についてのポインタがありますか? ?

4

1 に答える 1

0

この行では、クエリを作成します

requestCheckForLead = [[SFRestAPI sharedInstance] requestForQuery:[NSString stringWithFormat:@"SELECT ID, Company, Name, Street, City, State, PostalCode, Phone FROM Lead WHERE PostalCode = '%@' AND Street LIKE '%@' AND City = '%@' AND State = '%@'", zip, street, city, state]];

street他のパラメータのパラメータパスなどとして渡す代わりに[self escapeSosl:street]

于 2013-03-13T22:38:12.530 に答える