SwiftlySalesforce icon indicating copy to clipboard operation
SwiftlySalesforce copied to clipboard

Is there another way to perform salesforce.nextResultPage in V10?

Open perbrondum opened this issue 3 years ago • 6 comments

perbrondum avatar Apr 05 '22 14:04 perbrondum

@perbrondum sorry, I missed this issue. I neglected to include a 'convenience' method in Connection+API.swift but you could quickly create your own:

func nextResultsPage(path: String) async throws -> QueryResult<Record> {
    return try await request(service: Resource.Query.NextResultsPage(path: path))
}

I will add this to Connection+API.swift for next release.

mike4aday avatar Apr 14 '22 15:04 mike4aday

I tried to create the extension:

import Foundation
import SwiftlySalesforce

extension Connection {
    func nextResultsPage(path: String) async throws -> QueryResult<Record> {
        return try await request(service: Resource.Query.NextResultsPage(path: path))
    }
}

But I get: 'Query' is inaccessible due to 'internal' protection level

perbrondum avatar Apr 14 '22 17:04 perbrondum

Sorry @perbrondum - since Query is inaccessible, you could instead just create your own struct by copying Resource.Query.NextResults as:

struct MyOwnNextResultsPage<T: Decodable>: DataService {
            
    typealias Output = QueryResult<T>
            
    let path: String
            
    var batchSize: Int? = nil
            
    func createRequest(with credential: Credential) throws -> URLRequest {
        let headers = batchSize.map { ["Sforce-Query-Options" : "batchSize=\($0)"] }
        return try URLRequest(credential: credential, path: path, headers: headers)
    }
}

and then in your extension:

func nextResultsPage(path: String) async throws -> QueryResult<Record> {
    return try await request(service: MyOwnNextResultsPage(path: path))
}

(Or you could define the struct above within the extension method if the struct won't be reused elsewhere.)

mike4aday avatar Apr 14 '22 22:04 mike4aday

That works, thanks. Is there a reason that nextResultsPage returns <QueryResult<Record> and not a generic?

perbrondum avatar Apr 30 '22 20:04 perbrondum

Hi @perbrondum not sure I understand your question - the above nextResultsPage method returns a QueryResult<Record> but you could modify it to return QueryResult<T> instead where T is your own custom Decodable type, and Swiftly Salesforce would automatically decode the result's records, if any, into that type. I included my own type, Record, for those who don't want to define their own Decodable types and don't mind using strings to access the field values.

mike4aday avatar May 01 '22 18:05 mike4aday

I got the above to work with both Record and my own decodable type SFDCTask, by creating two versions of nextResultsPage. I tried but, my generics is not strong enough to be able to write a version of nextResultsPage that supports it. My only concern was if the official version of nextResultsPage will support generics? Btw, one of the reasons I continue to use my own type [SFDCTask] is that I'm not sure how to address items like 'task.Account.Name' using strings. Can you point me to a source (or example) for how to address this using strings?

perbrondum avatar May 01 '22 21:05 perbrondum