Networking structure for Swift iOS appAsynchronous networking iOS API callsNetworking in iOS SwiftGetting...

Why did Kant, Hegel, and Adorno leave some words and phrases in the Greek alphabet?

Everything Bob says is false. How does he get people to trust him?

How do I keep an essay about "feeling flat" from feeling flat?

Should my PhD thesis be submitted under my legal name?

Student evaluations of teaching assistants

Is there an Impartial Brexit Deal comparison site?

How can I use the arrow sign in my bash prompt?

At which point does a character regain all their Hit Dice?

Is there any reason not to eat food that's been dropped on the surface of the moon?

Personal Teleportation as a Weapon

How will losing mobility of one hand affect my career as a programmer?

Can criminal fraud exist without damages?

Why is delta-v is the most useful quantity for planning space travel?

Ways to speed up user implemented RK4

What's a natural way to say that someone works somewhere (for a job)?

Applicability of Single Responsibility Principle

Is it okay / does it make sense for another player to join a running game of Munchkin?

Confused about a passage in Harry Potter y la piedra filosofal

Is this Spell Mimic feat balanced?

Hostile work environment after whistle-blowing on coworker and our boss. What do I do?

What are the ramifications of creating a homebrew world without an Astral Plane?

Was the picture area of a CRT a parallelogram (instead of a true rectangle)?

Is there a problem with hiding "forgot password" until it's needed?

Your magic is very sketchy



Networking structure for Swift iOS app


Asynchronous networking iOS API callsNetworking in iOS SwiftGetting WiFi SSID on iOS in SwiftSwift iOS - Call back functionsImplementation of a like button in iOS for Instagram like app in SwiftInterview coding challenge for iOS Part 2 - the application in Objective-C and SwiftSwift/iOS: Subclassing UILabel and setting propertiesSwift/iOS component for label with clickable text buttonsiOS Swift 3 app that requests data from the Stack Exchange APIiOS Memory Game - Swift 4













1












$begingroup$


I would like any constructive comments regarding the structure of this simple App that takes an API response and then displays on a table view.



The URL is written in a ConstantsAPI file



let baseUrl : String = "https://haveibeenpwned.com/api/v2"
let breachesExtensionURL : String = "/breaches"


Displayed on a tableviewcontroller



class SitewideTableViewController: UITableViewController, DataManagerDelegate {
var pwnedData = [BreachModel]()
var session: URLSession!
var task: URLSessionDownloadTask!

override func viewDidLoad() {
super.viewDidLoad()
session = URLSession.shared
task = URLSessionDownloadTask()
DataManager.shared.delegate = self
DataManager.shared.fetchBreaches()
}

func didDownloadBreaches() {
DispatchQueue.main.async {
self.pwnedData = DataManager.shared.sortedBreaches()
self.tableView.reloadData()
}
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pwnedData.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Sitewide", for: indexPath)
cell.textLabel?.text = pwnedData[indexPath.row].name
return cell
}
}


Using the following model



import Foundation

class BreachModel : Codable {
let name : String
let title : String
let domain : String
let breachDate : String
let addedDate : String
let modifiedData : String
let pwnCount : Int
let description: String

private enum CodingKeys: String, CodingKey {
case name = "Name"
case title = "Title"
case domain = "Domain"
case breachDate = "BreachDate"
case addedDate = "AddedDate"
case modifiedData = "ModifiedDate"
case pwnCount = "PwnCount"
case description = "Description"
}
}


With a Data manager that would manage all of the data



@objc protocol DataManagerDelegate: class {
// optional delegate to practice
@objc optional func didDownloadBreaches() // called when the manager has completed downloading all the breaches
}


class DataManager {
static let shared: DataManager = DataManager()
public weak var delegate: DataManagerDelegate? = nil

private var breaches = [BreachModel]()
func fetchBreaches() {

HTTPManager.shared.get(urlString: baseUrl + breachesExtensionURL, completionBlock: { [weak self] (data: Data?) -> Void in
let decoder = JSONDecoder()
if let data = data{
print(data.count)
do {
self?.breaches = try decoder.decode([BreachModel].self, from: data)
self?.delegate?.didDownloadBreaches?()
} catch let error {
print ("Error in reading data", error)
}
}
}
)
}

func sortedBreaches() -> [BreachModel] {
return breaches.sorted{ a,b in a.name < b.name }
}
}


That calls a HTTP manager whose only responsibility is to call url's



class HTTPManager {
static let shared: HTTPManager = HTTPManager()
public func get (urlString: String, completionBlock: ((Data?) -> Void)?) {
let url = URL(string: urlString)
if let usableUrl = url {
let request = URLRequest(url: usableUrl)
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
completionBlock?(data)
})
task.resume()
}
}
}


So is this a reasonable extendable structure?
Should I have used dataTask or URLSessionDownloadTask?
Have I unwittingly introduced some memory leaks?



Any comments appreciated, I'm familiar with the Swift book but find other tutorials tend to just show the use of codable or an API and do not talk through the whole structure (at least not at an appropriate level for me). The code above does work, and I'm thinking of building upon it in the future but want to follow some form of best practice (no matter how trivial).



Git link: https://github.com/stevencurtis/basicnetworking









share











$endgroup$

















    1












    $begingroup$


    I would like any constructive comments regarding the structure of this simple App that takes an API response and then displays on a table view.



    The URL is written in a ConstantsAPI file



    let baseUrl : String = "https://haveibeenpwned.com/api/v2"
    let breachesExtensionURL : String = "/breaches"


    Displayed on a tableviewcontroller



    class SitewideTableViewController: UITableViewController, DataManagerDelegate {
    var pwnedData = [BreachModel]()
    var session: URLSession!
    var task: URLSessionDownloadTask!

    override func viewDidLoad() {
    super.viewDidLoad()
    session = URLSession.shared
    task = URLSessionDownloadTask()
    DataManager.shared.delegate = self
    DataManager.shared.fetchBreaches()
    }

    func didDownloadBreaches() {
    DispatchQueue.main.async {
    self.pwnedData = DataManager.shared.sortedBreaches()
    self.tableView.reloadData()
    }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return pwnedData.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Sitewide", for: indexPath)
    cell.textLabel?.text = pwnedData[indexPath.row].name
    return cell
    }
    }


    Using the following model



    import Foundation

    class BreachModel : Codable {
    let name : String
    let title : String
    let domain : String
    let breachDate : String
    let addedDate : String
    let modifiedData : String
    let pwnCount : Int
    let description: String

    private enum CodingKeys: String, CodingKey {
    case name = "Name"
    case title = "Title"
    case domain = "Domain"
    case breachDate = "BreachDate"
    case addedDate = "AddedDate"
    case modifiedData = "ModifiedDate"
    case pwnCount = "PwnCount"
    case description = "Description"
    }
    }


    With a Data manager that would manage all of the data



    @objc protocol DataManagerDelegate: class {
    // optional delegate to practice
    @objc optional func didDownloadBreaches() // called when the manager has completed downloading all the breaches
    }


    class DataManager {
    static let shared: DataManager = DataManager()
    public weak var delegate: DataManagerDelegate? = nil

    private var breaches = [BreachModel]()
    func fetchBreaches() {

    HTTPManager.shared.get(urlString: baseUrl + breachesExtensionURL, completionBlock: { [weak self] (data: Data?) -> Void in
    let decoder = JSONDecoder()
    if let data = data{
    print(data.count)
    do {
    self?.breaches = try decoder.decode([BreachModel].self, from: data)
    self?.delegate?.didDownloadBreaches?()
    } catch let error {
    print ("Error in reading data", error)
    }
    }
    }
    )
    }

    func sortedBreaches() -> [BreachModel] {
    return breaches.sorted{ a,b in a.name < b.name }
    }
    }


    That calls a HTTP manager whose only responsibility is to call url's



    class HTTPManager {
    static let shared: HTTPManager = HTTPManager()
    public func get (urlString: String, completionBlock: ((Data?) -> Void)?) {
    let url = URL(string: urlString)
    if let usableUrl = url {
    let request = URLRequest(url: usableUrl)
    let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
    completionBlock?(data)
    })
    task.resume()
    }
    }
    }


    So is this a reasonable extendable structure?
    Should I have used dataTask or URLSessionDownloadTask?
    Have I unwittingly introduced some memory leaks?



    Any comments appreciated, I'm familiar with the Swift book but find other tutorials tend to just show the use of codable or an API and do not talk through the whole structure (at least not at an appropriate level for me). The code above does work, and I'm thinking of building upon it in the future but want to follow some form of best practice (no matter how trivial).



    Git link: https://github.com/stevencurtis/basicnetworking









    share











    $endgroup$















      1












      1








      1





      $begingroup$


      I would like any constructive comments regarding the structure of this simple App that takes an API response and then displays on a table view.



      The URL is written in a ConstantsAPI file



      let baseUrl : String = "https://haveibeenpwned.com/api/v2"
      let breachesExtensionURL : String = "/breaches"


      Displayed on a tableviewcontroller



      class SitewideTableViewController: UITableViewController, DataManagerDelegate {
      var pwnedData = [BreachModel]()
      var session: URLSession!
      var task: URLSessionDownloadTask!

      override func viewDidLoad() {
      super.viewDidLoad()
      session = URLSession.shared
      task = URLSessionDownloadTask()
      DataManager.shared.delegate = self
      DataManager.shared.fetchBreaches()
      }

      func didDownloadBreaches() {
      DispatchQueue.main.async {
      self.pwnedData = DataManager.shared.sortedBreaches()
      self.tableView.reloadData()
      }
      }

      override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return pwnedData.count
      }

      override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: "Sitewide", for: indexPath)
      cell.textLabel?.text = pwnedData[indexPath.row].name
      return cell
      }
      }


      Using the following model



      import Foundation

      class BreachModel : Codable {
      let name : String
      let title : String
      let domain : String
      let breachDate : String
      let addedDate : String
      let modifiedData : String
      let pwnCount : Int
      let description: String

      private enum CodingKeys: String, CodingKey {
      case name = "Name"
      case title = "Title"
      case domain = "Domain"
      case breachDate = "BreachDate"
      case addedDate = "AddedDate"
      case modifiedData = "ModifiedDate"
      case pwnCount = "PwnCount"
      case description = "Description"
      }
      }


      With a Data manager that would manage all of the data



      @objc protocol DataManagerDelegate: class {
      // optional delegate to practice
      @objc optional func didDownloadBreaches() // called when the manager has completed downloading all the breaches
      }


      class DataManager {
      static let shared: DataManager = DataManager()
      public weak var delegate: DataManagerDelegate? = nil

      private var breaches = [BreachModel]()
      func fetchBreaches() {

      HTTPManager.shared.get(urlString: baseUrl + breachesExtensionURL, completionBlock: { [weak self] (data: Data?) -> Void in
      let decoder = JSONDecoder()
      if let data = data{
      print(data.count)
      do {
      self?.breaches = try decoder.decode([BreachModel].self, from: data)
      self?.delegate?.didDownloadBreaches?()
      } catch let error {
      print ("Error in reading data", error)
      }
      }
      }
      )
      }

      func sortedBreaches() -> [BreachModel] {
      return breaches.sorted{ a,b in a.name < b.name }
      }
      }


      That calls a HTTP manager whose only responsibility is to call url's



      class HTTPManager {
      static let shared: HTTPManager = HTTPManager()
      public func get (urlString: String, completionBlock: ((Data?) -> Void)?) {
      let url = URL(string: urlString)
      if let usableUrl = url {
      let request = URLRequest(url: usableUrl)
      let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
      completionBlock?(data)
      })
      task.resume()
      }
      }
      }


      So is this a reasonable extendable structure?
      Should I have used dataTask or URLSessionDownloadTask?
      Have I unwittingly introduced some memory leaks?



      Any comments appreciated, I'm familiar with the Swift book but find other tutorials tend to just show the use of codable or an API and do not talk through the whole structure (at least not at an appropriate level for me). The code above does work, and I'm thinking of building upon it in the future but want to follow some form of best practice (no matter how trivial).



      Git link: https://github.com/stevencurtis/basicnetworking









      share











      $endgroup$




      I would like any constructive comments regarding the structure of this simple App that takes an API response and then displays on a table view.



      The URL is written in a ConstantsAPI file



      let baseUrl : String = "https://haveibeenpwned.com/api/v2"
      let breachesExtensionURL : String = "/breaches"


      Displayed on a tableviewcontroller



      class SitewideTableViewController: UITableViewController, DataManagerDelegate {
      var pwnedData = [BreachModel]()
      var session: URLSession!
      var task: URLSessionDownloadTask!

      override func viewDidLoad() {
      super.viewDidLoad()
      session = URLSession.shared
      task = URLSessionDownloadTask()
      DataManager.shared.delegate = self
      DataManager.shared.fetchBreaches()
      }

      func didDownloadBreaches() {
      DispatchQueue.main.async {
      self.pwnedData = DataManager.shared.sortedBreaches()
      self.tableView.reloadData()
      }
      }

      override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return pwnedData.count
      }

      override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: "Sitewide", for: indexPath)
      cell.textLabel?.text = pwnedData[indexPath.row].name
      return cell
      }
      }


      Using the following model



      import Foundation

      class BreachModel : Codable {
      let name : String
      let title : String
      let domain : String
      let breachDate : String
      let addedDate : String
      let modifiedData : String
      let pwnCount : Int
      let description: String

      private enum CodingKeys: String, CodingKey {
      case name = "Name"
      case title = "Title"
      case domain = "Domain"
      case breachDate = "BreachDate"
      case addedDate = "AddedDate"
      case modifiedData = "ModifiedDate"
      case pwnCount = "PwnCount"
      case description = "Description"
      }
      }


      With a Data manager that would manage all of the data



      @objc protocol DataManagerDelegate: class {
      // optional delegate to practice
      @objc optional func didDownloadBreaches() // called when the manager has completed downloading all the breaches
      }


      class DataManager {
      static let shared: DataManager = DataManager()
      public weak var delegate: DataManagerDelegate? = nil

      private var breaches = [BreachModel]()
      func fetchBreaches() {

      HTTPManager.shared.get(urlString: baseUrl + breachesExtensionURL, completionBlock: { [weak self] (data: Data?) -> Void in
      let decoder = JSONDecoder()
      if let data = data{
      print(data.count)
      do {
      self?.breaches = try decoder.decode([BreachModel].self, from: data)
      self?.delegate?.didDownloadBreaches?()
      } catch let error {
      print ("Error in reading data", error)
      }
      }
      }
      )
      }

      func sortedBreaches() -> [BreachModel] {
      return breaches.sorted{ a,b in a.name < b.name }
      }
      }


      That calls a HTTP manager whose only responsibility is to call url's



      class HTTPManager {
      static let shared: HTTPManager = HTTPManager()
      public func get (urlString: String, completionBlock: ((Data?) -> Void)?) {
      let url = URL(string: urlString)
      if let usableUrl = url {
      let request = URLRequest(url: usableUrl)
      let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
      completionBlock?(data)
      })
      task.resume()
      }
      }
      }


      So is this a reasonable extendable structure?
      Should I have used dataTask or URLSessionDownloadTask?
      Have I unwittingly introduced some memory leaks?



      Any comments appreciated, I'm familiar with the Swift book but find other tutorials tend to just show the use of codable or an API and do not talk through the whole structure (at least not at an appropriate level for me). The code above does work, and I'm thinking of building upon it in the future but want to follow some form of best practice (no matter how trivial).



      Git link: https://github.com/stevencurtis/basicnetworking







      swift ios





      share














      share












      share



      share








      edited 2 mins ago







      stevenpcurtis

















      asked 7 mins ago









      stevenpcurtisstevenpcurtis

      1505




      1505






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216310%2fnetworking-structure-for-swift-ios-app%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216310%2fnetworking-structure-for-swift-ios-app%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          is 'sed' thread safeWhat should someone know about using Python scripts in the shell?Nexenta bash script uses...

          How do i solve the “ No module named 'mlxtend' ” issue on Jupyter?

          Pilgersdorf Inhaltsverzeichnis Geografie | Geschichte | Bevölkerungsentwicklung | Politik | Kultur...