Coding App

This chapter guides you on how to develop and use SDK by realizing the most basic file data upload function. It also shows the corresponding interface call and object maintenance in the application through key code segments.

Prepare DID

Developers should be aware that when saving Vault data to the backend, there will be four DIDs:

  • Application DID

  • Application Instance DID

  • User DID

  • Backend Hive Node Service DID

Among them, the application DID is generated by the developers in Essentials for the application, and the DID needs to be publicly put on the chain. Then, the application needs to be compiled to verify the compliance of its application when it is authorized to Essentials. The Application Instance DID stands for a unique application instance that should be run on Android or iOS devices. It needs to be generated at one time when the developer installs it in the application, but doesn’t need to be publicly put on the chain. It can only be used when the application, as the user’s Agent, performs login verification when logging into the Hive Node service.

Each application has a unique DID identity, and users need to generate the DID in Essentials - at the same time, they need to disclose the co-chain. After that, it's kept in Essentials, and users are authorized to use it when logging in for subsequent applications. Backend Hive Node service DID, similar to Application Instance DID, is the only instance DID that represents this Hive service but needs to be exposed for the two-way authentication when frontend applications interact.

The specified DID identity authorized in Essentials is used to login to the application. When requesting login from the backend Hive Node, you need to issue a credential requesting login to the application instance (instance DID) through the authorization of Essentials. Hive Node authorizes to issue an access token to the frontlog inend application by verifying the authenticity of the login credentials, and subsequent applications use the access token to save and access the data in the Vault.

Create Vault

After the user creates the application framework through Xcode tool, the Vault object is instantiated through SDK, and then the corresponding sub-service interface is obtained through the Vault object. When instantiating a Vault object, you need to prepare a certain program context environment. We need to use AppContext and Hive Node Provider URL address here. The Application Instance DID and User DID are used to create AppContext.

public class TestAppContextProvider: AppContextProvider {
    public func getAuthorization(_ authenticationChallengeJWTcode: String) -> Promise<String>? {
        return Promise<String> { resolver in
            resolver.fulfill(signAuthorization(authenticationChallengeJWTcode)!)
        }
    }
    
    public var appInstanceDid: AppDID
    public var userDid: UserDID
    private var localDataDir: String

    public func getLocalDataDir() -> String? {
        self.localDataDir
    }
    
    public func getAppInstanceDocument() -> DIDDocument? {
        return try! appInstanceDid.getDocument()
    }
    
    init(_ path: String, _ userDid: UserDID, _ appInstanceDid: AppDID) {
        self.localDataDir = path
        self.userDid = userDid
        self.appInstanceDid = appInstanceDid
    }
    
    public func signAuthorization(_ jwtToken: String) -> String? {
        
        var accessToken: String?
        let semaphore: DispatchSemaphore = DispatchSemaphore(value: 0)
        DispatchQueue.global().async { [self] in
            do {
                let claims = try JwtParserBuilder().build().parseClaimsJwt(jwtToken).claims
                let iss = claims.getIssuer()
                let nonce = claims.get(key: "nonce") as? String
                
                let vc = try userDid.issueDiplomaFor(appInstanceDid)
                let vp: VerifiablePresentation = try appInstanceDid.createPresentation(vc, iss!, nonce!)
                let token = try appInstanceDid.createToken(vp, iss!)
                accessToken = token
                semaphore.signal()
            } catch{
                print(error)
                semaphore.signal()
            }
        }
        semaphore.wait()
        return accessToken!
    }
}

let context = try AppContext.build(TestAppContextProvider(STORE-PATH, USER-DID, APPINSTANCE-DID), USER-DID)

同æ—ļ通čŋ‡é€‰æ‹Šå¯äŋĄįš„Hive Node æœåŠĄčŠ‚į‚šīŧŒåĄĢ充寚åē”įš„ Hive Node 地址äŊœä¸ē Provider address 参数。有äē† AppContext å¯ščąĄå’Œ Provider addressīŧŒå°ąå¯äģĨåŽžäž‹åŒ–åˇ˛å­˜åœ¨įš„ Vault service å¯ščąĄīŧš

Meanwhile, the corresponding Hive Node address is filled as the Provider address parameter by selecting trusted Hive Node service nodes. With AppContext object and Provider address, you can instantiate the existing Vault service object:

let vault = Vault(context, providerAddress)

Get FileService Interface

Because the example only involves the file upload function, we only need to get the FileService interface - the specific call interface is as follows:

let fileService = vault.fileService

Upload File

Once the FilesService interface instance is obtained, the file data can be uploaded to the Vault service through this interface. When a file is uploading, the writer should be obtained first; then the file content is written to complete the whole process of uploading file data.

self.scriptOwner.filesService.getUploadWriter(remoteImagePath).then { writer in
            return try writer.write(data: self.imgDate)
        }.done { success in
            DispatchQueue.main.async {
                let text = success == true ? "upload image: success" : "upload image: false"

               print(text)
				// handle your data ......
            }
        }.catch { error in
               print(error)
        }

Last updated