1

Qustion

I have a following structure

class UITableViewController (Presentation) -> class Contents(Domain) -> class API(Infrastructure)

Contents class gets raw data via API class and forms contents and then passes to UITableViewController.

I would like to use Alamofire to do Networking in API class.

I’ve looked through stackoverflow and I only found examples that UITableViewController directly accesses API class. Direct access from Presentation layer to Infrastructure layer is something we should not do. Like this How to return value from Alamofire

How do I achieve implementing Alamofire into DDD structure?

I want to achieve something like this

UITableViewController

class MyTableViewController: UITableViewController {

var contents: Contents?

override func viewDidLoad() {
    super.viewDidLoad()

    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_async(dispatch_get_global_queue(priority, 0)) {
        // do some task
        self.contents = Contents.get("MyContents")
        self.tableView.reloadData()

    }
}
}

Contents

class Contents: NSObject {

static func get(contentsName: String) -> Contents {
    let data = MyAPI.getRequest("https://xxxx.com/myContents")

    // Form contents
    let contents = ContentsFactory(data)

    return contents
}
}

API

class MyAPI: NSObject {

static getRequest(url) -> NSData {
    // Get and return data using alamofire
}
}
Community
  • 1
  • 1
Bigair
  • 1,452
  • 3
  • 15
  • 42

1 Answers1

0

You need to deal with the get request being run in the background, whereas the instance of Contents will be returned immediately. In the completion handler for the Alamofire request, you will need it to call back to the Contents instance, which will then call back to the ViewController.

Therefore your Contents class needs to have a completion closure passed on the get function, along the lines of:

static func get(contentsName: String, completion: (() -> Void)?) -> Contents {

This closure will have to be passed down to the API (or through other techniques), so it can ultimately be called when the Alamofire request completes. Also, rather than have the class method do all the background work, it would be better handled in the Contents instance you create.

Then you will call using:

self.contents = Contents.get("MyContents", completion({
    dispatch_async(dispatch_get_global_queue(priority, 0)) {
        self.tableView.reloadData()
    }
}
Michael
  • 8,891
  • 3
  • 29
  • 42
  • Thanks for brilliant answer. I did a little bit different way on TableView but overall idea was super helpful! – Bigair Feb 08 '16 at 14:31