 import Incito
 import UIKit
 
+enum IncitoPublicationLoaderError: Error {
+    case notAnIncitoPublication
+}
+
 extension IncitoLoaderViewController {
+    
+    public func load(
+        publicationId: CoreAPI.PagedPublication.Identifier,
+        graphClient: GraphClient = GraphAPI.shared.client,
+        publicationLoaded: ((Result<CoreAPI.PagedPublication>) -> Void)? = nil,
+        businessLoaded: ((Result<GraphBusiness>) -> Void)? = nil,
+        completion: ((Result<(viewController: IncitoViewController, firstSuccessfulLoad: Bool)>) -> Void)? = nil
+        ) {
+        
+        // Keep track of the id of the incitoId once it is loaded.
+        var firstLoadedIncitoId: IncitoGraphIdentifier? = nil
+        var publicationIncitoId: IncitoGraphIdentifier? = nil
+        
+        // every time the loader is called, fetch the width of the screen
+        let graphLoader: (IncitoGraphIdentifier) -> IncitoLoader = { graphId in
+            Future(work: { [weak self] in Double(self?.view.frame.size.width ?? 0) })
+            .asyncOnMain()
+            .flatMap({ width in
+                IncitoGraphLoader(
+                    id: graphId,
+                    graphClient: graphClient,
+                    width: width,
+                    businessLoadedCallback: { businessLoaded?($0.shopGunSDKResult) }
+                )
+            })
+        }
+        
+        // make a loader that first fetches the publication, then gets the incito id from that publication, then calls the graphLoader with that incitoId
+        let loader = Future<ShopGunSDK.Result<CoreAPI.PagedPublication>>(run: { cb in
+            let publicationReq = CoreAPI.Requests.getPagedPublication(withId: publicationId)
+            CoreAPI.shared.request(publicationReq, completion: cb)
+        })
+            .observe({ publicationLoaded?($0) })
+            .map({
+                Incito.Result(shopGunSDKResult:
+                    $0.mapValue({ (pub: CoreAPI.PagedPublication) -> IncitoGraphIdentifier in
+                        if let incitoId = pub.incitoId {
+                            publicationIncitoId = incitoId
+                            return incitoId
+                        } else {
+                            throw IncitoPublicationLoaderError.notAnIncitoPublication
+                        }
+                    })
+                )
+            })
+            .flatMapResult(graphLoader)
+        
+        self.load(loader) { [weak self] vcResult in
+            switch vcResult {
+            case let .success(viewController):
+                var firstSuccessfulReload: Bool = false
+                if let incitoId = publicationIncitoId {
+                    firstSuccessfulReload = (firstLoadedIncitoId != incitoId)
+                    
+                    if firstSuccessfulReload {
+                        firstLoadedIncitoId = incitoId
+                        self?.firstSuccessfulReload(incitoId: incitoId, relatedPublicationId: publicationId)
+                    }
+                }
+                completion?(.success((viewController, firstSuccessfulReload)))
+            case let .error(error):
+                completion?(.error(error))
+            }
+        }
+    }
     /**
      Will start loading the incito specified by the id, using the graphClient.
      

        self.load(loader) { [weak self] vcResult in
            switch vcResult {
            case let .success(viewController):
                let firstSuccessfulReload = (loadedIncitoId != id)
                if firstSuccessfulReload {
                    loadedIncitoId = id
                    self?.firstSuccessfulReload(incitoId: id, relatedPublicationId: relatedPublicationId)
                }
                completion?(.success((viewController, firstSuccessfulReload)))
            case let .error(error):

            .asyncOnMain()
            .flatMap({ width in
                IncitoGraphLoader(
                    id: graphId,
                    graphClient: graphClient,
                    width: width,
                    businessLoadedCallback: { businessLoaded?($0.shopGunSDKResult) }
