Networking in Swift has been a point of contention since the announcement of the language back in June of 2014. Even Swift’s creator, Chris Lattner, tweeted that decoding JSON is an “ongoing saga”. As a result, many have sought alternatives. Sure, there are built in classes to handle basic JSON parsing, but they are not the more developer-friendly. Fortunately, Alamofire exists. Written by the same creator as its Objective-C counterpart (AFNetworking), Alamofire is a powerful library that helps us decode JSON.
In this holiday-themed 3500+ word monstrosity of a tutorial, we’re going to explore a wide range of topics essential to networking and build a holiday todo list.
In this tutorial, you’ll discover how to use and decode JSON, write a custom server, use tools such as Heroku and MongoLab, how HTTP methods (including GET, POST, and DELETE) work, git, the terminal, and work with cocoa pods. If this sounds like a lot to you, grab a cup of coffee and let’s get started.
Oh, and happy holidays from all of us here at AppCoda. 🙂
NOTE: This is an advanced tutorial and covers a lot of ground – quickly. I assume you have a solid understanding of iOS and Swift. Certain topics such as tableviews, autolayout, delegates, etc will not be explained in depth. If these seem foreign to you, head on yonder to our excellent course and return later.
Getting Started
In order to make this work, I’ve written a backend in the popular server-side technology Node.js. For those unfamiliar with node, it based on javascript’s runtime environment in Google Chrome’s V8 engine. Long story short, it’s incredibly reliable, fast, and powerful.
For this backend, I also included Restify and used MongoDB. MongoDB is a no-SQL database popular among web developers. Using Mongo, we can store all our relevant content in the database.
When I was beginning my dive into Node, I was unsure how everything worked and many of the blogs I visited never explained what was ongoing. As such, although this is an iOS blog, I will introduce you to Javascript and how the Node server works.
I’ve scoured the web and there isn’t a detailed tutorial that walks you through the steps from creating an API to interacting with it in an iOS app. But that’s not true anymore. Enter the Networking tutorial…
Meet node.js
As I previously mentioned, Node js is a powerful server technology built upon Chrome’s running environment. As such, it is highly asynchronous and non blocking (if you’re unsure what this mean, it’s simple a reference to how the main thread, or main part of the app, does not get congested). Multithreading is a programming technology which prevents lag and increases program efficiency. Think of the app as a highway. If there is only one lane and 20 cars need to get through it, then there will likely be traffic or congestion. However, if there are three lanes, each with exists and entrances, then traffic will be much less. Multithreading is much the same way. In a multithreaded environment, code is executed on different threads which prevents congestion to the app and thus prevents it from stalling.
Node was developed by Joyent, a cloud computing company based in San Francisco and is maintained by the company.
If you’re still unsure how everything works, think of the backend as follows:
- It is a place that routes your API (we’re building an API for this app much like any other API on the web, including the popular forecast.io API we used in my previous tvOS tutorial).
- MongoDB gives us a place to store all this data. When we want to post a new message, we need to have a place where that message will be stored. In this scenario, it’s going to be stored to our Mongo database.
- We are creating a fully functional REST API which conforms to the REST protocol, which is how the web runs.
Our MongoDB is hosted on MongoLab and the node server is up on Heroku. Heroku, powered by Salesforce, is popular service for hosting Node, Rails, Python, etc. apps and MongoLab is an excellent service for hosting Mongo databases.
Introduction to HTTP Verbs
Before we begin coding, it is imperative that you understand HTTP verbs and how they will be used in our app.
GET – The GET verb queries our database and retrieves content. GET can be restricted to one, many, or all items. In fact, each and every time you go to google.com or view your Facebook/Twitter feed, you are performing a GET request (and likely not even knowing it)!
POST – The POST verb sends data to the server and then saves it. For example, when you compose a new Facebook or Twitter post and then press the Post/Tweet button, you are creating new content and thus using the POST verb.
UPDATE – The update verb allows you to modify content after the fact. When you edit a Facebook post, the UPDATE verb is being used.
DELETE – As the name implies, this verb calls for the deletion of content. When you press the delete button on a Facebook or Twitter post, this verb is called.
These four verbs are the basis on REST protocol and comprise how much of the internet works. You may also hear the acronym CRUD used interchangeably with these verbs. CRUD stands for Create Read Update and Delete. If it’s not already apparent, these words correspond with POST, GET, UPDATE, and DELETE.
Awesome! Now that we have a solid understanding of the HTTP protocol, we should be ready to jump into the meat of this tutorial and get rolling.
Setting up the Necessary Tools
Before we touch MongoLab or Heroku, let’s make sure you’re all set with Node.js.
Click on this link, follow the brief guide, and download node on your machine.
Then, refer to this page on npm’s website to download npm.
In order to set up our backend, we need to make accounts on both Heroku and MongoLab. Let’s start with MongoLab. Click this link to fire up MongoLab’s website and make an account.
Be sure to select single-node (this is free) and when prompted, fill in a name for your database. I called mine alamofire-db (the db suffix at the end stands for database and this is a common naming convention).
Next login to your database and locate the mongo URI.
You will next need to make a new user by clicking the users tab and select a name and password. Remember the password.
Now return to the page where your mongo URI was and replace it with your new credentials. For example:
1 |
mongodb://<dbuser>:<dbpassword>@ds057954.mongolab.com:57954/alamofire-db |
Became:
1 |
Great progress!
Now go to Heroku.com, signup for free, and return here when ready.
Click this link to install the heroku toolbelt on your mac and follow the guide.
Once installed, power up terminal and select heroku login. If you’ve never used the terminal before, don’t worry. We’ll be using it a lot in this tutorial so you’ll have a solid grasp on how it works by the end.
As soon as you’re logged in to heroku on terminal, use the cd command (which stands for change directory) to move into the project folder you downloaded before from dropbox. cd is the terminal equivalent to moving through folders in finder.
Hit the enter key to execute this command. Great job. Now we’ll be using git to push to heroku.
Enter the following commands in terminal.
NOTE: If you are having difficulty with this step as some have relayed in the comments, please remove the git origin using this:
rm -r .git
1 2 3 |
git init git add . git commit -m "First Commit" |
These three commands inintalzie a repository (repo for short), then add the files to that repository, and finally commit, or saves them.
Git is a popular version control software common to many workfows.
You should now see something like the following:
With the heroku toolbelt installed, type heroku login and enter your heoku login credentials (i.e. email and password). When you type in your password, it will be hidden. Hit enter to continue and if everything’s ok you’ll see your email highlighted in teal.
Now type heroku create to create a new heroku app. Heroku will create a new app for you with a domain. For example, mine is https://whispering-plains-1537.herokuapp.com/.
Now type git push heroku master to send you app to heroku!
If all goes well (which it should), you’ll see something like this (settings will vary).
Working with Node.JS, Express, MongoLab & Mongoose
Let’s begin by downloading the sample project linked here. Fire up your favorite text editor (Sublime Text 2 is mine; it’s available as an unlimited free trial on SublimeText.com, but if you like them support their app and make the purchase) and let’s dive in.
Javascript is very similar to Swift and you should (for the most part) be right at home with it. We’ll be using express and mongoose, two popular node packages. Make sure you have npm, the node package manager installed on your system.
Express, a “fast, unopinionated, minimalist web framework for Node.js” makes routing a breeze. What’s routing, you ask? Routing is the way we interact with the web. Every time you navigate to google.com you’re actually navigating to google.com/, which is the root index. If you were to go to google.com/hello that is another route. We an define routes we want our database to accept as we’ll do in a moment.
You can learn more about express and it’s capabilities from the official expressjs.org website.
Check out this example code:
1 2 3 4 5 6 |
var express = require('express'); // 1 var app = express(); // 2 // respond with "hello world" when a GET request is made to the homepage app.get('/', function(req, res) { // 3 res.send('hello world'); //4 }); |
The first line sets a variable called express. The second initializes a variable called app to express. In the third line we use the app, which represents the express environment. Here we use the get() function (much like in swift). When a user navigates to / (the default of all websites) then “Hello, World ” will appear. This is an example of express routing. For more information, check the express website http://expressjs.com/guide/routing.html
Now that we have our node environment setup with mongo, let’s try using some cURL request to test out its functionality. cURL is a command line program that allows you to send HTTP requests. We will first experiment with cURL and then migrate our cURL requests to AlamoFire.
Intro to JavaScript
Model Directory
Fire up your text editor (I’m using Sublime, by the way) and open the app. Navigate to the app.js file. As you can see, the app is broken down into a model and a routes file (and of course the app.js file you are currently viewing). The model file establishes the schema, or database structure. Let’s take a look at that file briefly.
1 2 3 4 5 6 7 8 9 |
var mongoose = require('mongoose'), Schema = mongoose.Schema; var TodoSchema = new Schema( { name: String }); mongoose.model('employees', TodoSchema); |
We can mongoose, the npm package that interfaces between the app and mongo. I was initially building an employe tracking app and actually called my model employees, but feel free to change this. I just kept it because the rest of the tutorial depends on it (and I caught it at the end)!
Mongoose will interface and connect our heroku node app with mongoLab. How convient.
Routes Directory
The routes file establishes what routes we will export to our app.js file. Don’t worry about exporting — it’s a more advanced feature of node and beyond the scope of this tutorial.
Notice newTodo in line 26. As you might have guessed, this creates a new todo.
1 2 3 4 5 6 7 8 9 |
var emp = new Todo(req.body); emp.save(function(err){ if (err) { res.send('Error occurred'); return console.log(err); } res.send(emp); }); |
We assign the Todo object (define in line 4 which is a connection from mongoose) to a variable called emp, set the req.body (req stands for request which is the data that was sent to us while res stands for response and is what we return).
Feel free to browse the rest of the methods.
Sticky Glue — App.js
Return now to the app.js file. This is the main part of the entire app and holds it all together. Here’s some of the highlights of this file:
- Line 13 establishes the express app
- Lines 15 – 22 configure the app
- In line 33 we connect the app to mongoose and our mongoLab database.
- In line 35 we establish a connection.
- Lines 41 – 45 establish the app routes and connect them to the /routes/todo.js file
- Line 48 creates a server
With that you should have a basic working knowledge of how the javascript app works. As this is not a javascript blog, I will not go further in depth. However, I encourage you to research express and mongoose.
Working with cURL
With our node app up and running, let’s perform some cURL requests to test it out. As soon as we’re done, we can migrate over to Alamofire.
GET Request:
Run the following command in the terminal (feel free to modify the url with your own heroku url).
1 |
curl -i -H "Accept: application/json" "https://rocky-meadow-1164.herokuapp.com/todo" |
The -i and -H are flags, which explain what will be accepted. We will accept json and append the JSON url at the end of the request.
You should see data returned. See the below screenshot.
As you can see, we have some data returned, which is exactly what we want. If you replaced my url with your own, you might not see any data as you probably don’t have anything in your mongo db.
POST Request
If you want to add something to the database, we can run a simple POST command.
1 |
curl -H "Content-Type: application/json" -X POST -d '{"name":"Buy Presents"}' https://rocky-meadow-1164.herokuapp.com/todo |
Now, rerun the GET command from earlier and you should see the “Buy Presents” we added before.
al
DELETE Request
1 |
curl -X DELETE 'https://rocky-meadow-1164.herokuapp.com/todo/5657901fee93910900cc54ed' |
Awesome. We’re not going to discuss PUT since we won’t be using it in our app, but it’s very much the same as the others.
Setting up an iOS app with Alamofire
Let’s get started by creating a new Xcode project called TodoApp. Since the holidays are upon us, we should probably have a way to keep track of things. Luckily, we have our node app to help us out!
While you could install Alamofire manually (by dragging and dropping the files into your project), we’re going to use Cocoapods. Cocoapods is the de facto dependency manager for iOS projects. Using cocoapods, developers can easily add frameworks and third party libraries. It’s an amazing resource and if you haven’t used it yet you most definitely should be using it!
Make sure you have cocoapods installed by running the following command in terminal.
1 |
$ gem install cocoapods |
Now navigate to your project and cd to its location.
Now type the following command
1 |
vim Podfile |
Vim is a command line editor, much like Sublime Text or TextMate although it is built into the command line. We’re going to make a Podfile, which is where cocoapods will look each time it updates the project’s pods (various dependencies).
Hit enter and type:
1 2 3 4 5 6 7 |
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! pod 'Alamofire', '~> 3.0' |
Then press the escape key followed by:
:wq
wq stands for write and quit. We have now created a new file and saved it. To install cocoapods, type
1 |
pod install |
If all goes well, you should see something like the following.
As the command line suggests, you must close your current xcode project, open up the finder window, and now select the .xcworkspace cocoapods generated.
The following handy command will open finder. We’re finally done with terminal…was that enough for one day?
1 |
open . |
Fire up ViewController.swift and let’s get rolling.
Alamofire GET request
Now import Alamofire using
1 |
import Alamofire |
Under viewDidLoad() type the following code
1 2 3 4 5 6 7 8 9 10 |
Alamofire.request(.GET, "https://rocky-meadow-1164.herokuapp.com/todo") .responseJSON { response in // 1 print(response.request) // original URL request print(response.response) // URL response print(response.data) // server data print(response.result) // result of response serialization if let JSON = response.result.value { print("JSON: \(JSON)") } } |
In line 1 we state this will be a GET request and pass in the URL we need. Run the app and see what it returns. If all goes well you’ll see returned JSON.
Now let’s move to our Main.storyboard and add a tableview to the view controller and embed it in a navigation controller. Your storyboard should look like mine below (notice the json returned from our node server in the console).
Copy and paste the following code in your viewcontroller.swift file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import UIKit import Alamofire class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! var jsonArray:NSMutableArray? var newArray: Array<String> = [] override func viewDidLoad() { super.viewDidLoad() Alamofire.request(.GET, "https://rocky-meadow-1164.herokuapp.com/todo") .responseJSON { response in print(response.request) // original URL request print(response.response) // URL response print(response.data) // server data print(response.result) // result of response serialization if let JSON = response.result.value { self.jsonArray = JSON as? NSMutableArray for item in self.jsonArray! { print(item["name"]!) let string = item["name"]! print("String is \(string!)") self.newArray.append(string! as! String) } print("New array is \(self.newArray)") self.tableView.reloadData() } } // Do any additional setup after loading the view, typically from a nib. } } |
I have initialized two arrays and perform a simpe for loop to iterate through the array of items and then assign each returned item to the newArray object.
Using POST cURL requests, I added a few more items to the database. Feel free to do the same.
The GET request can be further simplified to the following code should you chose to do so.
1 |
Alamofire.request(.GET, "https://rocky-meadow-1164.herokuapp.com/todo").responseJSON { response in debugPrint(response) } |
Next, add the UITableViewDelegate and UITableViewDataSource after the UIViewController declaration at the top of the file. Then assign the following code in viewDidLoad()
1 2 |
self.tableView.dataSource = self self.tableView.delegate = self |
Finally, add these UITableView delegate methods
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.newArray.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell cell.textLabel?.text = self.newArray[indexPath.row] return cell } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } |
As you can see, our tableview is populated!
Let’s now add a compose button to add an item to the list. Add a new class called AddViewController to the storyboard and wire it up with a segue. Your storyboard should now look like the following.
Alamofire POST Request
In your AddViewController.swift file create an IBOutlet for the textfield (name it textView) and an IBAction for the Save button. Under the save button, input the following code.
1 2 3 |
Alamofire.request(.POST, "https://rocky-meadow-1164.herokuapp.com/todo", parameters: ["name": self.textView.text!]) self.navigationController!.popViewControllerAnimated(true) |
As you can see, Alamofire dramatically simplifies the process of sending a POST request.
Next, let’s do some refactoring to our ViewController.swift code to ensure it updates after we save another item. Extract and remove your GET Alamofire code from viewDidLoad() and place it in a function called downloadAndUpdate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
func downloadAndUpdate() { Alamofire.request(.GET, "https://rocky-meadow-1164.herokuapp.com/todo") .responseJSON { response in print(response.request) // original URL request print(response.response) // URL response print(response.data) // server data print(response.result) // result of response serialization if let JSON = response.result.value { self.jsonArray = JSON as? NSMutableArray for item in self.jsonArray! { print(item["name"]!) let string = item["name"]! print("String is \(string!)") self.newArray.append(string! as! String) } print("New array is \(self.newArray)") self.tableView.reloadData() } } } |
Now, call the method ViewWillAppear() and call your function inside it.
1 2 3 |
override func viewWillAppear(animated: Bool) { self.downloadAndUpdate() } |
If you build and run the app again and go through the creation process, the app will reload with the new todo each time. But why?
Well, this brings us to a (rather short) discussion on the view controller life cycle. ViewDidLoad() is the function called when the view is instantiated and everything is finished lading. The problem is that when we load another view (the AppViewController class) on top of the already loaded ViewController class, viewDidLoad is not called again (as it was instantiated before). ViewWillAppear, however is called every time a view is shown on screen. Since we are showing ViewController.swift again, this method will work.
Alamofire DELETE Request
Now add the following array under the newArray variable
1 |
var IDArray: Array<String> = [] |
Next, update your downloadAndUpdate function with the following changes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
self.newArray.removeAll() // NEW self.IDArray.removeAll() // NEW Alamofire.request(.GET, "https://rocky-meadow-1164.herokuapp.com/todo") .responseJSON { response in print(response.request) // original URL request print(response.response) // URL response print(response.data) // server data print(response.result) // result of response serialization if let JSON = response.result.value { self.jsonArray = JSON as? NSMutableArray for item in self.jsonArray! { print(item["name"]!) let string = item["name"]! let ID = item["_id"]! // NEW self.newArray.append(string! as! String) self.IDArray.append(ID! as! String) // NEW } print("New array is \(self.newArray)") self.tableView.reloadData() } } |
The two new lines have comments saying NEW. Essentially, we are looping through the array to obtain the ID for each index and store it in the IDArray. We also removed all the old items from the array and reset it.
Now add the commitEditingStyle function to invoke the DELETE request.
1 2 3 4 5 6 7 8 9 10 11 |
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { if editingStyle == .Delete { print("ID is \(self.IDArray[indexPath.row])") Alamofire.request(.DELETE, "https://rocky-meadow-1164.herokuapp.com/todo/\(self.IDArray[indexPath.row])") self.downloadAndUpdate() } else if editingStyle == .Insert { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } |
As you can see, we just conform to our node app’s API which says that a delete request comes through /todo/ID.
Again, this rather simple Alamofire method invokes the DELETE request and then destroys the todo item.
And there you have it, a fully functioning todo app just in time the holidays. Thus concludes our 3500+ word tutorial.
Conclusion
We explored a lot in this tutorial. From Javascript’s Node to express and MongoDB to cURL and terminal to cocoapods and finally Alamofire, we dove into the details of what makes a REST API and how networking works. You should not have a solid grasp on how to:
- Build an API
- Deploy an API
- Write a Client App
- Interact with HTTP Verbs
- Use Cocoapods
- Use cURL
- Interact with Node and the MongoDB/Express environment
- Use Express routes
- Use Alamofire
This has been a monster tutorial and I thank you for sticking it out with me. For your reference, the entire source code can be downloaded here (including the Node app and iOS app).
As always, leave your thoughts in the comments and I’ll pop in to answer questions. Until next time!
Comments
Oskar Larsson
AuthorWhere can I find “project folder you downloaded before from dropbox”. Is there supposed to be downloaded from somewhere on this page or Heroku?
Biranchi Narayan Nayak
AuthorI got the following project created in heroku.
https://dashboard.heroku.com/apps/protected-gorge-3344/
but when i type the below command in terminal, i get the complete html file instead of json response.
curl -i -H “Accept: application/json” “https://dashboard.heroku.com/apps/protected-gorge-3344/todo”
loqalinfo
AuthorWhere is the link to the dropbox folder mentioned in “Setting up the necessary tools” section?
loqalinfo
AuthorIm stuck at the “Setting up Necessary Tools” section. Specifically the push heroku. I am receiving a fatal error reading that I do not have access to the requested url. Any suggestions?
Marko Žél
AuthorDO:
___________
rm -r .git
___________
BEFORE:
__________
git init
git add .
git commit -m ‘Whatever’
Nabeel Munawar
AuthorHi Marko Žél ,
I tried “rm -r .git ” But terminal is stuck for long time..
Actually, I was also getting same error as loqalinfo..
It states “fatal: unable to access ‘https://git.heroku.com/rocky-meadow-1164.git/’: The requested URL returned error: 403”
loqalinfo
Author“Intro to Javascript” Section – do you mean we should be viewing the todo.js file? The code snippet if from that file, not the app.js file.
loqalinfo
AuthorIf you use the project files “appcoda-mongo-todo” from dropbox (which are provided a dropbox folder was referenced in Setting up Necessary Tools), and attempt to [ git push heroic master ] there is a fatal error: unable to access ‘http…./rocky-meadow.1164…’
Any suggestions?
Quang Quoc Tran
AuthorView this link: http://stackoverflow.com/questions/28641851/cannot-push-to-heroku-fatal-unable-to-access-could-not-resolve-host-nil-n
Oskar Larsson
AuthorWhere do you find that drop box folder, I must be blind? I can only see the drop box link under the “Working with Node.JS, Express, MongoLab & Mongoose” section, not under “Setting up Necessary Tools”.
loqalinfo
AuthorYou are not blind but correct. The setting up necessary tools section does not provide the link, but I skimmed ahead and found a dropbox link two sections ahead. I tried to use the project files from this Dropbox folder but I continue to get an error when trying to push to heroku. The error complains I do not have access to the app domain.
Nabeel Munawar
AuthorHi loqalinfo,
I’m also getting same error.. “fatal: unable to access ‘https://git.heroku.com/rocky-meadow-1164.git/’: The requested URL returned error: 403”
Plus I’m also using appcoda-Mongo-todo project from dropbox.. Did you managed to solve it..and push ??
Best
loqalinfo
Authorsee Marko’s response to Gregg’s update comment. You need to remove / delete the git file which is downloaded with the project files. This file is referencing the “…rocky-mountain…” URL which you cannot access. So, delete the git file, then repeat the steps to initialize git in the local repo and you should be able to push to heroku thereafter.
Nabeel Munawar
Author@loqalinfo:disqus
No file with extention “.git” Well can you please write name of file..
Nabeel Munawar
AuthorMore over command “rm-r .git” does not work for me.. Terminal was stuck for 1+ hour when gave rm -r .git command.
Gregg Mojica
AuthorHey guys, gregg here! I realize some people have been having this issue. I will update the tutorial shortly with more detailed steps to fi this, but in short, this is what one of our readers mentioned to me on twitter:
“I renamed, removed git repo, created new one, created heroku and it works.”
cd /the-app-coda-project-you-downloaded-navigate-to-the-right-directory/
rm -r .git
Like I said, I will update the post with more detailed info tomorrow or Thursday, but this should get you on the right track. Sorry for any inconviences!
You can remove a git repo using the following commands:
Marko Žél
AuthorI can confirm. Do rm -r .git before:
___________________________
git init
git add .
git commit -m “First Commit”
___________________________
and it build successfully after
git push heroku master
richard6s
Authorhi I’m havin that problem and I´ve tried with rm -r .git and heruku keys:add but nothing works… I’m kind of desperate…
richard6s
Authorwell so I run git remote rm heroku
then git remote add heroku “the url of your application at heroku”
and the problem I have now it with the nmp version and the projects still rejected but at least it something
tongdengquan
AuthorHey guys,i can’t access to the link https://www.dropbox.com/sh/hvvneknq4hh7ntw/AAARljJGt3OLLjQRmIMxDsIHa?dl=0# in our contry,who can honer sent it to my email [email protected] ,thank you so much
Damian Esteban
AuthorWould you like me to post it on mega?
tongdengquan
Authori get it already,thank you all the same
loqalinfo
Authorto integrate Alamofire to the project, use the instructions from the Alamofire Github repo. The contents for the podfile provided in directions of this tutorial is marked up with HTML.
source ‘https://github.com/CocoaPods/Specs.git’
platform :ios, ‘8.0’
use_frameworks!
pod ‘Alamofire’, ‘~> 3.0’
Gregg Mojica
AuthorThanks. It’s been updated. Something got messed up with the formatting.
Damian Esteban
AuthorNermind.
Faisal
AuthorSome steps are not working i am getting problem here :
As soon as you’re logged in to heroku on terminal, use the cd command (which stands for change directory) to move into the project folder you downloaded before from dropbox. cd is the terminal equivalent to moving through folders in finder
Which Folder downloaded from Drop Box before. i didnt see any dropbox download before these lines please guide me little here.
Regards
Chris Kong
AuthorSo, I downloaded the appcoda-mongo-todo folder from Dropbox. CD the folder to the terminal, logged on Heroku. I have trouble with heroku create command. Getting this error: Error: undefined method `netrc_filename’ for Netrc:Class (NoMethodError)
Command: heroku create
Version: heroku-toolbelt/3.42.24 (x86_64-darwin10.8.0) ruby/1.9.3
What did I do wrong?
Nabeel Munawar
Authorok.. when I do.. “git push heroku master” it works and app is pushed.. But after pushing heroku gives 503(service unavailable) error.. I have used curl to check http requests.. but error 503 (service not available).. What should I do ? is it an issue in App code ? I hope not ? But error occurs only after pushing..
@greggmojica:disqus
sayonsom
Authorhave you been able to figure this out? i have the same problem. Please help.
Damien
AuthorI successfully deployed to Heroku, but the node app did not work. I tried to run it locally, which eventually worked. A little digging revealed that updates to the Mongoose library since this tutorial was made have broken something.
I simply updated the package.json file, replacing “mongoose”: “latest” with “mongoose”: “4.2.8”. Obviously this is not the ideal solution, but the app is deployed to Heroku and working now.
Great tutorial – thanks for sharing!
Nabeel Munawar
Authorreplacing “mongoose”: “latest” with “mongoose”: “4.2.8” really helped. 😉
Damien
AuthorAlso, line 66 of routes/todo.js should read
if(!todo){
zyq
AuthorHey guys,i can’t access to the link https://www.dropbox.com/sh/hvv… in our contry,who can honer sent it to my email [email protected] ,thank you so much
Bruce Elliott
AuthorHey guys, I don’t see the link to “appcoda-mongo-todo” on Dropbox. Can someone share the link please or point me to where it’s located in this tutorial.
Bruce Elliott
AuthorNever mind. I found it here: https://www.dropbox.com/sh/axho3cgfvinz9lc/AADXjhAPwATsbZBA-z9mVLn4a?dl=0
Bruce Elliott
AuthorHey guys, is anyone else getting the following error (see below for error and request) when running the cURL request?
curl -i -H “Accept: application/json “https://quiet-hollows-4340.herokuapp.com/todo”
curl: (6) Could not resolve host: application
HTTP/1.1 503 Service Unavailable
Connection: keep-alive
Server: Cowboy
Date: Mon, 28 Dec 2015 18:19:04 GMT
Content-Length: 484
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache, no-store
html, body, iframe { margin: 0; padding: 0; height: 100%; }
iframe { display: block; width: 100%; border: none; }
Application Error
Application Error
Thomas Richardson
AuthorYup I’m getting this. did you manage to resolve the issue?
Bruce Elliott
AuthorUnfortunately I don’t remember what I did to fix it but I was was something silly. Check to ensure you are logged into the heroku session.
hussnain
AuthorI am getting the same error and a little bit frustrated cause it took me a lot of time in solving push heroku master error. Can you please help with this?
hussnain
AuthorHey Bruce did you manage to solve this problem and how? thankyou
Regi Ellis
AuthorFor anyone interested, I re-wrote the server portion of this tutorial with no dependencies on external services such as MongoLabs and Heroku. This should allow those who would like to focus on the integration between IOS and parsing a JSON data feed with Alamofire.
You can grab a copy from my github account: https://github.com/regiellis/alamofire-todo-server
Bruce Elliott
AuthorHey guys, I am getting the following error when sending the GET request of Alamofire.request(.GET, “https://rocky-meadow-1164.herokuapp.com/todo”):
Optional(周)
String is 周
nil
fatal error: unexpectedly found nil while unwrapping an Optional value
Does anyone else get this error? How did you handle it?
Angel Huaman Rojas
AuthorThe same error for me.
Angel Huaman Rojas
AuthorThe problem is because the name is nil: {“_id”:”568139bdb530e00900e2e916″,”__v”:0}
My solution put bellow “for item in self.jsonArray!”:
if (item[“name”]! != nil) {
print(item[“name”]!)
…
}
Bruce Elliott
AuthorThanks, but still getting the following error message: “Cannot assign to immutable expression of type ‘AnyObject'”
Here is the code that I added….
Added the following code: for item in self.jsonArray! {
if(item[“name”]!!=nil){
print(item[“name”]!)
let string = item[“name”]!
print(“String is (string!)”)
self.newArray.append(string! as! String)
}
}
Bruce Elliott
AuthorYour code helped. Thanks. There is one big omission from the tutorial and that is adding a “Table Cell view” to the tableview in storyboard! For someone who is a new to your tutorials that is a big omission and will cause the app the error out once it starts simulating.
Gregg Mojica
AuthorThanks. I wil update the article. As I mentioned, it’s an advanced tutorial so it’s not designed for those new to iOS or these iOS tutorials in general.
andy
AuthorI just threw it inside an if let
*pretty sure its happening because somebody submitted an empty name.
**you can remove the optional by adding a secondary ! and unwrap it.
if let string = item[“name”]!
{
let ID = item[“_id”]!
print(“String is (string)”)
self.newArray.append(string as! String)
self.IDArray.append(ID! as! String)
}
}
works.
Kody
AuthorIf I try to .GET to your address “”https://rocky-meadow-1164.herokuapp.com/todo”” should that be successful? I get a 404 (I have added “allow arbitrary loads” to my plist)
Jose Galvez
AuthorNice tutorial!
To avoid removing -git directory , just change the remote URL for repo:
git remote set-url –add heroku https://git.heroku.com/limitless-castle-43804.git (change for your app URL)
and remove the original URL:
git remote set-url –delete heroku https://git.heroku.com/rocky-meadow-1164.git
Sad Panda
AuthorThis tutorial is not working.. I have tried everything I can and followed the methods in the comments, but still when accessing the application page I get an “Cannot GET /” error.
Donovan
AuthorA little confused. The tutorial says: N”ow return to the page where your mongo URI was and replace it with your new credentials.” but I don’t see a place to edit or replace the default URI that is on Mongo?
Tony Ricardo
AuthorHey boss, if i want to get a “INT” in the array, not a String, how i can do it ? i mean, i have a JSON that inside the array i have INT value, how i can get it? he call
{
“title”: “The Dark Knight”,
“year”: 2008,
}
i tried
var IDInt: Int = 0
let anos = item[“year”]!
self.IDArray.append(anos! as! Int)
can you help me?
Tony Ricardo
Authorok to get a INT , i did it, thats correct?
var yearArray: Array = []
if let JSON = response.result.value {
self.jsonArray = JSON as? NSMutableArray
for item in self.jsonArray! {
let string = item[“title”]!
let anos = item[“year”]!
self.datas.append(string! as! String)
self.yearArray.append(anos! as! Int)
}
cell.detailTextLabel?.text = “(self.yearArray[indexPath.row])”
vinzo
AuthorMany mistakes in this tutorial, hard to follow.
Gregg Mojica
Authorhey! Could you elaborate? I’m happy to update it and make it clearer if it is not, but I need to know what’s confusing. Keep in mind this is an advanced tutorial and I made that clear in the beginning
Gregg Mojica
AuthorFor those having difficulties with this tutorial:
1). Look at the entire source I linked in the zip file
2). Remote the git remote origin as I detailed
These fixes should address most concerns. As always, drop me a line via email or twitter if you have any other difficulties. I’m happy to assist.
Mike Critchley
AuthorHi there. I’m working through the tutorial and I see that, at least on Safari, I’m not seeing any link to the xCode sample project. Where should I be looking? Or does anybody have a dropbox link to it? Thanks!
Arik Segal
AuthorWhen first pushing the app to Heroku, the remote build failed and rejected the push. I managed to solve it by doing the following:
1.
Install the latest version of npm:
sudo npm install npm@latest -g
2.
Edit package.json and replace the npm version number:
“engines”:{
“node”:”0.8.x”,
“npm”:”3.10.8″
},
3.
Adding the change to the local repo:
git add .
4.
Pushing again. This time it worked.
Lance Hirsch
AuthorThanks, that worked!
Max Kremlev
AuthorThaaaanks!
AshWinee Dhakad
AuthorGreat work !!!
I have a requirement of sending headers with parameters in GET request using Alamofire.
I read Alamofire Documentation but still not able to do that.
Thanks rpsn!!!!
Vatsal Shukla
Authoris Alamofire supports ipv6?
Vatsal Shukla
Authoris Alamofire 4.4.0 version supported to iPv6?
Max Kremlev
AuthorHi, @greggmojica:disqus! Great thanks for tutorial! I get an error during “git push heroku master”! It says
Some possible problems:
– This version of npm (1.1.71) has several known issues – consider upgrading to the latest release (4.5.0)
But I have npm version 4.5.0. At least it says so after “npm -v” command.
Is there anybody with same problem?
JorGe Zevallos
Authorhello everyone,
I have a problem implementing the Alamofire GET request.
when I declare a for like this:
for item in self.jsonArray! {
print(item[“name”]!)
let string = item[“name”]! —–> Error Type ‘Any’ has no subscript members
print(“String is (string!)”)
self.newArray.append(string! as! String)
}
I am quite new in Swift somebody have a idea whats going on there..?
Stas
AuthorI prefer to use Codelobster code editor – https://codelobster.com