iOS client
Basically keep in mind that when you want to hit a local node js server, the address on the network from the iOS cient’s pov is 192.168.1.102.
You go to System Preferences > Wi-Fi (or Ethernet, or whatever you use to get internet connection ). Then on the right hand side, the status should say ‘connected’ and you’ll see something like “Wi-Fi is connected to TP-LINK_3DF056 and has the IP address 192.168.1.102.”
192.168.1.102 is the network address of the computer that’s running the node js server. Hence when iOS clients look for the server, they will need to hit that address.
We are simply trying to hit a url using GET, and expect json data back.
GET for /
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
#pragma mark - ------------- NSURLConnectionDataDelegate ------------- -(void)logUserIn:(OnUserLogInCloud)userLogInBlk; { NSLog(@"logUserIn"); NSString * urlStr = [NSString stringWithFormat:@"http://192.168.1.102:8080/"]; NSURL *url = [NSURL URLWithString:urlStr]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"GET"]; [request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; /* create the connection */ self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; if (self.connection) { self.buffer = [NSMutableData data]; /* initialize the buffer */ [self.connection start]; /* start the request */ self.completed = userLogInBlk; } } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"did fail with error %@", [error debugDescription]); self.completed(nil, nil, nil); } -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"didReceiveResponse - %@, %@", [self debugDescription], [response debugDescription]); [self.buffer setLength:0]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { NSLog(@"%@ - didReceiveData - length of data is: %lu", [self debugDescription], (unsigned long)[data length]); [self.buffer appendData:data]; } -(void)connectionDidFinishLoading:(NSURLConnection *)connection { NSError *error = nil; NSDictionary* json = [NSJSONSerialization JSONObjectWithData: self.buffer options: kNilOptions error: &error]; NSString * msg = [json objectForKey:@"message"]; if(error) { [self showMessageBox:@"error" andMessage:[error localizedDescription] andCancelTitle:@"ok"]; } else { self.completed(self.email, self.auth_token, self.userID); } } |
Notice that we use “message” as the key for our json data because in our node code, we are returning a json object using the key “message”.
Node server
1 2 3 4 |
// route to show a random message (GET http://localhost:8080/api/) app.get('/', function(req, res) { res.json({ message: '(GET http://localhost:8080/)' }); }); |
POST /setup with parameters ‘name’ and ‘password’
iOS client side
So we use NSDictionary to create dictionary object with keys name and password.
Then, we encode it into a NSUTF8StringEncoding string.
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 |
#pragma mark - ------------- LifeCycle ------------- -(instancetype)initWithEmail:(NSString*)email andAuthToken:(NSString*)token andID:(NSString*)newID { if(self=[super init]) { //build an info object and convert to json self.info = [NSDictionary dictionaryWithObjectsAndKeys: @"Shirley Qian", @"name", @"12345678", @"password", nil]; NSError *error = nil; //1st step NSData *jsonInputData = [NSJSONSerialization dataWithJSONObject:self.info options:NSJSONWritingPrettyPrinted error:&error]; //2nd step self.jsonInputString = [[NSString alloc] initWithData:jsonInputData encoding:NSUTF8StringEncoding]; } return self; } |
We then use that dictionary string and set it as Http body using setHTTPBody for the request object. We also set our http method to POST using setHTTPMethod on the request object.
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 |
-(void)logUserIn:(OnUserLogInCloud)userLogInBlk; { NSLog(@"logUserIn"); NSString * urlStr = [NSString stringWithFormat:@"http://192.168.1.102:8080/setup"]; NSURL *url = [NSURL URLWithString:urlStr]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:[self.jsonInputString dataUsingEncoding:NSUTF8StringEncoding]]; /* create the connection */ self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; if (self.connection) { self.buffer = [NSMutableData data]; /* initialize the buffer */ [self.connection start]; /* start the request */ self.completed = userLogInBlk; } } |
1 2 3 4 5 6 7 8 9 |
-(void)connectionDidFinishLoading:(NSURLConnection *)connection { NSError *error = nil; NSDictionary* json = [NSJSONSerialization JSONObjectWithData: self.buffer options: kNilOptions error: &error]; NSString * msg = [json objectForKey:@"success"]; ... ... |
Node server side
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// http://localhost:8080/setup app.post('/setup', function(req, res) { console.log('POST parameter received, name is: ' + req.body.name); // create a sample user var nick = new User({ name: req.body.name, password: req.body.password, //You would protect your passwords by hashing it. admin: true }); // save the sample user nick.save(function(err) { if (err) throw err; console.log('User ' + req.body.name + ' saved successfully...!'); res.json({ success: true }); }); }); |
Checking mongo db via terminal
Open your terminal and type in
mongo
2015-07-05T22:05:14.298+0800 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
> show dbs
PersonDatabase 0.078GB
local 0.078GB
> use PersonDatabase;
switched to db PersonDatabase
> db.user.count()
3
> db.user.find()
the result is that Shirley Qian has been inserted:
{ “_id” : ObjectId(“55973f3702e8b0094967b544”), “name” : “rtsao”, “password” : “compaq”, “admin” : true, “__v” : 0 }
{ “_id” : ObjectId(“55977f4b06112d75860f9af6”), “name” : “rtsao6680”, “password” : “abcde12345”, “admin” : true, “__v” : 0 }
{ “_id” : ObjectId(“5599cc4ec1fa2c05496b5c34”), “name” : “Shirley Qian”, “password” : “12345678”, “admin” : true, “__v” : 0 }
>
Full server code
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
// ======================= // get the packages we need ============ // ======================= var express = require('express'); var app = express(); var bodyParser = require('body-parser'); var morgan = require('morgan'); var mongoose = require('mongoose'); var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens var config = require('./config'); // get our config file var User = require('./models/user'); // get our mongoose model // ======================= // configuration ========= // ======================= var port = 8080; // used to create, sign, and verify tokens mongoose.connect(config.database); // connect to database var db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function (callback) { // yay! console.log('mongoose db connected'); }); //app.set(name, value) //Assigns setting name to application setting : value, //where name is one of the properties from the app.set('superSecret', config.secret); // secret variable // use body parser so we can get info from POST and/or URL parameters app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); // use morgan to log requests to the console app.use(morgan('dev')); // API ROUTES ------------------- // get an instance of the router for api routes var apiRoutes = express.Router(); // route to authenticate a user (POST http://localhost:8080/api/authenticate) apiRoutes.post('/authenticate', function(req, res) { console.log('name value: ' + req.body.name); console.log('password value: ' + req.body.password); //User is model object made by mongoose // mongoose's findOne function to find the user User.findOne({ name: req.body.name }, function(err, user) { if (err) throw err; if (!user) { res.json({ success: false, message: 'Authentication failed. User not found.' }); } else if (user) { //user with that name is returned...we just have to check if the pwds match // check if password matches if (user.password != req.body.password) { res.json({ success: false, message: 'Authentication failed. Wrong password.' }); } else { console.log('user found, and password is correct'); // if user is found and password is right // create a token, jsonwebtoken to create the token. var token = jwt.sign(user, app.get('superSecret'), { expiresInMinutes: 1440 // expires in 24 hours }); // return the information including token as JSON res.json({ success: true, message: 'Enjoy your token!', token: token }); } } }); }); // route middleware to verify a token apiRoutes.use(function(req, res, next) { console.log('------apiRoutes.use function------------'); //X-ACCESS-TOKEN is the key, we need to give it value of token //so it can authenticate us console.log("req.body.token: " + req.body.token); console.log("req.query.token: " + req.query.token); console.log("req.headers[x-access-token]: " + req.headers['x-access-token']); // check header or url parameters or post parameters for token var token = req.body.token || req.query.token || req.headers['x-access-token']; // decode token if (token) { // verifies secret and checks exp jwt.verify(token, app.get('superSecret'), function(err, decoded) { if (err) { return res.json({ success: false, message: 'Failed to authenticate token.' }); } else { // if everything is good, save to request for use in other routes req.decoded = decoded; next(); } }); } else { // if there is no token // return an error return res.status(403).send({ success: false, message: 'No token provided.' }); } }); // route to return all users (GET http://localhost:8080/api/users) apiRoutes.get('/users', function(req, res) { console.log('(GET http://localhost:8080/api/users)'); User.find({}, function(err, users) { res.json(users); }); }); // apply the routes to our application with the prefix /api app.use('/api', apiRoutes); // http://localhost:8080/setup //app.get('/setup', function(req, res) { app.post('/setup', function(req, res) { console.log('POST parameter received, name is: ' + req.body.name); // create a sample user var nick = new User({ name: req.body.name, password: req.body.password, //You would protect your passwords by hashing it. admin: true }); // save the sample user nick.save(function(err) { if (err) throw err; console.log('User ' + req.body.name + ' saved successfully...!'); res.json({ success: true }); }); }); // route to show a random message (GET http://localhost:8080/api/) app.get('/', function(req, res) { res.json({ message: '(GET http://localhost:8080/)' }); }); // ======================= // start the server ====== // ======================= app.listen(port); console.log('Magic happens at http://localhost:' + port); |