xml地图|网站地图|网站标签 [设为首页] [加入收藏]
WebAPI设置路由和参数2,相关语法进阶
分类:编程

//

1.上面已经教大家如何修改全局路由了,那么修改完后我们在post请求的要这样使用,其中model模型我就默认你应该已经建好了,没有创建的话请看上一部分

  初学Swift没几天,就试着自己写了一个城市选择器,纯Swift代码。

//  main.swift

Post方法的参数,如果提交的请求体需要是phoneNum=123&password=123这样的格式。如果用string AddNew(string phoneNum, string password)这种普通参数会有很多的坑(参考《C#进阶系列—— WebApi 接口参数不再困惑:传参详解》),所以不要用。都用模型对象,public string AddNew2(LoginModel model),也可以参数标注[FromBody]:public string AddNew2([FromBody]LoginModel model)。(只能有一个参数标注FromBody)。

 

//  Swift_Other

图片 1图片 2

  ViewController.Swift文件中:

//

[HttpPost]
        public bool Login4(LoginModel model)//也可以参数标注[FromBody]LoginModel model
        {
            if (model.phoneNum == "123" && model.password == "123")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
//
//  ViewController.Swift
//  Swift demo - UIPickerView之城市选择器
//
//  Created by 柯其谱 on 17/3/11.
//  Copyright © 2017年 柯其谱. All rights reserved.
//

import UIKit

//MARK: View life cycle
class ViewController: UIViewController {

    /** 懒加载的城市数据源数组 */
    fileprivate lazy var cCityDataArray: [StateModel] = {
        //Plist文件路径
        let path = Bundle.main.path(forResource: "area", ofType: "plist")
        var areas: NSArray? = nil
        //读取Plist文件数组
        if let arrayPath = path {
            areas = NSArray (contentsOfFile: arrayPath)
        }
        //数组转换为模型数组
        var cityData = Array<StateModel>()
        if let areasArr = areas {
            for area in areasArr {
                let areaDic = area as! NSDictionary
                let stateModel = StateModel.init(dictionary: areaDic)
                cityData.append(stateModel)
            }
        }
        return cityData
    }()

    /** 省级数据源数组 */
    fileprivate var cStatesArr: [StateModel]? = nil
    /** 市级数据源数组 */
    fileprivate var cCitiesArr: [CityModel]? = nil
    /** 区级数据源数组 */
    fileprivate var cAreasArr: [String]? = nil
    /** 选择城市的textField */
    fileprivate let cCityTextField: UITextField? = UITextField()
    /** 选择城市的pickerView */
    fileprivate let cCityPickerView: UIPickerView? = UIPickerView()
    /** 选择城市的toolBar */
    fileprivate let cCityToolBar: UIToolbar? = UIToolbar()
    /** 选择城市的背景蒙版 */
    fileprivate let cTextFieldCoverButton: UIButton = UIButton (frame: UIScreen.main.bounds)

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = UIColor(red:0.85, green:0.85, blue:0.85, alpha:1.00)
        self.setupSubviews()
        //设置数据源数组初始值
        cStatesArr = cCityDataArray
        cCitiesArr = cStatesArr?.first?.cities
        cAreasArr = cCitiesArr?.first?.areas
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

//MARK: Setup
extension ViewController {
    /** 设置subviews */
    fileprivate func setupSubviews() -> Void {
        self.setupTextField()
        self.setupCoverButton()
        self.setupPickerView()
        self.setupToolBar()
    }

    /** 设置textField */
    private func setupTextField() -> Void {
        if let cityTextField = cCityTextField {
            cityTextField.frame = CGRect (x: 50, y: 200, width: 200, height: 44)
            cityTextField.delegate = self
            cityTextField.backgroundColor = UIColor.white
            cityTextField.placeholder = "请选择城市"
            cityTextField.borderStyle = UITextBorderStyle.roundedRect
            self.view.addSubview(cityTextField)
        }
    }

    /** 设置背景蒙版Button */
    private func setupCoverButton() -> Void {
        cTextFieldCoverButton.addTarget(self, action: #selector(clickTextFieldCoverButton(sender:)), for: UIControlEvents.touchUpInside)
        self.view.addSubview(cTextFieldCoverButton)
        cTextFieldCoverButton.isHidden = true
    }

    /** 设置pickerView */
    private func setupPickerView() -> Void {
        if let cityPickerView = cCityPickerView {
            cityPickerView.delegate = self
            cityPickerView.dataSource = self
            cCityTextField!.inputView = cityPickerView
        }
    }

    /** 设置toolBar */
    private func setupToolBar() -> Void {
        if let cityToolBar = cCityToolBar {
            cityToolBar.frame = CGRect (x: 0, y: 0, width: 0, height: 44)
            cityToolBar.backgroundColor = UIColor.white

            let cancelItem = UIBarButtonItem.init(title: "取消", style: UIBarButtonItemStyle.done, target: self, action: #selector(clickToolBarCancelItem(sender:)))
            let spaceItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
            let doneItem = UIBarButtonItem.init(title: "确定", style: UIBarButtonItemStyle.done, target: self, action: #selector(clickToolBarDoneItem(sender:)))
            cityToolBar.items = [cancelItem, spaceItem, doneItem]
            cCityTextField?.inputAccessoryView = cityToolBar
        }
    }
}

//MARK: UITextFieldDelegate
extension ViewController: UITextFieldDelegate {

    func textFieldDidBeginEditing(_ textField: UITextField) {
        cTextFieldCoverButton.isHidden = false
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        cTextFieldCoverButton.isHidden = true
    }
}

//MARK: UIPickerViewDelegate 
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 3
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        switch component {
        case 0:
            return cStatesArr!.count
        case 1:
            return cCitiesArr!.count
        case 2:
            return cAreasArr!.count
        default:
            return 0
        }
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        switch component {
        case 0:
            return cStatesArr![row].state
        case 1:
            return cCitiesArr![row].city
        case 2:
            return cAreasArr![row]
        default:
            return nil
        }
    }

    func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        return self.view.frame.width / 3
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        switch component {
        case 0:
            //保存市级数据源数组
            cCitiesArr = cCityDataArray[row].cities
            //若有区级数据,则保存区级数据源数组
            if cCitiesArr?.first?.areas != nil {
                cAreasArr = cCitiesArr?.first?.areas
            }

            //重新加载第1、2组
            pickerView.reloadComponent(1)
            pickerView.reloadComponent(2)

            //默认选中第1、2组的第1行数据
            pickerView.selectRow(0, inComponent: 1, animated: true)
            pickerView.selectRow(0, inComponent: 2, animated: true)
        case 1:
            //保存区级数据源数组
            if cCitiesArr![row].areas.count != 0 {
                cAreasArr = cCitiesArr![row].areas
            }

            //重新加载第2组数据
            pickerView.reloadComponent(2)

            //默认选中第2组第1行数据
            pickerView.selectRow(0, inComponent: 2, animated: true)
        default:
            return
        }
    }
}

//MARK: Event response
extension ViewController {
    @objc fileprivate func clickTextFieldCoverButton(sender: UIButton) -> Void {
        cCityTextField?.resignFirstResponder()
    }

    @objc fileprivate func clickToolBarCancelItem(sender: UIBarButtonItem) -> Void {
        cCityTextField?.resignFirstResponder()
    }

    @objc fileprivate func clickToolBarDoneItem(sender: UIBarButtonItem) -> Void {
        cCityTextField?.resignFirstResponder()
        let selectedState = cCityPickerView?.selectedRow(inComponent: 0)
        let selectedCity = cCityPickerView?.selectedRow(inComponent: 1)
        let selectedArea = cCityPickerView?.selectedRow(inComponent: 2)
        var cityString = (cStatesArr?[selectedState!].state)! + (cCitiesArr?[selectedCity!].city)!
        if cAreasArr?.count != 0 {
            cityString += (cAreasArr?[selectedArea!])!
        }
        cCityTextField?.text = cityString
    }
}

//  Created by 齐彦坤 on 2017/7/21.

View Code

 

//  Copyright © 2017年 KG. All rights reserved.

图片 3

  StateModel.swfit文件中,用于保存省级数据:

//

2.通过自定义路由规则来捕获参数

//
//  StateModel.Swift
//  Swift demo - UIPickerView之城市选择器
//
//  Created by 柯其谱 on 17/3/11.
//  Copyright © 2017年 柯其谱. All rights reserved.
//

import UIKit

/** 省级Model */
class StateModel: NSObject {

    /** 省下级所有城市 */
    let cities: Array<CityModel>

    /** 省级名称 */
    let state: String

    init(dictionary: NSDictionary) {
        state = dictionary["state"] as! String
        let citiesArr = dictionary["cities"] as! NSArray
        var citiesMutableArr = Array<CityModel>()
        for city in citiesArr {
            let cityDic = city as! NSDictionary
            let cityModel = CityModel.init(dictionary: cityDic)
            citiesMutableArr.append(cityModel)
        }
        cities = citiesMutableArr
    }
}

 

WebAPI可以通过[Route]和[RoutePrefix]来自定义路由,[RoutePrefix]作用于Controller,[Route]作 用于Action,一旦一个Controller或者Action设置了[Route]、[RoutePrefix]那么设置的routeTemplate讲在 这个Controller或者Action中就不起作用了。

 

// 2.3 与 3.0 迁移对比

(1)[Route]自定义路由

CityModel.Swift文件中,用于保存市级数据

import Foundation

图片 4图片 5

//
//  CityModel.Swift
//  Swift demo - UIPickerView之城市选择器
//
//  Created by 柯其谱 on 17/3/11.
//  Copyright © 2017年 柯其谱. All rights reserved.
//

import UIKit

//MARK: 城市Model
class CityModel: NSObject {

    /** 城市下级area */
    let areas: Array<String>
    /** 城市名 */
    let city: String

    init(dictionary: NSDictionary){
        city = dictionary["city"] as! String
        let areasArr = dictionary["areas"] as! NSArray
        var areasMutableArr = Array<String>()
        for area in areasArr {
            let areaString = area as! String
            areasMutableArr.append(areaString)
        }
        areas = areasMutableArr
    }

}

 

[Route("Login/{phoneNum}/{password}")]
        [HttpGet]
        public string Login5(string phoneNum, string password)
        {
            return string.Format("Login5-->phoneNum:{0},password:{1}", phoneNum, password);
        }

 

// Swift 与 Objective-C 中的 nil

View Code

 

// Swift 使用 nil 代表 <#值缺失#>

图片 6

// Swift 中 nil与 Objective-C 中的 nil 完全不同, 在 Objective-C 中, nil 代表一个并不次混在的指针对象, 而在 Swift 中并不代表指针而是一个确定的值-------他是一个确定的值, 用于代表"值缺失", 任何 <#可选类型#> 的变量都可以呗赋值为 nil, 如 Int?, Double? 等都可以接受 nil 值.

(2)每个方法都[Route]自定义太麻烦,[RoutePrefix]作用于Controller适用内部所有方法

//  can not recieve nil

图片 7图片 8

// Var age: Int = nil

//当然每个Action都设定api/Login很麻烦,可以在Controller上标注[RoutePrefix("api/Login")](路径不能以/结尾)
    [RoutePrefix("api/Login")]
    public class LoginController : ApiController
    {
        [HttpGet]
        public string LoginAction(string phoneNum, string password)
        {
            return string.Format("Login-->phoneNum:{0},password:{1}", phoneNum, password);
        }
    }

// Int? 类型的才可以接受 nil

View Code

// var age: Int? = nil

 图片 9

// var myName : String?

 

// print(myName ?? "")

总结:

 

1.如果使用 Post 请求,那么就需要每个方法都声明一个参数对应的类,参数前可标注[FromBody]。

var name_prefix = "123456"

2.如果使用 Get 请求,那么参数比较自由,但是需要注意防范缓存(使用 ajax 的话加上一个当前时间或者 随机数的参数,使用 HttpClient 等需要禁用缓存)。

var info = name_prefix + "789"

3.如果用 Get 方式,参数既可以用普通参数也可以用模型类参数,需要注意防止缓存;如 果 用 Post 方 式 , 参 数 一 定 要 用 模 型 类 , 客 户 端 既 可 以 用 ContentType=” application/x-www-form-urlencoded”提交表单,也可以用 ContentType=”application/json”提交。

print(info)

4.路由设置的话根据项目情况设置,适合的才是好的,切记不要搞得太乱。

name_prefix.removeAll(keepingCapacity: false) // storge and string -- > falses (released) /  true (NoReleased)

 

 

var diamond : Character = "u{2666}"

var heart : Character = "u{2663}"

var club : Character = "u{2665}"

var spade : Character = "u{2660}"

print("(diamond) (heart) (club) (spade)") // ♦ ♣ ♥ ♠

 

// n -- u{a}

 

 

// 7.6 属性观察者

// willSet(newValue): 被观察的属性即将被赋值之前自动调用该方法

// didSet(oldValue):  被观察的属性即将被赋值完成之后自动调用该方法

// 只要程序对非延迟存储的存储属性赋值 --- 即使所赋的值与原值相等, 属性观察者也能监听到

 

// 属性观察者监听的范围

// 1. 除了延迟属性之外的所有存储属性

// 2. 可以通过重载的方式为继承得到的属性添加属性观察者

// 3. 普通的属性添加属性观察者是没有意义的

/*

// 格式如下

[修饰符] var 存储属性名: 属性类型 [= 初始值]

{

    willSet

    {

        // 属性即将赋值之前的代码

    }

    didSet

    {

        // 赋值完成之后的代码

    }

}

*/

 

class Person

{

    var name : String = ""

    {

        willSet

        {

            if (name as NSString).length > 6 || (name as NSString).length < 2

            {

                print("no")

            }else{

                print("yes")

            }

        }

        

        didSet

        {

            print("didSetName: (name)")

        }

    }

}

 

var p = Person()

p.name = "小黄人"

print("p.name = (p.name)")

 

// 7.7.6 属性和方法的统一

// 全局函数

func factorial(n:Int) -> Int

{

    var result = 1

    for idx in 1...n {

        result *= idx

    }

    return result

}

 

struct SomeStruct

{

    // 将一个布闭包函数作为 info 存储属性的初始值

    var info:() -> Void = {

        print("info 方法")

    }

    // factorial全局函数作为 fact 存储属性的初始值

    static var fact:(Int) -> Int = factorial

}

var sc = SomeStruct()

sc.info()

sc.info = {

    print("另外一个闭包")

}

sc.info()

var n =  6

print("(n)的阶乘: (SomeStruct.fact(6))")

 

// 7.8 下标

/*

subscript(形参列表) -> 下表返回值

{

    get

    {

        // getter 执行部分, 必须有返回值

    }

    

    set

    {

        // setter 部分执行代码, 该部分不一定有返回值

    }

}

*/

 

struct FKRect

{

    var x : Int

    var y : Int

    var width : Int

    var height : Int

    subscript(idx : Int) -> Int

    {

        get

        {

            switch(idx)

            {

                case 0:

                    return self.x

                case 1:

                    return self.y

                case 2:

                    return self.width

                case 3:

                    return self.height

                default:

                    print("unSupport type")

                    return 0

            }

        }

        

        set

        {

            switch(idx)

            {

                case 0:

                    self.x = newValue

                case 1:

                    self.y = newValue

                case 2:

                    self.width = newValue

                case 3:

                    self.height = newValue

                default:

                    print("unSupport type")

            }

 

        }

    }

}

 

var rect = FKRect(x: 20, y: 12, width: 200, height: 300)

// 通过下表对 rect 的属性赋值

rect[0] = 40

rect[1] = 67

print("rect 的 x 的坐标为: (rect[0]), y 的坐标为 (rect[1])")

 

// 7.9 可选链

 

class Company

{

    var name = "crazy"

    var addr = "home"

    init(name : String, addr : String)

    {

        self.name = name

        self.addr = addr

    }

}

 

class Employee

{

    var name = " 白骨精"

    var title = "销售客服"

    var company : Company!

    init(name : String, title : String)

    {

        self.name = name

        self.title = title

    }

}

 

class Customer

{

    var name = ""

    var emp : Employee?

    // "_" 取消构造器参数的外部形参名

    init(_ name : String)

    {

        self.name = name

    }

    

}

 

var  c3 = Customer("唐僧")

//print("为(c3.name)服务的公司: (String(describing: c3.emp!.company?.name))") // fatal error: unexpectedly found nil while unwrapping an Optional value

print("为(c3.name)服务的公司: (String(describing: c3.emp?.company?.name))") // fatal error: unexpectedly found nil while unwrapping an Optional value

 

// 7.11.4 使用闭包后函数为属性设置初始值

// 用于作为存储属性初始值的函数或闭包的返回值类型需要与该属性的类型匹配

struct closurenit

{

    var test : Int = {

        return 6

    }()

}

var ci = closurenit()

print(ci.test)

 

// 构造器

// 对于值类型, Swift 允许使用 self,init(实参)在自定义在构造器中调用其他重载的构造器, 而且只允许在构造器内部使用self.init(实参)

struct Apple

{

    var name : String

    var color : String

    var weight : String!

    

    init(_ name : String, color  : String)

    {

        self.name = name

        self.color = color

    }

    

    init(name : String, color : String)

    {

//        name = "trmp" // 执行 self.init 之前, 不允许对人如何实例睡醒赋值, 也不允许访问任何任何实例属性, 不被允许使用 self. 而一个构造器中只能有一行 self.init(实参)

        self.init(name, color: color)

    }

    

    init(name : String, color : String, weight : String)

    {

        self.init(name, color: color) // 构造器代理 --> 在构造器中调用其他构造器来执行构造的过程被称为构造器代理

        self.weight = weight

    }

}

 

var ap1 = Apple("红富士", color: "粉红色")

var ap2 = Apple(name: "青苹果", color: "绿色")

var ap3 = Apple(name: "红苹果", color: "红色", weight: "1.0 kg")

 

// 8.2 类的构造

// 8.2.1 便利构造器

// 定义便利构造器需要早 init 前添加 convenience

// convenience init(形参) {  }

// 只有类中才有构造器的概念, 结构体 / 枚举 不支持便利构造器

class Apple_one

{

    var name : String!

    var weight : Double

    // 定义指定构造器

    init(name : String, weight : Double) {

        self.name = name

        self.weight = weight

    }

    // 定义便利构造器

    convenience init(n name : String, w  weight  : Double)

    {

        self.init(name : name, weight : weight)

本文由澳门新葡亰手机版发布于编程,转载请注明出处:WebAPI设置路由和参数2,相关语法进阶

上一篇:没有了 下一篇:没有了
猜你喜欢
热门排行
精彩图文