Group Group Group Group Group Group Group Group Group

raywenderlich.com Forums

CocoaPods Tutorial for Swift: Getting Started

In this tutorial, you'll learn how to install CocoaPods to help you manage third-party library dependencies in your Swift projects.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/626-cocoapods-tutorial-for-swift-getting-started
1 Like

Thanks Joshua and raywenderlich.com for this tutorial!
I can’t wait to get into it.
I really appreciate raywenderlich.com as one of my best, highest quality, most reliable learning resources.
I’m a huge fan and customer!

Jerry

  guard let strongSelf = self else { return }

  strongSelf.hideLoadingHUD() // <-- Add this line

Just a simple question.
Why counldn’t you use just self.hideLoadingHUD() above?

Thanks for the kind words! :smile:

This is to avoid a potential strong reference cycle.

Alamofire.request uses a singleton instance under the hood. Here’s the function for it:

public func request(
    _ url: URLConvertible,
    method: HTTPMethod = .get,
    parameters: Parameters? = nil,
    encoding: ParameterEncoding = URLEncoding.default,
    headers: HTTPHeaders? = nil)
    -> DataRequest
{
   // SessionManager.default is a singleton!
    return SessionManager.default.request(
        url,
        method: method,
        parameters: parameters,
        encoding: encoding,
        headers: headers
    )
}

In a real app, it’s possible SessionManager.default could (and likely would even) outlive the view controller here.

So if we inadvertently capture self (the view controller) within the SessionManager.default's closure, there’s a potential we could extend its life longer than necessary, or in the worst case, even leak memory.

By doing the weak -> strongSelf dance as we’ve done, this prevents the strong reference cycle issue here. :smile:

Guys I installed RxTest and RxBlocking via CocoaPods and those libraries works perfectly, but Xcode is showing error “No such module RxTest”
When I comment it out, then error is on another import line…

The same thing with FBSnapshotTestCase… Problem occurs only in Tests Target.

As I said, it has no effect on compile and testing, it’s just annoying. Do you know how to fix it?

Here is my pod file:
# Uncomment the next line to define a global platform for your project
platform :ios, ‘10.2’

target 'MyProject' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

    # Pods for MyProject
    pod 'RxSwift'
    pod 'RxCocoa'
    pod 'RxDataSources'
    
  target 'MyProjectTests' do
      # inherit! :search_paths
      # Pods for testing
      pod 'RxBlocking'
      pod 'RxTest'
      pod 'FBSnapshotTestCase'
  end

end

post_install do |installer|
    installer.pods_project.targets.each do |target|
        if target.name == 'RxSwift'
            target.build_configurations.each do |config|
                if config.name == 'Debug'
                    config.build_settings['OTHER_SWIFT_FLAGS'] ||= ['-D', 'TRACE_RESOURCES']
                end
            end
        end
    end
end

By doing the weak -> strongSelf dance as we’ve done, this prevents the strong reference cycle issue here.

Is it possible to use an explicitly weak variable instead of the strong reference in this case ?

Thanks for the excellent article.

As a newbie question, where would you recommend to look for pods as per needs in my apps? Like I need some interactive controllers etc? Thanks!

Yes, this is what [weak self] does: it declares self to be weak within the closure’s context.

We get a strong reference to self by doing guard let strongSelf = self else { return }, which essentially says “if self still exists (isn’t nil yet), create a strong reference to it, or else just bail out (that is, return early).”

You could have done self?.hideLoadingHUD() instead. I personally prefer getting a strongSelf reference, however, as it ensures self will be around until the end of the closure.

Also, if self doesn’t exist anymore, you bail out a little earlier. This isn’t too significant in this context, where we aren’t doing much in the closure, but it could matter if you were doing calculations or something processor-intensive in the closure.

I’m also fairly lazy: I like solutions that generally work everywhere, and I don’t think about it too much thereafter. :wink:

1 Like

RayWenderlich.com is a great place to start! :]

Check out iOS Tutorials and scroll down to Tools and Libraries.

You can also search cocoapods.org directly. This has a nice rating system too. The more “pie slices” a library has, the higher it’s rated by CocoaPods.

For example, search CocoaPods for Alamofire. Click on the first result in the list, and you’ll see this:

You can also see how they came up with the rating too by clicking on the pie chart.

Lastly, there’s another neat CocoaPods command you can use. Enter this in Terminal:

pod try LibraryName

where you substitute LibraryName with whatever the library’s name is on CocoaPods (e.g. pod try Alamofire).

This will pull down an example project for the library, if it has one. Most popular libraries support this, and it’s a great way to “try out” libraries easily.

1 Like

Uh, that’s awkward… :confused:

If you haven’t already, I’d try cleaning the project (shortcut is CMD+SHIFT+K) and cleaning build folder too (shortcut is OPT+CMD+SHIFT+K). This may or may not work, though… Xcode can be a pain at times, right? :wink:

I don’t have much experience using RxSwift myself, unfortunately.

You might try asking on their Github repo and/or StackOverflow to get expert help.

Good luck! :]

Oh, didn’t think about that ! Nice point, you don’t have to test self each time you use it in the closure then.

Thanks for the explanation :smiley:

Thanks Joshua! It is nice tutorial. I think that Swift is a new perspective in programming!
And we should pop it more. Here is my article on this https://www.cleveroad.com/blog/swift-vs-objective-c--what-is-the-best-language-for-ios-development-
https://www.cleveroad.com/images/article-previews/swift-language-performance.png

First of all it’s an excellent tutorial, very clear.

However, it has me perplexed. I have followed the instructions and successfully added the code as far as Alamofire.request(
and the simulator shows the topping options.
Then I add the code for: showLoadingHUD()
and I don’t see any progress bar, so I assume that perhaps my internet connection is too fast.
I then disable my internet connection from with in System Preferences - Networks and rerun the Xcode App having first cleaned it. This is where is gets weird, the App still runs correctly and show the topping options. So what is happening? Is plist data being cashed somewhere?
If I comment out the body of loadFlavors() then I can succeed in eliminating the topping options.

This tutorial is more than six months old so questions are no longer supported at the moment for it. We will update it as soon as possible. Thank you! :]

@destroplayer I had the same issue with CocoaPods and FBSnapshotTestCase. I used Carthage to integrate the testing framework in my project instead and it worked as expected.

Hope this helps. Thank you! :]