0

I have three function inside the repository class . I am calling the function in order first createUser, then submitApplication and finally submitMemorableWord function . Condition is if the createUser function execution is successfully then it will go to submitApplication function , then if submitApplication function execution is successfully then flow will go to submitMemorableWord function.

I have set boolean flag into function execution block if the boolean flag return true then go to next code execution and call the appropriate function. I have debug it it and find out only createUser function is called.

I made boolean tag (success) to true on execute function and then I am expecting it should go to submit function and call submitApplication. I also set another boolean flag submitComplete into submit function and change the value to true when submit function is return successfully and finally I am checking if boolean tag submitComplete return true , that means submit function code execution is successfull then call complete function and respectfully return the result of the complete function.

of the never call submit or submitApplication function which is next function to be called..

Here is the code for Repository class....

import Foundation

class Repository {
 
    init() {}
    func createUser() async throws -> String {
        "User"
    }
 
    func submitApplication() async throws -> Bool {
        true
    }
 
    func submitMemorableWord() async throws -> Bool {
        true
    }
}

Here is the code for

import Foundation UseCase class 

class UseCase {
  
  let repository = Repository()
  var success: Bool = false
  var sumbitComplete: Bool = false
  
  func execute() async throws {
    do {
      success = true
      let createUser =  try await repository.createUser()
    } catch {
      success = false
      print("error " + error.localizedDescription)
    }
    
    func submit() async -> Bool {
      if success {
        do {
          let submit = try await repository.submitApplication()
          sumbitComplete = true
        } catch {
          return false
        }
      }
      return true
    }
  }
  func complete() async {
    if sumbitComplete {
      do {
        let completeRequest =  try await repository.submitMemorableWord()
      } catch {
        print("Sorry sometings went wrong..")
      }
    }
  }
}

Here is code in view controller ..

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
      Task { await FinalResult() }
    }


  func FinalResult() async {
    let usecase = SimpleUseCase()
    do {
      let result = try await usecase.execute()
    } catch {
      print(error.localizedDescription)
    }
  }
}
5
  • Different possible way. You could write a didSet on execute() and call then submit() if needed. But it might be simpler in execute to call submit() if success, etc. Commented Oct 8, 2024 at 8:37
  • You never call submit or complete. Also submit is a nested function inside execute. Is that really what you intended? Why don't you simply call submit() and complete() in order inside ` execute()`? Commented Oct 8, 2024 at 9:04
  • like this way ... do { let _ = try await repository.submitMemorableWord() } catch { print("Sorry sometings went wrong..") } Commented Oct 8, 2024 at 10:06
  • For "complicated" logic, I usually use a Finite State Machine. A solution using this, is however a bit more involved. If you are interested I can post a solution. Commented Oct 8, 2024 at 11:40
  • please post the solution . I love to learn and solve the problem always batter way. @CouchDeveloper. Commented Oct 8, 2024 at 14:23

2 Answers 2

0

It seems like it would be simpler to have execute manage the whole process

func execute() async throws {
   let createUser = try await repository.createUser()
   let submit = try await repository.submitApplication()
   let completeRequest = try await repository.submitMemorableWord()
}

There is no need for the do/try/catch in execute(). Any errors will be thrown to the caller.

If you want to be able to catch an error that tells you which part of the process failed, you can use a custom error that wraps the thrown error:

enum RepositoryError: Error {

  case createUserError(_ error: Error)
  case submitApplicationError(_ error: Error)
  case submitWordError(_ error: Error)
}

func execute() async throws {
   do {
       let createUser = try await repository.createUser()
   catch {
       throw RespositoryError.createUserError(error)
   }
   do { 
       let submit = try await repository.submitApplication()
   } 
   catch {
       throw RespositoryError.submitApplicationError(error)
   }
   do {
       let completeRequest = try await repository.submitMemorableWord()
   }
   catch {
       throw RespositoryError.submitWordError(error)
   }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Ok . Thanks .. How can I can handle error case if anyone request is fail but I do not want to modify the repository class
If the repository methods don't throw specific errors, you could create your own error types and use them to wrap the error that was thrown and throw them
0

You can just call the async calls serially, since it waits for the result, hence it would execute serially.

func execute() async throws {
    do {
        let createUser =  try await repository.createUser()
        let submit = try await repository.submitApplication()
        let completeRequest =  try await repository.submitMemorableWord()
    } catch {
        print("error " + error.localizedDescription)
    }
}

You can handle the error in any of the request in the catch block.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.