72

New to IOS programming but just wondering where is the best place to put functions that I would use throughout my code. For example, I want to write a few functions to perform a POST request to a web service and return a dictionary. Maybe another function to do some calculations. Is it best to create another .swift file and put all my functions there. And what would be a good name to give the file if so?

public func postRequest() -> [String:String] {
     // do a post request and return post data
     return ["someData" : "someData"]
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
Alex Lacayo
  • 1,462
  • 1
  • 19
  • 27
  • 1
    Create a separate swift file and put all such functions in that. You can use that throughout the code. – Kapil Jun 04 '15 at 01:27

5 Answers5

123

The best way is to create a helper class with static functions, like this:

class Helper{
    static func postRequest() -> [String:String] {
         // do a post request and return post data
         return ["someData" : "someData"]
    }
}

Now every time you need to use postRequest you can just use like so: Helper.postRequest()

starball
  • 20,030
  • 7
  • 43
  • 238
Icaro
  • 14,585
  • 6
  • 60
  • 75
  • Thank you! So just simply naming it Helper.swift would be ok practice? – Alex Lacayo Jun 04 '15 at 01:30
  • 9
    I normally have many helper so I would have AnimationHelper.swift, CoreDataHelper.swift and so on, try to break your helper classes separated by the job it does – Icaro Jun 04 '15 at 01:31
  • Would func postRequest() need to be a static func postRequest() in order to call it using Helper.postRequest()? xCode is telling me so. – Alex Lacayo Jun 04 '15 at 08:49
  • 1
    Yes sorry it has to, otherwise you need to create an object to use. I update the post – Icaro Jun 04 '15 at 08:51
  • Thanks. Also how can another class within Helper call postRequest()? I was having trouble doing this once it became static? – Alex Lacayo Jun 04 '15 at 08:52
  • Yes no problem, the only thing you cannot do is use no static class variables, but if you are going to have class variables its better to not use static func but create an object to use – Icaro Jun 04 '15 at 08:56
  • `Helper.postRequest()` is it a singleton object ? Also it will occupy same instance of class in memory or not ? – Shah Nilay Nov 21 '17 at 04:26
  • I want to write activity indicator once and use it in different places, that my app needs. Can you assist me how to do that? – Vasanth Jan 04 '18 at 12:17
  • If I am not making it static then Instead of this can we use a singleton class to avoid memory consumption?? – Bhavin_m Mar 20 '19 at 07:10
  • Seem you can remove the class, Just keep func in a Helper.swift is more simple – Moon soon Mar 24 '20 at 09:31
  • @Bhavin_m did you get your answer? – Dzondzula Nov 06 '22 at 16:58
  • Not sure but this was a way older question, I would have found a good explanation here -- https://stackoverflow.com/questions/37806982/difference-between-static-function-and-singleton-class-in-swift#:~:text=Major%20difference%20between%20static%20and,be%20used%20directly%20without%20instantiation. regarding the same, which might help you or someone else. – Bhavin_m Nov 10 '22 at 09:25
4

I usually create a separate class if I have functions that will be used by multiple classes, especially for the ones involving network operations.

If you just have separate functions that will be used, you can simply create static functions inside that class so it is easily accessible by other classes in a static way:

class DataController {
    static func getData() -> [String:String] {
        // do some operations
        return ["someData" : "someData"]
    }
}

let data = DataController.getData()  // example

However, what often has been the case for me (especially if it involves more complicated operations) was that these network operations needed to establish an initial connection beforehand or required some initial setups, and they also performed asynchronous operations that needed to be controlled. If this is the case and you will often be calling such methods, you might want to create a singleton object that you could use throughout different classes and functions. This way, you could do the initial setup or establish an initial connection just once, and then do the rest as needed with the other functions, instead of doing them every time the function gets called.

Creating a singleton object is pretty simple in Swift:

class DataController {
    static let sharedInstance = DataController()  // singleton object

    init() {
        // do initial setup or establish an initial connection
    }

    func getData() -> [String:String] {
        // do some operations
        return ["someData" : "someData"]
    }
}

let data = DataController.sharedInstance.getData()  // example

For the name of the class, I usually name it something like DataController or DataHelper, but anything that makes sense as a "helper" class would work.

Hope this helps :)

Dennis
  • 3,506
  • 5
  • 34
  • 42
3

For reusable functions it depends what I decide to use. For this specific case I use a separate file, because posting to a backend will become more complicated when the application evolves. In my app I use a backend class, with all kinds of helper classes:

struct BackendError {
    var message : String
}

struct SuccessCall {
    var json : JSON

    var containsError : Bool {
        if let error = json["error"].string {
            return true
        }
        else {
            return false
        }

    }
}

typealias FailureBlock  = (BackendError) -> Void
typealias SuccessBlock  = (SuccessCall) -> Void

typealias AlamoFireRequest = (path: String, method: Alamofire.Method, data: [String:String]) -> Request
typealias GetFunction = (path: String , data: [String : String], failureBlock: FailureBlock, successBlock: SuccessBlock) -> Void

class Backend {
   func getRequestToBackend (token: String )(path: String , data: [String : String], failureBlock: FailureBlock, successBlock: 

}

For other cases I often use extensions on Swift classes. Like for getting a random element from an Array.

extension Array {
    func sampleItem() -> T {
        let index = Int(arc4random_uniform(UInt32(self.count)))
        return self[index]
    }
}
Raymond
  • 3,630
  • 2
  • 19
  • 22
  • this seems pretty cool. Do you have soe sample app? I'm a newbie and it would help me a lot. – bruno Jan 27 '17 at 10:26
3

This very old question but I would like to chirp some more points. There are a few option, basically you can write your utility functions in Swift -

A class with static function. For example

class CommonUtility {
      static func someTask() {
      }    
}
// uses
CommonUtility.someTask()

Also, you can have class method's as well instead of static method but those functions can be overridden by subclasses unlike static functions.

class CommonUtility {
      class func someTask() {
      }    
}
// uses
CommonUtility.someTask()

Secondly, you can have Global functions as well, that are not part of any class and can be access anywhere from your app just by name.

func someTask() {
} 

Though, selecting one over other is very subjective and I thing this is ok to make a class with static function in this particular case, where you need to achieve networking functionality but if you have some functions which perform only one task than Global function is a way to go because Global functions are more modular and separate out single tasks for a single function.

In case of static functions, if we access one of the static member, entire class gets loaded in memory. But in case of global function, only that particular function will be loaded in mem

Suryakant Sharma
  • 3,852
  • 1
  • 25
  • 47
1

You can create a separate swift class, might name it WebServicesManager.swift, and write all methods related to web requests in it.

You can use class methods, or singleton pattern to access the methods.

sudhanshu-shishodia
  • 1,100
  • 1
  • 11
  • 25