如何使用swift 3 for iOS连接到MEAN stack REST api

我试图用iOS创build一个简单的login应用程序,该应用程序使用MEAN堆栈服务器公开REST API以供iOS端连接。

我一直在服务器端工作,并有一个API,允许用户创build一个电子邮件和密码的用户。 我也创build了DELETE和GET请求,按照这个教程: https : //codeforgeek.com/2015/08/restful-api-node-mongodb/

不过,我不确定如何在iOS端login这些信息。 我有几个问题是:

  • 我需要为iOS端创build一个令牌吗?
  • 我需要一个validation方法吗?

我已经包含了我的服务器和我的iOS下面的代码。

我对这两种语言都很陌生,所以任何帮助将不胜感激。 先谢谢你。

app.js

var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var index = require('./routes/index'); var users = require('./routes/users'); var app = express(); app.use( bodyParser.json() ); // to support JSON-encoded bodies app.use(bodyParser.urlencoded({ // to support URL-encoded bodies extended: true })); // view engine setup // all views passed through views app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.get('/javascript/jquery.min.js', function (req, res) { res.sendFile( __dirname + "/javascript" + "/jquery.min.js" ); }); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', index); app.use('/users', users); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); app.post('/', function(req, res) { console.log(req.body); res.send(200); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); //app.use('/',router); module.exports = app; 

index.js

 var express = require('express'); var router = express.Router(); var exec = require('child_process').exec; var util = require('util') var bodyParser = require('body-parser'); var app = express(); //needed to be able to run child_proccess app.get('/javascript/jquery.min.js', function (req, res) { res.sendFile( __dirname + "/javascript" + "/jquery.min.js" ); }); router.get('/', function(req, res){ res.render('index', { title: 'Home' }); }); /** bodyParser.urlencoded(options) * Parses the text as URL encoded data (which is how browsers tend to send form data from regular forms set to POST) * and exposes the resulting object (containing the keys and values) on req.body */ router.use(bodyParser.urlencoded({ extended: true })); /**bodyParser.json(options) * Parses the text as JSON and exposes the resulting object on req.body. */ router.use(bodyParser.json()); router.post('/unLock', function(req, res){ console.log("unlocking"); //print to console when the lock is being operated // console.log(req.body.paramString); //this doesnt work, trying to get the app to print to console exec('ssh pi@192.168.2.2 sudo python /home/pi/unlock.py', (e, stdout, stderr)=> { if (e instanceof Error) { console.error(e); throw e; } }) }); router.post('/Lock', function(req, res){ console.log("locking"); //print to console when the lock is being operated exec('ssh pi@192.168.2.2 sudo python /home/pi/lock.py', (e, stdout, stderr)=> { if (e instanceof Error) { console.error(e); throw e; } }) }); module.exports = router; 

users.js

 var express = require('express'); var router = express.Router(); var mongoOp = require("../model/mongo"); router.route("/") .get(function(req,res){ var response = {}; mongoOp.find({},function(err,data){ // Mongo command to fetch all data from collection. if(err) { response = {"error" : true,"message" : "Error fetching data"}; } else { response = {"error" : false,"message" : data}; } res.json(response); }); }) //create new user .post(function(req,res){ var db = new mongoOp(); var response = {}; // fetch email and password from REST request. // Add strict validation when you use this in Production. db.userEmail = req.body.email; // Hash the password using SHA1 algorithm. db.userPassword = require('crypto') .createHash('sha1') .update(req.body.password) .digest('base64'); db.save(function(err){ // save() will run insert() command of MongoDB. // it will add new data in collection. if(err) { response = {"error" : true,"message" : "Error adding data"}; } else { response = {"error" : false,"message" : "Data added"}; } res.json(response); }); }); //get by id using GET http://localhost:3000/users/id router.route("/:id") .get(function(req,res){ var response = {}; mongoOp.findById(req.params.id,function(err,data){ // This will run Mongo Query to fetch data based on ID. if(err) { response = {"error" : true,"message" : "Error fetching data"}; } else { response = {"error" : false,"message" : data}; } res.json(response); }); }) //update data of a user .put(function(req,res){ var response = {}; // first find out record exists or not // if it does then update the record mongoOp.findById(req.params.id,function(err,data){ if(err) { response = {"error" : true,"message" : "Error fetching data"}; } else { // we got data from Mongo. // change it accordingly. if(req.body.userEmail !== undefined) { // case where email needs to be updated. data.userEmail = req.body.userEmail; } if(req.body.userPassword !== undefined) { // case where password needs to be updated data.userPassword = req.body.userPassword; } // save the data data.save(function(err){ if(err) { response = {"error" : true,"message" : "Error updating data"}; } else { response = {"error" : false,"message" : "Data is updated for "+req.params.id}; } res.json(response); }) } }); }) //DELETE http://localhost:3000/users/id //delete data .delete(function(req,res){ var response = {}; // find the data mongoOp.findById(req.params.id,function(err,data){ if(err) { response = {"error" : true,"message" : "Error fetching data"}; } else { // data exists, remove it. mongoOp.remove({_id : req.params.id},function(err){ if(err) { response = {"error" : true,"message" : "Error deleting data"}; } else { response = {"error" : true,"message" : "Data associated with "+req.params.id+"is deleted"}; } res.json(response); }); } }); }) module.exports = router; 

mongo.js

 var mongoose = require("mongoose"); mongoose.connect('mongodb://localhost:27017/lock'); // create instance of Schema var mongoSchema = mongoose.Schema; // create schema var userSchema = { "userEmail" : String, "userPassword" : String }; // create model if not exists. module.exports = mongoose.model('userLogin',userSchema); 

ViewController.swift这个文件目前要求服务器的IP,并允许一个发出解锁和locking请求,我将在未来添加数据。

我想让这个视图只能通过login到服务器作为一个有效的用户并被呈现。

 import UIKit class ViewController: UIViewController { func presentAlert() { let alertController = UIAlertController(title: "IP?", message: "Please input your unique key:", preferredStyle: .alert) let confirmAction = UIAlertAction(title: "Confirm", style: .default) { (_) in if let field = alertController.textFields?[0] { //this could be lock unique key name etc in future UserDefaults.standard.set(field.text, forKey: "userIP") UserDefaults.standard.synchronize() } else { // user did not fill field - doesnt currently work print("no input given") } } let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in } alertController.addTextField { (textField) in textField.placeholder = "IP" } alertController.addAction(confirmAction) alertController.addAction(cancelAction) self.present(alertController, animated: true, completion: nil) } //view did appear for the alert override func viewDidAppear(_ animated: Bool) { presentAlert() } override func viewDidLoad() { super.viewDidLoad() } var Timestamp: String { return "\(NSDate().timeIntervalSince1970 * 1000)" } func un_lock() { let u = UserDefaults.standard.value(forKey: "userIP")! let url_to_unlock:String = "http://\(u):3000/unLock" print(url_to_unlock) let url:URL = URL(string: url_to_unlock)! let session = URLSession.shared let request = NSMutableURLRequest(url: url) request.httpMethod = "POST" request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData //make this work let paramString = "data=unLocking at \(Timestamp)" request.httpBody = paramString.data(using: String.Encoding.utf8) let task = session.dataTask(with: request as URLRequest, completionHandler: { ( data, response, error) in guard let _:Data = data, let _:URLResponse = response , error == nil else { print("Error comunicating with server, Check IP") return } //for errors let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) print(dataString! ) }) task.resume() } func lock() { let u = UserDefaults.standard.value(forKey: "userIP")! let url_to_lock:String = "http://\(u):3000/Lock" let url:URL = URL(string: url_to_lock)! let session = URLSession.shared let request = NSMutableURLRequest(url: url) request.httpMethod = "POST" request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData //make this work let paramString = "data=Locking at \(Timestamp)" request.httpBody = paramString.data(using: String.Encoding.utf8) let task = session.dataTask(with: request as URLRequest, completionHandler: { ( data, response, error) in guard let _:Data = data, let _:URLResponse = response , error == nil else { print("Error comunicating with server, Check IP") return } //for errors let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) print(dataString! ) }) task.resume() } //button actions @IBAction func Submit(_ sender: UIButton) { } @IBAction func lock(_ sender: UIButton) { lock() } @IBAction func unLock(_ sender: Any) { un_lock() } 

我想知道完全一样的东西。 我从IFTTT的API教程开始,并采取了一个Udemy Node.js课程,所以我开始创build服务器端,为我想开发的iOS应用程序。

我将继续这个post,希望有人会友好地帮助我们。

我确实通过searchfind了本教程,所以我将对此进行调查

https://www.raywenderlich.com/61264/write-ios-app-uses-node-jsmongodb-web-service