日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

swift通知栏推送_如何使用Swift使用推送通知构建食品交付应用

發(fā)布時間:2023/11/29 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 swift通知栏推送_如何使用Swift使用推送通知构建食品交付应用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

swift通知欄推送

by Neo Ighodaro

由新Ighodaro

如何使用Swift使用推送通知構(gòu)建食品交付應(yīng)用 (How to build a food delivery app with push notifications using Swift)

A basic understanding of Swift and Node.js is needed to follow this tutorial.

要學(xué)習(xí)本教程,需要對Swift和Node.js有基本的了解。

Last mile delivery marketplaces make it easy to order food from a mobile device and have it delivered to a user’s door while it’s still hot.

最后一英里的運送市場使從移動設(shè)備訂購食物變得很容易,并且可以在仍然很熱的時候?qū)⑹澄镞\送到用戶家中。

Marketplaces like Deliveroo, Postmates, or Uber Eats use your device’s location to serve you a list of restaurants that are close enough to you (and open) so you can get your delivery as soon as possible.

像Deliveroo,Postmates或Uber Eats這樣的市場都使用您設(shè)備的位置為您提供了一個距離您足夠近(開著)的餐館列表,因此您可以盡快獲得送貨。

This realtime experience between the customer, restaurant, and driver relies on transactional push notifications to move the order from the kitchen to the table seamlessly. Customers want push notifications to alert them when their order is on its way and when they need to meet the driver at the door.

客戶,餐廳和駕駛員之間的這種實時體驗依賴于交易推送通知,以將訂單從廚房無縫地轉(zhuǎn)移到桌子上。 客戶希望推送通知在他們的訂單即將到來時以及何時需要在門口與駕駛員見面時向他們發(fā)出警報。

Setting up push notifications can be confusing and time consuming. However, with Pusher’s Push Notifications API, the process is a lot easier and faster.

設(shè)置推送通知可能會造成混亂和耗時。 但是,使用Pusher的Push Notifications API ,此過程變得更加輕松快捷。

In this article, we will be considering how you can build apps on iOS that have transactional push notifications. For this, we will be building a make-believe food delivery app.

在本文中,我們將考慮如何在具有事務(wù)性推送通知的iOS上構(gòu)建應(yīng)用程序。 為此,我們將構(gòu)建一個虛構(gòu)的外賣應(yīng)用程序。

先決條件 (Prerequisites)

  • A Mac with Xcode installed. Download Xcode here.

    裝有Xcode的Mac。 在此處下載Xcode 。

  • Knowledge of using Xcode.

    了解使用Xcode的知識。
  • Knowledge of Swift.

    了解Swift 。

  • A Pusher account. Create one here.

    Pusher帳戶。 在此處創(chuàng)建一個 。

  • Basic knowledge of JavaScript/Node.js (Check out this tutorial).

    JavaScript / Node.js的基礎(chǔ)知識( 請參閱本教程 )。

  • Cocoapods installed on your machine.

    您的機器上已安裝了 Cocoapods。

Once you have the requirements, let’s start.

有了需求后,就開始吧。

構(gòu)建我們的應(yīng)用程序-規(guī)劃 (Building our application — planning)

Before we start building our application, we need to do some planning on how we want the application to work.

在開始構(gòu)建應(yīng)用程序之前,我們需要對我們希望應(yīng)用程序的工作方式進(jìn)行一些規(guī)劃。

We will be making three applications:

我們將提出三個申請:

  • The backend application (Web using Node.js).

    后端應(yīng)用程序(使用Node.js的Web)。
  • The client application (iOS using Swift).

    客戶端應(yīng)用程序(使用Swift的iOS)。
  • The admin application (iOS using Swift).

    管理應(yīng)用程序(使用Swift的iOS)。

后端應(yīng)用 (The backend application)

This will be the API. For simplicity, we will not add any sort of authentication to the API. We will be calling the API from our iOS applications. The API should be able to provide the food inventory, the orders, and also manage the orders. We will also be sending push notifications from the backend application.

這將是API。 為簡單起見,我們不會向API添加任何形式的身份驗證。 我們將從iOS應(yīng)用程序中調(diào)用API。 該API應(yīng)該能夠提供食品庫存,訂單以及管理訂單。 我們還將從后端應(yīng)用程序發(fā)送推送通知。

客戶端應(yīng)用 (The client application)

This will be the application that will be with the customer. It’s where the user will be able to order food. For simplicity, we will not have any sort of authentication, and everything will be straight to the point. A customer should be able to see the inventory and order one or more things from that inventory. They should also be able to see the list of their orders and the status of each order.

這將是與客戶一起使用的應(yīng)用程序。 用戶可以在這里訂購食物。 為簡單起見,我們將沒有任何形式的身份驗證,并且所有內(nèi)容都直截了當(dāng)。 客戶應(yīng)該能夠看到庫存并從該庫存中訂購一件或多件東西。 他們還應(yīng)該能夠看到他們的訂單列表以及每個訂單的狀態(tài)。

管理員應(yīng)用程序 (The admin application)

This will be the application that the company providing the service will use to fulfill orders. The application will display the available orders, and the admin will be able to set the status for each order.

這將是提供服務(wù)的公司用于履行訂單的應(yīng)用程序。 該應(yīng)用程序?qū)@示可用的訂單,管理員將能夠設(shè)置每個訂單的狀態(tài)。

構(gòu)建后端應(yīng)用程序(API) (Building the backend application (API))

The first thing we want to build is the API. We will be adding everything required to support our iOS applications, and will then add push notifications later on.

我們要構(gòu)建的第一件事是API。 我們將添加支持我們的iOS應(yīng)用程序所需的所有內(nèi)容,然后在以后添加推送通知。

To get started, create a project directory for the API. In the directory, create a new file called package.json. In the file, paste the following:

首先,為API創(chuàng)建一個項目目錄。 在目錄中,創(chuàng)建一個名為package.json的新文件。 在文件中,粘貼以下內(nèi)容:

{ "main": "index.js", "scripts": {}, "dependencies": { "body-parser": "^1.18.2", "express": "^4.16.2" } }

Next run the command below in your terminal:

接下來在您的終端中運行以下命令:

$ npm install

This will install all the listed dependencies. Next, create an index.js file in the same directory as the package.json file and paste in the following code:

這將安裝所有列出的依賴項。 接下來,在與package.json文件相同的目錄中創(chuàng)建一個index.js文件,并粘貼以下代碼:

// -------------------------------------------------------- // Pull in the libraries // -------------------------------------------------------- const app = require('express')() const bodyParser = require('body-parser') // -------------------------------------------------------- // Helpers // -------------------------------------------------------- function uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } // -------------------------------------------------------- // In-memory database // -------------------------------------------------------- var user_id = null var orders = [] let inventory = [ { id: uuidv4(), name: "Pizza Margherita", description: "Features tomatoes, sliced mozzarella, basil, and extra virgin olive oil.", amount: 39.99, image: 'pizza1' }, { id: uuidv4(), name: "Bacon cheese fry", description: "Features tomatoes, bacon, cheese, basil and oil", amount: 29.99, image: 'pizza2' } ] // -------------------------------------------------------- // Express Middlewares // -------------------------------------------------------- app.use(bodyParser.json()) app.use(bodyParser.urlencoded({extended: false})) // -------------------------------------------------------- // Routes // -------------------------------------------------------- app.get('/orders', (req, res) => res.json(orders)) app.post('/orders', (req, res) => { let id = uuidv4() user_id = req.body.user_id let pizza = inventory.find(item => item["id"] === req.body.pizza_id) if (!pizza) { return res.json({status: false}) } orders.unshift({id, user_id, pizza, status: "Pending"}) res.json({status: true}) }) app.put('/orders/:id', (req, res) => { let order = orders.find(order => order["id"] === req.params.id) if ( ! order) { return res.json({status: false}) } orders[orders.indexOf(order)]["status"] = req.body.status return res.json({status: true}) }) app.get('/inventory', (req, res) => res.json(inventory)) app.get('/', (req, res) => res.json({status: "success"})) // -------------------------------------------------------- // Serve application // -------------------------------------------------------- app.listen(4000, _ => console.log('App listening on port 4000!'))

The above code is a simple Express application. Everything is self-explanatory and has comments to guide you.

上面的代碼是一個簡單的Express應(yīng)用程序。 一切都是不言自明的,并有注釋可以指導(dǎo)您。

In the first route, /orders, we display the list of orders available from the in-memory data store. In the second route, POST /orders, we just add a new order to the list of orders. In the third route, PUT /orders/:id, we just modify the status of a single order from the list of orders. In the fourth route, GET /inventory, we list the inventory available from the list of inventory in the database.

在第一個路線/orders ,我們顯示內(nèi)存數(shù)據(jù)存儲中可用的訂單列表。 在第二條路線POST /orders ,我們只是將新訂單添加到orders列表中。 在第三條路線PUT /orders/:id ,我們只是從orders列表中修改單個訂單的狀態(tài)。 在第四條路線GET /inventory ,我們從數(shù)據(jù)庫中的清單列表中列出可用inventory 。

We are done with the API for now, and we will revisit it when we need to add the push notification code. If you want to test that the API is working, then run the following command on your terminal:

目前,我們已經(jīng)完成了API的使用,當(dāng)我們需要添加推送通知代碼時,我們將對其進(jìn)行重新訪問。 如果要測試API是否正常運行,請在終端上運行以下命令:

$ node index.js

This will start a new Node server listening on port 4000.

這將啟動在端口4000上偵聽的新Node服務(wù)器。

構(gòu)建客戶端應(yīng)用程序 (Building the client application)

The next thing we need to do is build the client application in Xcode. To start, launch Xcode and create a new ‘Single Application’ project. We will name our project PizzaareaClient.

我們需要做的下一步是在Xcode中構(gòu)建客戶端應(yīng)用程序。 首先,啟動Xcode并創(chuàng)建一個新的“單一應(yīng)用程序”項目。 我們將項目命名為PizzaareaClient。

Once the project has been created, exit Xcode and create a new file called Podfile in the root of the Xcode project you just created. In the file, paste in the following code:

創(chuàng)建項目后,退出Xcode并在剛創(chuàng)建的Xcode項目的根目錄中創(chuàng)建一個名為Podfile的新文件。 在文件中,粘貼以下代碼:

platform :ios, '11.0'target 'PizzareaClient' do use_frameworks! pod 'PusherSwift', '~> 5.1.1' pod 'Alamofire', '~> 4.6.0' end

In the file above, we specified the dependencies the project needs to run. Remember to change the target above to the name of your project. Now in your terminal, run the following command to install the dependencies:

在上面的文件中,我們指定了項目需要運行的依賴項。 請記住,將 上面 target 更改 為您的項目名稱。 現(xiàn)在在您的終端中,運行以下命令以安裝依賴項:

$ pod install

After the installation is complete, open the Xcode workspace file that was generated by Cocoapods. This should relaunch Xcode.

安裝完成后,打開由Cocoapods生成的Xcode工作區(qū)文件。 這應(yīng)該重新啟動Xcode。

When Xcode has been relaunched, open the Main.storyboard file. In it we will create the storyboard for our client application. Below is a screenshot of how we have designed our storyboard:

Xcode重新啟動后,打開Main.storyboard文件。 在其中,我們將為客戶應(yīng)用程序創(chuàng)建情節(jié)提要。 以下是我們?nèi)绾卧O(shè)計故事板的屏幕截圖:

The first scene is the navigation view controller, which has a table view controller as the root controller. The navigation controller is the initial controller that is loaded when the application is launched.

第一個場景是導(dǎo)航視圖控制器,它具有一個表視圖控制器作為根控制器。 導(dǎo)航控制器是啟動應(yīng)用程序時加載的初始控制器。

創(chuàng)建披薩列表場景 (Creating the pizza list scene)

The second scene is the view controller that lists the inventory that we have available.

第二個場景是視圖控制器,它列出了我們可用的清單。

Create a new file in Xcode called PizzaTableListViewController.swift, make it the custom class for the second scene, and paste in the following code:

在Xcode中創(chuàng)建一個名為PizzaTableListViewController.swift的新文件,使其成為第二個場景的自定義類,然后粘貼以下代碼:

import UIKit import Alamofireclass PizzaListTableViewController: UITableViewController {var pizzas: [Pizza] = []override func viewDidLoad() { super.viewDidLoad()navigationItem.title = "Select Pizza"fetchInventory { pizzas in guard pizzas != nil else { return } self.pizzas = pizzas! self.tableView.reloadData() } }private func fetchInventory(completion: @escaping ([Pizza]?) -> Void) { Alamofire.request("http://127.0.0.1:4000/inventory", method: .get) .validate() .responseJSON { response in guard response.result.isSuccess else { return completion(nil) } guard let rawInventory = response.result.value as? [[String: Any]?] else { return completion(nil) }let inventory = rawInventory.flatMap { pizzaDict -> Pizza? in var data = pizzaDict! data["image"] = UIImage(named: pizzaDict!["image"] as! String)return Pizza(data: data) }completion(inventory) } }@IBAction func ordersButtonPressed(_ sender: Any) { performSegue(withIdentifier: "orders", sender: nil) }override func numberOfSections(in tableView: UITableView) -> Int { return 1 }override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return pizzas.count }override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Pizza", for: indexPath) as! PizzaTableViewCellcell.name.text = pizzas[indexPath.row].name cell.imageView?.image = pizzas[indexPath.row].image cell.amount.text = "$\(pizzas[indexPath.row].amount)" cell.miscellaneousText.text = pizzas[indexPath.row].descriptionreturn cell }override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 100.0 }override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { performSegue(withIdentifier: "pizza", sender: self.pizzas[indexPath.row] as Pizza) }override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "pizza" { guard let vc = segue.destination as? PizzaViewController else { return } vc.pizza = sender as? Pizza } } }

In the viewDidLoad method, we call the fetchInventory method that uses Alamofire to fetch the inventory from our backend API. Then we save the response to the orders property of the controller.

在viewDidLoad方法中,我們調(diào)用fetchInventory方法,該方法使用Alamofire從后端API中獲取清單。 然后,將響應(yīng)保存到控制器的orders屬性。

The ordersButtonPressed is linked to the Orders button on the scene. This just presents the scene with the list of orders using a named segue orders.

ordersButtonPressed鏈接到場景中的“ Orders按鈕。 這只是呈現(xiàn)使用名為賽格瑞訂單列表現(xiàn)場orders 。

The tableView* methods implement methods available to the UITableViewDelegate protocol and should be familiar to you.

tableView*方法實現(xiàn)了UITableViewDelegate協(xié)議可用的方法,您應(yīng)該熟悉它們。

The final method prepare simply sends the pizza to the view controller on navigation. But this pizza is only sent over if the view controller being loaded is the PizzaViewController .

最終的prepare方法只是將pizza發(fā)送到導(dǎo)航中的視圖控制器。 但這種pizza只送過來,如果要加載的視圖控制器是PizzaViewController 。

Before we create the third scene, create a PizzaTableViewCell.swift class and paste in the following:

在創(chuàng)建第三個場景之前,請創(chuàng)建PizzaTableViewCell.swift類并粘貼以下內(nèi)容:

import UIKit class PizzaTableViewCell: UITableViewCell { @IBOutlet weak var pizzaImageView: UIImageView! @IBOutlet weak var name: UILabel! @IBOutlet weak var miscellaneousText: UILabel! @IBOutlet weak var amount: UILabel! override func awakeFromNib() { super.awakeFromNib() } }

?? Make sure the custom class of the cells in the second scene is PizzaTableViewCell, and that the reusable identifier is Pizza.

??確保第二個場景中單元格的自定義類是PizzaTableViewCell ,并且可重復(fù)使用的標(biāo)識符是Pizza 。

創(chuàng)建披薩視圖場景 (Creating the pizza view scene)

The third scene in our storyboard is the Pizza view scene. This is where the selected inventory can be viewed.

我們的情節(jié)提要中的第三個場景是Pizza視圖場景。 在這里可以查看所選庫存。

Create a PizzaViewController.swift file, make it the custom class for the scene above, and paste in the following code:

創(chuàng)建一個PizzaViewController.swift文件,使其成為上面場景的自定義類,然后粘貼以下代碼:

import UIKit import Alamofireclass PizzaViewController: UIViewController {var pizza: Pizza?@IBOutlet weak var amount: UILabel! @IBOutlet weak var pizzaDescription: UILabel! @IBOutlet weak var pizzaImageView: UIImageView!override func viewDidLoad() { super.viewDidLoad()navigationItem.title = pizza!.name pizzaImageView.image = pizza!.image pizzaDescription.text = pizza!.description amount.text = "$\(String(describing: pizza!.amount))" }@IBAction func buyButtonPressed(_ sender: Any) { let parameters = [ "pizza_id": pizza!.id, "user_id": AppMisc.USER_ID ]Alamofire.request("http://127.0.0.1:4000/orders", method: .post, parameters: parameters) .validate() .responseJSON { response in guard response.result.isSuccess else { return self.alertError() }guard let status = response.result.value as? [String: Bool], let successful = status["status"] else { return self.alertError() }successful ? self.alertSuccess() : self.alertError() } }private func alertError() { return self.alert( title: "Purchase unsuccessful!", message: "Unable to complete purchase please try again later." ) }private func alertSuccess() { return self.alert( title: "Purchase Successful", message: "You have ordered successfully, your order will be confirmed soon." ) }private func alert(title: String, message: String) { let alertCtrl = UIAlertController(title: title, message: message, preferredStyle: .alert)alertCtrl.addAction(UIAlertAction(title: "Okay", style: .cancel) { action in self.navigationController?.popViewController(animated: true) })present(alertCtrl, animated: true, completion: nil) } }

In the code above, we have multiple @IBOutlet’s and a single @IBAction. You need to link the outlets and actions to the controller from the storyboard.

在上面的代碼中,我們有多個@IBOutlet和一個@IBAction 。 您需要從情節(jié)提要中將插座和動作鏈接到控制器。

In the viewDidLoad we set the outlets so they display the correct values using the pizza sent from the previous view controller. The buyButtonPressed method uses Alamofire to place an order by sending a request to the API. The remaining methods handle displaying the error or success response from the API.

在viewDidLoad我們設(shè)置出口,以便它們使用從前一個視圖控制器發(fā)送的pizza顯示正確的值。 buyButtonPressed方法使用Alamofire通過向API發(fā)送請求來下訂單。 其余方法處理顯示來自API的錯誤或成功響應(yīng)。

創(chuàng)建訂單清單場景 (Creating the orders list scene)

The next scene is the Orders list scene. In this scene, all the orders are listed so the user can see them and their status:

下一個場景是“訂單”列表場景。 在此場景中,列出了所有訂單,因此用戶可以查看它們及其狀態(tài):

Create a OrderTableViewController.swift file, make it the custom class for the scene above, and paste in the following code:

創(chuàng)建一個OrderTableViewController.swift文件,使其成為上面場景的自定義類,然后粘貼以下代碼:

import UIKit import Alamofireclass OrdersTableViewController: UITableViewController {var orders: [Order] = []override func viewDidLoad() { super.viewDidLoad() navigationItem.title = "Orders"fetchOrders { orders in self.orders = orders! self.tableView.reloadData() } }private func fetchOrders(completion: @escaping([Order]?) -> Void) { Alamofire.request("http://127.0.0.1:4000/orders").validate().responseJSON { response in guard response.result.isSuccess else { return completion(nil) }guard let rawOrders = response.result.value as? [[String: Any]?] else { return completion(nil) }let orders = rawOrders.flatMap { ordersDict -> Order? in guard let orderId = ordersDict!["id"] as? String, let orderStatus = ordersDict!["status"] as? String, var pizza = ordersDict!["pizza"] as? [String: Any] else { return nil }pizza["image"] = UIImage(named: pizza["image"] as! String)return Order( id: orderId, pizza: Pizza(data: pizza), status: OrderStatus(rawValue: orderStatus)! ) }completion(orders) } }@IBAction func closeButtonPressed(_ sender: Any) { dismiss(animated: true, completion: nil) }override func numberOfSections(in tableView: UITableView) -> Int { return 1 }override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return orders.count }override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "order", for: indexPath) let order = orders[indexPath.row]cell.textLabel?.text = order.pizza.name cell.imageView?.image = order.pizza.image cell.detailTextLabel?.text = "$\(order.pizza.amount) - \(order.status.rawValue)"return cell }override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 100.0 }override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { performSegue(withIdentifier: "order", sender: orders[indexPath.row] as Order) }override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "order" { guard let vc = segue.destination as? OrderViewController else { return } vc.order = sender as? Order } } }

The code above is similar to the code in the PizzaTableViewController above. However, instead of fetching the inventory, it fetches the orders. Instead of passing the pizza in the last method, it passes the order to the next controller. The controller also comes with a closeButtonPressed method that just dismisses the controller and returns to the inventory list scene.

上面的代碼PizzaTableViewController上面的PizzaTableViewController的代碼。 但是,它不是獲取庫存,而是獲取orders 。 而不是通過最后一個方法傳遞pizza ,而是將order傳遞給下一個控制器。 控制器還帶有closeButtonPressed方法,該方法只是關(guān)閉控制器并返回到清單清單場景。

創(chuàng)建訂單狀態(tài)場景 (Creating the Order Status Scene)

The next scene is the Order scene. In this scene, we can see the status of the order:

下一個場景是訂購場景。 在此場景中,我們可以看到訂單的狀態(tài):

?? The scene above has an invisible view right above the status label. You need to use this view to create an @IBOutlet to the controller.

above?上面的場景在狀態(tài)標(biāo)簽的正上方具有不可見的視圖。 您需要使用此視圖為控制器創(chuàng)建@IBOutlet 。

Create a OrderViewController.swift file, make it the custom class for the scene above, and paste in the following code:

創(chuàng)建一個OrderViewController.swift文件,使其成為上面場景的自定義類,然后粘貼以下代碼:

import UIKitclass OrderViewController: UIViewController {var order: Order?@IBOutlet weak var status: UILabel! @IBOutlet weak var activityView: ActivityIndicator!override func viewDidLoad() { super.viewDidLoad()navigationItem.title = order?.pizza.nameactivityView.startLoading()switch order!.status { case .pending: status.text = "Processing Order" case .accepted: status.text = "Preparing Order" case .dispatched: status.text = "Order is on its way!" case .delivered: status.text = "Order delivered" activityView.strokeColor = UIColor.green activityView.completeLoading(success: true) } } }

In the code above, we are doing all the work in our viewDidLoad method. In there we have the ActivityIndicator class, which we will create next, referenced as an @IBOutlet.

在上面的代碼中,我們正在執(zhí)行viewDidLoad方法中的所有工作。 在那里,我們有ActivityIndicator類,接下來將創(chuàng)建該類,將其稱為@IBOutlet 。

創(chuàng)建應(yīng)用程序的其他部分 (Creating other parts of the application)

We are using a third-party library called the [ActivityIndicator](https://github.com/abdulKarim002/activityIndicator), but since the package is not available via Cocoapods, we have opted to create it ourselves and import it.

我們正在使用一個名為[ActivityIndicator](https://github.com/abdulKarim002/activityIndicator)的第三方庫,但是由于該軟件包無法通過Cocoapods獲得,因此我們選擇自己創(chuàng)建并導(dǎo)入。

Create a new file in Xcode called ActivityIndicator and paste the code from the repo here into it.

在Xcode中創(chuàng)建一個名為ActivityIndicator的新文件,并將代碼從倉庫中粘貼到其中。

Next, create a new Order.swift file and paste in the following code:

接下來,創(chuàng)建一個新的Order.swift文件并粘貼以下代碼:

import Foundationstruct Order { let id: String let pizza: Pizza var status: OrderStatus }enum OrderStatus: String { case pending = "Pending" case accepted = "Accepted" case dispatched = "Dispatched" case delivered = "Delivered" }

Finally, create a Pizza.swift and paste in the following code:

最后,創(chuàng)建Pizza.swift并粘貼以下代碼:

import UIKitstruct Pizza { let id: String let name: String let description: String let amount: Float let image: UIImageinit(data: [String: Any]) { self.id = data["id"] as! String self.name = data["name"] as! String self.amount = data["amount"] as! Float self.description = data["description"] as! String self.image = data["image"] as! UIImage } }

That is all for the client application. One last thing we need to do, though, is modify the info.plist file. We need to add an entry to the plist file to allow connection to our local server:

這就是客戶端應(yīng)用程序的全部內(nèi)容。 但是,我們需要做的最后一件事是修改info.plist文件。 我們需要在plist文件中添加一個條目,以允許連接到我們的本地服務(wù)器:

Let’s move on to the admin application.

讓我們繼續(xù)進(jìn)行管理應(yīng)用程序。

生成管理應(yīng)用程序 (Building the admin application)

Launch a new instance of Xcode and create a new ‘Single Application’ project. We will name our project PizzaareaAdmin.

啟動Xcode的新實例并創(chuàng)建一個新的“單一應(yīng)用程序”項目。 我們將我們的項目命名為PizzaareaAdmin。

Once the project has been created, exit Xcode and create a new file called Podfile in the root of the Xcode project you just created. In the file, paste in the following code:

創(chuàng)建項目后,退出Xcode并在剛創(chuàng)建的Xcode項目的根目錄中創(chuàng)建一個名為Podfile的新文件。 在文件中,粘貼以下代碼:

platform :ios, '11.0'target 'PizzareaAdmin' do use_frameworks! pod 'PusherSwift', '~> 5.1.1' pod 'Alamofire', '~> 4.6.0' end

In the file above, we specified the dependencies the project needs to run. Remember to change the **target** above to the name of your project.

在上面的文件中,我們指定了項目需要運行的依賴項。 請記住,將 上面的“ **target** 更改 為您的項目名稱。

Now, in your terminal, run the following command to install the dependencies:

現(xiàn)在,在您的終端中,運行以下命令以安裝依賴項:

$ pod install

After the installation is complete, open the Xcode workspace file that was generated by Cocoapods. This should relaunch Xcode.

安裝完成后,打開由Cocoapods生成的Xcode工作區(qū)文件。 這應(yīng)該重新啟動Xcode。

When Xcode has been relaunched, open the Main.storyboard file. In there we will create the storyboard for our client application. Below is a screenshot of how we have designed our storyboard:

Xcode重新啟動后,打開Main.storyboard文件。 在這里,我們將為客戶應(yīng)用程序創(chuàng)建情節(jié)提要。 以下是我們?nèi)绾卧O(shè)計故事板的屏幕截圖:

Above we have a navigation view controller that is the initial view controller.

上面我們有一個導(dǎo)航視圖控制器,它是初始視圖控制器。

創(chuàng)建訂單清單場景 (Creating the orders list scene)

The orders list scene is supposed to show the list of clients’ orders. From there we can change the status of each order when we want.

訂單列表場景應(yīng)該顯示客戶訂單的列表。 從那里我們可以在需要時更改每個訂單的狀態(tài)。

Create a new file in Xcode called OrdersListViewController.swift, make it the custom class for the second scene, and paste in the following code:

在Xcode中創(chuàng)建一個名為OrdersListViewController.swift的新文件,使其成為第二個場景的自定義類,并粘貼以下代碼:

import UIKit import Alamofireclass OrdersTableViewController: UITableViewController {var orders: [Order] = []override func viewDidLoad() { super.viewDidLoad()navigationItem.title = "Client Orders"fetchOrders { orders in self.orders = orders! self.tableView.reloadData() } }private func fetchOrders(completion: @escaping([Order]?) -> Void) { Alamofire.request("http://127.0.0.1:4000/orders").validate().responseJSON { response in guard response.result.isSuccess else { return completion(nil) }guard let rawOrders = response.result.value as? [[String: Any]?] else { return completion(nil) }let orders = rawOrders.flatMap { ordersDict -> Order? in guard let orderId = ordersDict!["id"] as? String, let orderStatus = ordersDict!["status"] as? String, var pizza = ordersDict!["pizza"] as? [String: Any] else { return nil }pizza["image"] = UIImage(named: pizza["image"] as! String)return Order( id: orderId, pizza: Pizza(data: pizza), status: OrderStatus(rawValue: orderStatus)! ) }completion(orders) } }override func numberOfSections(in tableView: UITableView) -> Int { return 1 }override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return orders.count }override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "order", for: indexPath) let order = orders[indexPath.row]cell.textLabel?.text = order.pizza.name cell.imageView?.image = order.pizza.image cell.detailTextLabel?.text = "$\(order.pizza.amount) - \(order.status.rawValue)"return cell }override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 100.0 }override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let order: Order = orders[indexPath.row]let alertCtrl = UIAlertController( title: "Change Status", message: "Change the status of the order based on the progress made.", preferredStyle: .actionSheet )alertCtrl.addAction(createActionForStatus(.pending, order: order)) alertCtrl.addAction(createActionForStatus(.accepted, order: order)) alertCtrl.addAction(createActionForStatus(.dispatched, order: order)) alertCtrl.addAction(createActionForStatus(.delivered, order: order)) alertCtrl.addAction(createActionForStatus(nil, order: nil))present(alertCtrl, animated: true, completion: nil) }private func createActionForStatus(_ status: OrderStatus?, order: Order?) -> UIAlertAction { let alertTitle = status == nil ? "Cancel" : status?.rawValue let alertStyle: UIAlertActionStyle = status == nil ? .cancel : .defaultlet action = UIAlertAction(title: alertTitle, style: alertStyle) { action in if status != nil { self.setStatus(status!, order: order!) } }if status != nil { action.isEnabled = status?.rawValue != order?.status.rawValue }return action }private func setStatus(_ status: OrderStatus, order: Order) { updateOrderStatus(status, order: order) { successful in guard successful else { return } guard let index = self.orders.index(where: {$0.id == order.id}) else { return }self.orders[index].status = status self.tableView.reloadData() } }private func updateOrderStatus(_ status: OrderStatus, order: Order, completion: @escaping(Bool) -> Void) { let url = "http://127.0.0.1:4000/orders/" + order.id let params = ["status": status.rawValue]Alamofire.request(url, method: .put, parameters: params).validate().responseJSON { response in guard response.result.isSuccess else { return completion(false) } guard let data = response.result.value as? [String: Bool] else { return completion(false) }completion(data["status"]!) } } }

The code above is similar to the code in the PizzaListTableViewController in the client application, so check back there if you need further explanation.

上面的代碼與客戶端應(yīng)用程序中的PizzaListTableViewController中的代碼相似,因此如果需要進(jìn)一步的說明,請在此處檢查。

There is a createActionForStatus, which is a helper for creating and configuring UIAlertAction object. There is a setStatus method that just attempts to set the status for an order. And then there is the updateOrderStatus method that sends the update request using Alamofire to the API.

有一個createActionForStatus ,它是用于創(chuàng)建和配置UIAlertAction對象的幫助器。 有一個setStatus方法只是嘗試設(shè)置訂單的狀態(tài)。 然后是updateOrderStatus方法,該方法使用Alamofire將更新請求發(fā)送到API。

Next, create the Order.swift and Pizza.swift classes like we did before in the client application:

接下來,像以前在客戶端應(yīng)用程序中一樣創(chuàng)建Order.swift和Pizza.swift類:

// Order.swift import Foundationstruct Order { let id: String let pizza: Pizza var status: OrderStatus }enum OrderStatus: String { case pending = "Pending" case accepted = "Accepted" case dispatched = "Dispatched" case delivered = "Delivered" }// Pizza.swift import UIKitstruct Pizza { let id: String let name: String let description: String let amount: Float let image: UIImageinit(data: [String: Any]) { self.id = data["id"] as! String self.name = data["name"] as! String self.amount = data["amount"] as! Float self.description = data["description"] as! String self.image = data["image"] as! UIImage } }

That’s all for the admin application. One last thing we need to do, though, is modify the info.plist file as we did in the client application.

這就是管理應(yīng)用程序的全部內(nèi)容。 但是,我們需要做的最后一件事是像在客戶端應(yīng)用程序中一樣修改info.plist文件。

向我們的送餐iOS應(yīng)用添加推送通知 (Adding Push Notifications to our food delivery iOS app)

At this point, the application works as expected out of the box. We now need to add push notifications to the application to make it more engaging even when the user is not currently using the application.

此時,該應(yīng)用程序可以按預(yù)期工作。 現(xiàn)在,我們需要向應(yīng)用程序添加推送通知,以使其更具吸引力,即使用戶當(dāng)前未使用該應(yīng)用程序也是如此。

?? You need to be enrolled to the Apple Developer program to be able to use the Push Notifications feature. Also, Push Notifications do not work on Simulators, so you will need an actual iOS device to test.

??您需要注冊到Apple Developer程序才能使用Push Notifications功能。 此外,推送通知在模擬器上也不起作用,因此您將需要實際的iOS設(shè)備進(jìn)行測試。

Pusher’s Push Notifications API has first-class support for native iOS applications. Your iOS app instances subscribe to I**nterests**, then your servers send push notifications to those interests. Every app instance subscribed to that interest will receive the notification, even if the app is not open on the device at the time.

Pusher的Push Notifications API對本地iOS應(yīng)用程序具有一流的支持。 您的iOS應(yīng)用實例訂閱了I ** nterests **,然后您的服務(wù)器向這些興趣發(fā)送推送通知。 訂閱該興趣的每個應(yīng)用程序?qū)嵗紩盏酵ㄖ?#xff0c;即使該應(yīng)用程序當(dāng)時不在設(shè)備上打開。

This section describes how you can set up an iOS app to receive transactional push notifications about your food delivery orders through Pusher.

本節(jié)介紹如何設(shè)置iOS應(yīng)用程序以通過Pusher接收有關(guān)您的食品交付訂單的事務(wù)性推送通知。

配置APN (Configure APNs)

Pusher relies on the Apple Push Notification service (APNs) to deliver push notifications to iOS application users on your behalf. When we deliver push notifications, we use your APNs Key. This page guides you through the process of getting an APNs Key and how to provide it to Pusher.

Pusher依靠Apple Push Notification Service(APN)來代表您向iOS應(yīng)用程序用戶傳遞推送通知。 當(dāng)我們傳遞推送通知時,我們將使用您的APNs密鑰。 本頁指導(dǎo)您完成獲取APNs密鑰的過程,以及如何將其提供給Pusher。

Head over to the Apple Developer dashboard by clicking here and then create a new Key as seen below:

通過單擊此處轉(zhuǎn)到Apple Developer儀表板,然后創(chuàng)建一個新密鑰,如下所示:

When you have created the key, download it. Keep it safe as we will need it in the next section.

創(chuàng)建密鑰后,請下載它。 確保安全,因為我們將在下一節(jié)中使用它。

?? You have to keep the generated key safe as you cannot get it back if you lose it.

??您必須保護(hù)生成的密鑰安全,因為如果丟失它將無法找回。

創(chuàng)建您的Pusher應(yīng)用程序 (Creating your Pusher application)

The next thing you need to do is create a new Pusher Push Notification application from the Pusher dashboard.

接下來需要做的是從Pusher儀表板創(chuàng)建一個新的Pusher Push Notification應(yīng)用程序。

When you have created the application, you should be presented with a Quickstart wizard that will help you set up the application.

創(chuàng)建應(yīng)用程序后,應(yīng)顯示一個快速入門向?qū)?#xff0c;該向?qū)椭O(shè)置應(yīng)用程序。

In order to configure Push Notifications, you will need to get an APNs key from Apple. This is the same key as the one we downloaded in the previous section. Once you’ve got the key, upload it to the Quickstart wizard.

為了配置推送通知,您將需要從Apple獲得APNs密鑰。 這與上一節(jié)中下載的密鑰相同。 獲取密鑰后,將其上傳到快速入門向?qū)А?

Enter your Apple Team ID. You can get the Team ID from here. Click on continue to proceed to the next step.

輸入您的Apple Team ID。 您可以從此處獲取團(tuán)隊ID。 單擊繼續(xù)以繼續(xù)下一步。

更新客戶端應(yīng)用程序以支持推送通知 (Updating your client application to support Push Notifications)

In your client application, open the Podfile and add the following pod to the list of dependencies:

在您的客戶端應(yīng)用程序中,打開Podfile并將以下pod添加到依賴項列表中:

pod 'PushNotifications'

Now run the pod install command as you did earlier to pull in the notifications package. When installation is complete, create a new class AppMisc.swift and in there paste the following:

現(xiàn)在,像以前一樣運行pod install命令,以獲取通知包。 安裝完成后,創(chuàng)建一個新的AppMisc.swift類,并在其中粘貼以下內(nèi)容:

class AppMisc { static let USER_ID = NSUUID().uuidString.replacingOccurrences(of: "-", with: "_") }

In the little class above, we generate a user ID for the session. In a real application, you would typically have an actual user ID after authentication.

在上面的小類中,我們?yōu)闀捝梢粋€用戶ID。 在實際的應(yīng)用程序中,身份驗證后通常會具有實際的用戶ID。

Next open the AppDelegate class and import the PushNotifications package:

接下來打開AppDelegate類并導(dǎo)入PushNotifications包:

import PushNotifications

Now, as part of the AppDelegate class, add the following:

現(xiàn)在,作為AppDelegate類的一部分,添加以下內(nèi)容:

let pushNotifications = PushNotifications.sharedfunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { self.pushNotifications.start(instanceId: "PUSHER_NOTIF_INSTANCE_ID") self.pushNotifications.registerForRemoteNotifications() return true }func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { self.pushNotifications.registerDeviceToken(deviceToken) { try? self.pushNotifications.subscribe(interest: "orders_" + AppMisc.USER_ID) } }

? Replace PUSHER_PUSH_NOTIF_INSTANCE_ID with the key given to you by the Pusher application.

? 將P USHER_PUSH_NOTIF_INSTANCE_ID替換為Pusher應(yīng)用程序提供給您的密鑰。

In the code above, we set up push notifications in the application(didFinishLaunchingWithOptions:) method and then we subscribe in the application(didRegisterForRemoteNotificationsWithDeviceToken:) method.

在上面的代碼中,我們在application(didFinishLaunchingWithOptions:)方法中設(shè)置了推送通知,然后在application(didRegisterForRemoteNotificationsWithDeviceToken:)方法中進(jìn)行了訂閱。

Next, we need to enable push notifications for the application. In the project navigator, select your project, and click on the Capabilities tab. Enable Push Notifications by turning the switch ON.

接下來,我們需要為應(yīng)用程序啟用推送通知。 在項目導(dǎo)航器中,選擇您的項目,然后單擊“ 功能”選項卡。 通過打開開關(guān)啟用推送通知 。

更新您的管理應(yīng)用程序以支持推送通知 (Updating your admin application to support Push Notifications)

Your admin application also needs to be able to receive Push Notifications. The process is similar to the set up above. The only difference will be the interest we will be subscribing to in AppDelegate which will be orders.

您的管理應(yīng)用程序還需要能夠接收推送通知。 該過程類似于上面的設(shè)置。 唯一的區(qū)別是我們將在AppDelegate中訂閱的興趣是訂單

更新您的API以發(fā)送推送通知 (Updating your API to send Push Notifications)

Push Notifications will be published using our backend server API, which is written in Node.js. For this we will use the Node.js SDK. cd to the backend project directory and run the following command:

推送通知將使用我們的后端服務(wù)器API發(fā)布,該API用Node.js編寫。 為此,我們將使用Node.js SDK 。 cd到后端項目目錄,然后運行以下命令:

$ npm install pusher-push-notifications-node --save

Next, open the index.js file and import the pusher-push-notifications-node package:

接下來,打開index.js文件并導(dǎo)入pusher-push-notifications-node包:

const PushNotifications = require('pusher-push-notifications-node');let pushNotifications = new PushNotifications({ instanceId: 'PUSHER_PUSH_NOTIF_INSTANCE_ID', secretKey: 'PUSHER_PUSH_NOTIF_SECRET_KEY' });

Next, we want to add a helper function that returns a notification message based on the order status. In the index.js add the following:

接下來,我們要添加一個輔助函數(shù),該函數(shù)根據(jù)訂單狀態(tài)返回通知消息。 在index.js添加以下內(nèi)容:

function getStatusNotificationForOrder(order) { let pizza = order['pizza'] switch (order['status']) { case "Pending": return false; case "Accepted": return `? Your "${pizza['name']}" is being processed.` case "Dispatched": return `?? Your "${order['pizza']['name']}" is on it’s way` case "Delivered": return `? Your "${pizza['name']}" has been delivered. Bon Appetit.` default: return false; } }

Next, in the PUT /orders/:id route, add the following code before the return statement:

Next, in the PUT /orders/:id route, add the following code before the return statement:

let alertMessage = getStatusNotificationForOrder(order)if (alertMessage !== false) { pushNotifications.publish([`orders_${user_id}`], { apns: { aps: { alert: { title: "Order Information", body: alertMessage, }, sound: 'default' } } }) .then(response => console.log('Just published:', response.publishId)) .catch(error => console.log('Error:', error)); }

In the code above, we send a push notification to the **orders_${user_id}** interest (user_id is the ID generated and passed to the backend server from the client) whenever the order status is changed. This will be a notification that will be picked up by our client application, since we subscribed for that interest earlier.

In the code above, we send a push notification to the **orders_${user_id}** interest ( user_id is the ID generated and passed to the backend server from the client) whenever the order status is changed. This will be a notification that will be picked up by our client application, since we subscribed for that interest earlier.

Next, in the POST /orders route, add the following code before the return statement:

Next, in the POST /orders route, add the following code before the return statement:

pushNotifications.publish(['orders'], { apns: { aps: { alert: { title: "? New Order Arrived", body: `An order for ${pizza['name']} has been made.`, }, sound: 'default' } } }) .then(response => console.log('Just published:', response.publishId)) .catch(error => console.log('Error:', error));

In this case, we are sending a push notification to the orders interest. This will be sent to the admin application that is subscribed to the orders interest.

In this case, we are sending a push notification to the orders interest. This will be sent to the admin application that is subscribed to the orders interest.

That’s all there is to adding push notifications using Pusher. Here are screen recordings of our applications in action:

That's all there is to adding push notifications using Pusher. Here are screen recordings of our applications in action:

Conclusion (Conclusion)

In this article, we created a basic food delivery system and used that to demonstrate how to use Pusher to send Push Notifications in multiple applications using the same Pusher application. Hopefully you learned how you can use Pusher to simplify the process of sending Push Notifications to your users.

In this article, we created a basic food delivery system and used that to demonstrate how to use Pusher to send Push Notifications in multiple applications using the same Pusher application. Hopefully you learned how you can use Pusher to simplify the process of sending Push Notifications to your users.

This post was first published to Pusher.

This post was first published to Pusher .

翻譯自: https://www.freecodecamp.org/news/how-to-build-a-food-delivery-app-with-push-notifications-using-swift-2aa259ffea58/

swift通知欄推送

總結(jié)

以上是生活随笔為你收集整理的swift通知栏推送_如何使用Swift使用推送通知构建食品交付应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

欧美激情精品 | 国产精品久久久久一区二区国产 | 久久免费视频一区 | 日韩欧美在线视频一区二区三区 | 97日日碰人人模人人澡分享吧 | 香蕉一区 | 91香蕉视频720p | 免费观看黄色12片一级视频 | 中文字幕一区二区在线观看 | 精品国产91亚洲一区二区三区www | 中文字幕av免费在线观看 | 国产精品一区二区久久久 | 国产亚洲欧美精品久久久久久 | 日韩电影一区二区三区在线观看 | 国产日韩欧美自拍 | 久久久久在线观看 | 国产九九精品视频 | 中文字幕第一页在线 | 麻豆成人在线观看 | 久久久久久免费视频 | 91传媒视频在线观看 | 九九热re | 91 在线视频 | 天天干天天拍天天操天天拍 | 日韩99热| 久久99久久99精品免视看婷婷 | 久久久久网站 | 奇米网777 | 香蕉视频4aa| 丰满少妇在线观看网站 | 欧美片网站yy| 国产精品一区二区在线播放 | 日韩视频在线观看视频 | 国产黄色大全 | 激情五月***国产精品 | 亚洲天堂网视频在线观看 | 狠狠色丁香久久综合网 | 国产成人精品一区二区三区网站观看 | 国产手机视频在线播放 | 91激情视频在线 | 五月婷婷av在线 | 欧美大片mv免费 | 亚洲精品在线观看中文字幕 | 少妇bbbb搡bbbb桶 | 久久久久国产一区二区三区 | 日韩在线视频免费观看 | 精品国产激情 | 免费精品在线视频 | 欧美地下肉体性派对 | 九九在线高清精品视频 | 狠狠躁日日躁狂躁夜夜躁av | 国产在线观看xxx | 国产精品一区二区精品视频免费看 | 日韩高清一区 | 成人欧美一区二区三区黑人麻豆 | 黄色av一区| 激情欧美一区二区免费视频 | 91在线蜜桃臀| 一级性视频 | 亚洲高清视频在线播放 | 韩国av免费观看 | 亚洲视频第一页 | 四虎成人精品 | 超碰97成人 | 国产精品视频内 | 中文字幕韩在线第一页 | 中文字幕在线观看视频一区二区三区 | 最近免费在线观看 | 伊人天天综合 | 久久理伦片| 亚洲二级片 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 国产精品手机在线播放 | 亚州天堂| 激情综合色综合久久 | 丁香激情综合 | 99精品国产99久久久久久福利 | 国产性天天综合网 | 久久久久久久久艹 | 特级黄色视频毛片 | 午夜视频在线观看欧美 | 国产69精品久久99不卡的观看体验 | 日日干天夜夜 | www91在线观看 | 青草视频在线 | 亚洲欧美一区二区三区孕妇写真 | 丁香av | 碰天天操天天 | 99久久精品免费一区 | 国产黄色成人 | 免费视频久久 | 国产精品麻豆视频 | 久久99国产综合精品免费 | 国产视频亚洲视频 | av大片免费在线观看 | 99视频精品免费观看, | 九九久久精品 | 岛国精品一区二区 | 成年人视频在线免费观看 | 国内少妇自拍视频一区 | 操操日日 | 亚洲精品久久视频 | 国产精品一区二区电影 | 91精品国产一区二区三区 | 久久视频在线观看 | 91成人精品一区在线播放69 | 国产一线天在线观看 | 欧美成人精品欧美一级乱黄 | 91色蜜桃| 91九色在线视频 | 成人av手机在线 | 97超碰成人在线 | 日韩av不卡在线观看 | av在线网站免费观看 | 亚洲激情在线视频 | 91精品国产91p65 | 国产欧美日韩视频 | 国产精品理论在线观看 | 天天干天天做 | 欧美国产日韩一区二区 | 免费在线观看日韩欧美 | 又黄又爽又无遮挡的视频 | 久久久久久久久亚洲精品 | 国产精品久久久久久麻豆一区 | 在线影院 国内精品 | 成年人毛片在线观看 | 狠狠色丁香婷综合久久 | 久久天堂影院 | 亚洲黄色高清 | 日韩视频在线不卡 | 干干干操操操 | 韩日精品在线 | 又污又黄的网站 | 国产精品一区二区久久精品爱微奶 | 久久伊99综合婷婷久久伊 | 在线色亚洲 | www.夜夜操.com | 日日爱网址 | 天天干天天摸 | 久久国产精品久久精品国产演员表 | 日韩高清成人 | 69视频永久免费观看 | 999毛片| 日韩精品高清视频 | 91视频午夜 | 区一区二区三区中文字幕 | 中午字幕在线观看 | 丁香六月五月婷婷 | 午夜久久影视 | 免费在线观看av电影 | 激情电影影院 | 正在播放一区 | 亚洲成色| 天天操夜夜爱 | 久久久综合 | 91视频免费 | 一区二区三区国 | 99欧美视频 | 久久激情小视频 | 亚洲精品在线免费播放 | 一级片视频在线 | 精品国产一区二区三区噜噜噜 | 不卡av电影在线观看 | 国产精品美女999 | 国产看片免费 | 国产精品一区二区久久精品爱微奶 | 深爱婷婷久久综合 | 一区二区精品 | 综合天天| 日韩视频一区二区三区在线播放免费观看 | 四虎免费在线观看视频 | 国产97碰免费视频 | 中文字幕电影高清在线观看 | 丰满少妇一级 | 麻豆视频一区二区 | 中文字幕欧美激情 | 最新av网站在线观看 | 日本高清免费中文字幕 | 国产黄色免费观看 | 国产亚洲精品久久久久久久久久久久 | 制服丝袜在线91 | 中文字幕在线观看网 | 亚洲色图激情文学 | 黄色大片日本免费大片 | 国产精品久久久久久久久大全 | 亚洲欧美偷拍另类 | 91成品视频 | www.伊人网 | 丁香花在线视频观看免费 | 国产美女在线精品免费观看 | 亚洲黄色网络 | 国产亚洲视频在线 | 精品国产观看 | 国产a高清 | 免费观看一级成人毛片 | 探花视频在线版播放免费观看 | 色婷婷国产在线 | 青青草在久久免费久久免费 | 久久1区 | a午夜在线 | 成人免费视频免费观看 | 韩国中文三级 | 久草在线在线精品观看 | 色婷婷啪啪免费在线电影观看 | 欧美调教网站 | 亚洲美女精品区人人人人 | 国产a高清 | 日韩在线看片 | 亚洲一一在线 | 国产生活一级片 | 日韩影视在线 | 国产又粗又猛又黄 | 国内精品久久久久影院优 | 免费日韩av电影 | 五月婷婷导航 | 香蕉在线视频播放网站 | 视频一区二区国产 | 久久视频在线观看免费 | 日韩av黄 | 天天亚洲| 国产999久久久 | 国产精品久久精品国产 | 天天综合网天天 | 日韩视频一区二区三区 | 少妇bbbb| 成人毛片一区 | 国产精品你懂的在线观看 | 97激情影院 | 精产嫩模国品一二三区 | 人人干天天射 | 久久综合精品国产一区二区三区 | 日本巨乳在线 | 美女一级毛片视频 | 99视频在线观看一区三区 | 免费能看的av | 在线视频你懂得 | 久久免费高清视频 | 国模精品在线 | 免费看一级黄色 | 国产精品不卡视频 | 国产精品videoxxxx| 精品人人爽 | 国产午夜精品一区二区三区在线观看 | 中文字幕色婷婷在线视频 | 欧美精品一级视频 | 亚洲第一香蕉视频 | 精品在线亚洲视频 | 爱射综合| 久久久久色 | 国产中文视频 | 国产精品初高中精品久久 | 久久精品亚洲综合专区 | 97在线观看免费观看 | 国产精品亚洲精品 | 久久精品国产成人精品 | 狠狠狠色丁香婷婷综合久久五月 | 久久久久夜色 | 亚洲欧美日韩精品一区二区 | 国产精品久久久久久久婷婷 | 综合久久久久久久 | 久久国产精品一区二区三区四区 | 国产精品一区二区三区在线 | 欧美精品久久久久久久久久久 | 中文字幕第一页在线 | 国产香蕉av| 亚洲一区二区三区四区在线视频 | 黄色影院在线观看 | 欧美大片大全 | av电影在线播放 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 日韩高清精品一区二区 | 81精品国产乱码久久久久久 | 狠狠躁夜夜a产精品视频 | av先锋影音少妇 | 久久久久久久久久久久亚洲 | 免费看污网站 | 久久精品九色 | 国产主播大尺度精品福利免费 | 在线观看网站你懂的 | 天天做天天射 | www178ccom视频在线 | 97精品国产一二三产区 | 91人人澡| 久久久久久久国产精品影院 | 天天操人人要 | 97精品国产97久久久久久久久久久久 | 中文字幕色婷婷在线视频 | 日韩中文字幕视频在线 | 友田真希x88av | 久久久精品福利视频 | 天天操天天色天天射 | 美女网站色在线观看 | 国产小视频在线播放 | 亚洲一区二区视频在线 | 成人黄色在线播放 | 丁香午夜婷婷 | 天天人人 | 日韩欧美在线视频一区二区 | 精品一区二区三区久久 | sm免费xx网站 | 午夜av一区二区三区 | 国产精品久久久久影院 | 中文字幕av全部资源www中文字幕在线观看 | 中文字幕免费观看 | 国产又黄又硬又爽 | 麻豆国产视频下载 | 国产精品99精品久久免费 | 日本电影久久 | 国产精品亚洲片夜色在线 | 在线视频 你懂得 | 久久电影色 | 麻豆影视在线观看 | 国产精品免费人成网站 | 99精彩视频在线观看免费 | 久久久www免费电影网 | 久久精品视频在线播放 | 国产二区视频在线 | 99久久精品免费 | 五月综合激情网 | 国产在线不卡一区 | 91亚洲狠狠婷婷综合久久久 | 欧美久久99 | 涩涩网站免费 | 国精产品永久999 | 69精品久久久 | 久久久久免费视频 | 日韩1页 | 四虎在线观看精品视频 | 91人人爽人人爽人人精88v | 精品久久亚洲 | 色婷婷www | 91激情视频在线观看 | 国产一区国产二区在线观看 | 韩国一区在线 | 香蕉视频4aa | 欧美成a人片在线观看久 | 丁香影院在线 | 婷婷六月中文字幕 | 激情av综合 | 亚洲h在线播放在线观看h | 韩国视频一区二区三区 | 精品在线观 | 国产亚洲精品久久久久久网站 | 成人免费在线网 | 黄色软件网站在线观看 | 亚洲区另类春色综合小说校园片 | 黄色一区二区在线观看 | 免费视频二区 | 国产精品九九久久99视频 | 中文十次啦 | 中文字幕在线影视资源 | 91丨九色丨丝袜 | 国产免费一区二区三区最新 | 国产一区二区免费看 | 在线观看国产成人av片 | 日本特黄特色aaa大片免费 | 在线观看免费一区 | 亚洲国产精品va在线 | 91九色成人 | 婷婷丁香av| av成人在线电影 | 国产精品久久免费看 | 色av婷婷 | 亚洲 综合 激情 | av成人在线网站 | 久草在线视频网站 | 在线国产福利 | 中文不卡视频在线 | 成人h电影 | 久久免费99 | 精品美女久久久久久免费 | 久久久国产一区二区三区 | 91中文在线| 精品在线一区二区 | 伊人狠狠干 | 91亚洲成人| 中文资源在线官网 | 久久久久久97三级 | h视频在线看 | 日日夜夜操操操操 | 亚洲国产精品视频在线观看 | 免费黄色激情视频 | 91麻豆精品国产自产在线游戏 | 亚洲视频电影在线 | 亚洲综合黄色 | 91亚洲激情| 日韩免费成人av | 色免费在线 | www黄色| 国产免费一区二区三区网站免费 | 久久99久久99精品免视看婷婷 | 国产成人精品综合久久久久99 | 激情视频区 | 中文字幕在线乱 | 欧美va天堂va视频va在线 | 日韩在线 一区二区 | 久久毛片网站 | 国产精品一区二区三区久久久 | 91禁看片 | 国产日韩三级 | 韩日色视频 | 国产尤物视频在线 | 国产字幕在线看 | 国产精品麻豆91 | 免费av观看 | 天天综合人人 | 欧美国产日韩一区二区三区 | 在线观看岛国av | www.天天成人国产电影 | 成人资源在线播放 | 国产一区 在线播放 | 波多野结衣在线观看一区 | 久久精品国产一区二区 | 国产亚洲精品久 | 欧美性色综合网站 | 国产精品免费久久久久影院仙踪林 | 亚州av成人 | 久草电影在线观看 | 中文字幕一区二区三区在线视频 | 人人干人人爽 | 国产精品第一页在线观看 | 久草在线资源免费 | 国产成年免费视频 | 欧美性生交大片免网 | 丝袜美腿在线播放 | 久久精品99国产精品酒店日本 | 免费观看www7722午夜电影 | 91超碰免费在线 | 尤物九九久久国产精品的分类 | 91av蜜桃| 97韩国电影| 91av资源网 | 天天干婷婷 | 婷婷网在线 | 国产精品久久久久国产精品日日 | 久久a免费视频 | 一本到视频在线观看 | 美女在线免费视频 | 日韩久久久久久久 | 久久免费一 | 久久久999精品视频 国产美女免费观看 | 在线v| 亚洲 精品在线视频 | 日韩av成人在线观看 | 国产91免费观看 | 久久精品99久久久久久 | 97超碰在 | 久久99视频精品 | 国产综合小视频 | 国产伦精品一区二区三区无广告 | 超碰97中文| 激情五月婷婷丁香 | 成人app在线播放 | 狠狠干中文字幕 | 狠狠干夜夜爱 | 日日夜夜艹 | 日韩有色 | 九九免费在线观看视频 | 中文字幕免费观看 | 美女一区网站 | 夜夜操天天干 | 午夜男人影院 | 午夜久久久久 | 久草资源在线观看 | 91视频高清 | 欧美嫩草影院 | 一区二区三区日韩在线 | www.亚洲在线| 91视频高清免费 | 夜色资源网 | a视频在线播放 | 日韩电影在线观看一区二区三区 | 精品久久视频 | 一本一本久久a久久精品综合妖精 | 一区二区av | 欧美精品久久久久久久久久丰满 | 黄色免费网战 | 日韩电影在线观看中文字幕 | 欧美91精品国产自产 | 精品国产色 | 国产亚洲欧美一区 | 久久草草热国产精品直播 | 欧美日韩久久一区 | 欧美性脚交 | 久免费 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 97夜夜澡人人爽人人免费 | 久久人人爽人人人人片 | 97视频在线观看视频免费视频 | 色综合天天天天做夜夜夜夜做 | 在线视频亚洲 | 国产又粗又猛又色又黄视频 | 免费在线电影网址大全 | 国产精品日韩在线观看 | 日韩精品一区二区三区在线视频 | 亚洲精品午夜视频 | 欧美日韩在线第一页 | 我要看黄色一级片 | 久久久久久久av麻豆果冻 | 在线你懂的视频 | 亚洲国产中文字幕在线视频综合 | 在线视频观看你懂的 | 精品视频一区在线观看 | 色综合久久久久综合99 | 免费观看视频的网站 | 99视频精品 | 国产精品福利在线播放 | 天天人人综合 | 国产日韩精品欧美 | www.五月天激情 | 91精品视频一区二区三区 | 国产精品久久久久久电影 | 免费av在线网站 | 国产精品久久久久久久久久久杏吧 | 伊人官网 | 久久综合久久综合这里只有精品 | 久久综合精品一区 | 亚洲最新av网址 | 国产成人av电影在线 | 日产av在线播放 | 国产在线观看你懂得 | av一级片网站 | 98久9在线 | 免费 | ww亚洲ww亚在线观看 | 2020天天干夜夜爽 | 久久久久久久久久久久国产精品 | 在线观看免费色 | 免费看一级一片 | 激情综合亚洲 | 日韩免费在线观看视频 | 天天操天天操天天操天天 | 国产在线视频资源 | 欧美性极品xxxx娇小 | 午夜视频免费在线观看 | 国产精品第二页 | 一区二区三区免费在线播放 | 在线观看视频h | av电影在线观看完整版一区二区 | av成年人电影| 激情五月六月婷婷 | 丰满少妇在线 | 国产精品女同一区二区三区久久夜 | 精品久久久久久久久久岛国gif | 亚洲精品资源在线观看 | 色婷婷影视 | 99久久www免费 | 国产在线国偷精品产拍 | 国产成人精品一区二区三区福利 | 中文视频一区二区 | 黄色的视频 | 欧美一区日韩精品 | 欧美一二三区播放 | 亚洲精品久久久久久久不卡四虎 | 亚洲精品欧洲精品 | 久草在线最新免费 | 99精彩视频在线观看免费 | 中文av影院 | 天天干天天干天天色 | 欧美精品小视频 | av资源在线看 | 久久综合欧美精品亚洲一区 | 丁香视频免费观看 | 国产亚洲成av片在线观看 | 亚洲黄色小说网址 | 欧美性受极品xxxx喷水 | 麻豆系列在线观看 | 成人久久久精品国产乱码一区二区 | 91精品91 | 久久国际影院 | 久久黄色精品视频 | 视频成人永久免费视频 | 久久大视频 | 欧美性脚交 | 国产成人在线观看 | 日日干天夜夜 | 午夜av在线播放 | 日韩最新在线视频 | 99在线观看 | 欧美午夜a| 国产精品1区 | 亚洲一级片在线观看 | 欧美人人| 日韩午夜在线观看 | 国产精品 9999 | 精品国产伦一区二区三区 | 九九视频免费在线观看 | 日韩理论片 | 丝袜美腿av | 又黄又爽又湿又无遮挡的在线视频 | 美女视频黄免费网站 | 中文永久免费观看 | 久操久 | 国产一级在线观看视频 | 操操操影院 | 最新午夜 | 麻豆影音先锋 | 国内久久精品视频 | 天天做天天看 | 在线免费视 | 亚洲激情综合 | 天天干夜夜想 | 亚洲经典视频在线观看 | 国产一区二区视频在线播放 | 开心激情婷婷 | 日韩高清片 | 热九九精品 | 国产精品毛片一区二区三区 | 久久综合影视 | 国产偷国产偷亚洲清高 | 开心丁香婷婷深爱五月 | 欧美精品999| 奇米网444 | av蜜桃在线 | 奇米影视777影音先锋 | 国产91九色蝌蚪 | 高清av免费一区中文字幕 | 欧美性性网 | 免费观看久久 | 中文字幕欧美日韩va免费视频 | av在线激情 | 久久国产片 | 91在线免费视频 | 中文有码在线视频 | 国内精品久久久久影院优 | 91香蕉视频 mp4| 碰超在线97人人 | 久久99最新地址 | 国产女做a爱免费视频 | 日韩小视频网站 | 天天射成人 | 久久高清国产视频 | 在线电影av| 国产一区二区久久久久 | 色全色在线资源网 | 四虎成人精品永久免费av | 99久久精品免费看国产免费软件 | 蜜臀久久99精品久久久久久网站 | 美女网站黄在线观看 | 人人草人 | 久久精品国产精品亚洲 | 欧美日韩1区2区 | 色的网站在线观看 | 中文字幕在线日 | 91精品欧美一区二区三区 | 国产资源精品在线观看 | 色吊丝在线永久观看最新版本 | 黄色小网站在线观看 | 日韩字幕在线观看 | 91免费观看视频在线 | 免费在线观看av网址 | 久久久国产一区 | 久久综合9988久久爱 | av电影一区二区三区 | 国产九九九精品视频 | 亚洲国产视频在线 | 国产品久精国精产拍 | 国产 在线 日韩 | 中文区中文字幕免费看 | 亚洲欧美999| 国产精品精品久久久 | 久久视频这里只有精品 | 久久艹国产视频 | 欧美久久久久久久久中文字幕 | 久久久久久久久久久久影院 | 国产主播大尺度精品福利免费 | 91探花系列在线播放 | 人人爱天天操 | 欧美a级在线播放 | 高清精品久久 | 久久96国产精品久久99软件 | 久久久久久久久久久久av | 国产精品免费视频网站 | 99r在线| 九月婷婷综合网 | 亚洲成人黄色在线观看 | 日韩一级精品 | 久久一区精品 | sesese图片 | 日韩大片在线看 | 久草免费资源 | 国产成人资源 | 国产品久精国精产拍 | 久久久99精品免费观看乱色 | 亚洲综合在线发布 | 国产亚洲精品久久久久动 | 91超级碰| 看国产黄色片 | 久久av电影| 亚洲精品国产精品乱码不99热 | 国产精品美女免费视频 | 免费观看av网站 | 天天色综合天天 | 久久草在线视频国产 | 天天操人人干 | 日日爽天天操 | 开心丁香婷婷深爱五月 | 久久在线免费视频 | 人人爽人人爽人人爽人人爽 | 日本最新高清不卡中文字幕 | 国产99一区视频免费 | 免费看污黄网站 | 久久综合久久综合九色 | 九九九热精品 | 久草在线精品观看 | 狠狠色丁香婷婷综合久久片 | 成人av片免费观看app下载 | 97超碰成人在线 | 亚洲午夜电影网 | 一区二区视频在线播放 | 日韩久久精品一区二区三区下载 | 五月天天av| japanesefreesexvideo高潮 | 91片网 | 日韩在线观看视频一区二区三区 | 97超碰人人澡人人爱学生 | 美女中文字幕 | 国产亚洲在线视频 | 91综合视频在线观看 | 久久久久久久久久免费 | 99久久久成人国产精品 | 激情久久久 | 欧美黑人xxxx猛性大交 | 91精品一 | 在线观看岛国av | 久99精品| 亚洲成人影音 | 天天干天天天 | 亚洲国产一二三 | 青青草久草在线 | 91看片淫黄大片在线播放 | 亚洲有 在线 | 91视频在线免费 | 免费视频成人 | 香蕉影院在线 | 中文字幕av电影下载 | 国产精品精品久久久久久 | 97成人在线视频 | 免费av网址在线观看 | 狠狠的干狠狠的操 | 天天干夜夜操视频 | 国产成人高清 | 亚洲视频www | 国产亚洲精品bv在线观看 | 国产69精品久久app免费版 | 99性视频 | 国产一性一爱一乱一交 | 日日夜夜天天久久 | 丁香激情综合久久伊人久久 | 精品国产理论片 | 最新av在线播放 | 久久久久成人精品免费播放动漫 | 亚洲精品国产综合99久久夜夜嗨 | 日韩电影在线观看一区二区 | 亚洲免费观看视频 | 国产伦精品一区二区三区… | 日韩69av | 精品黄色在线观看 | 99精品免费久久久久久久久日本 | 精品亚洲欧美一区 | 日韩成人精品 | 成人永久在线 | 久久婷婷综合激情 | 亚洲激情视频 | 欧美国产不卡 | 夜夜操天天| 国产精品九九久久99视频 | 麻豆一二 | 91精品免费在线视频 | 中文字幕乱码亚洲精品一区 | 亚洲va天堂va欧美ⅴa在线 | 亚洲黄色在线 | 欧美日韩三级 | 午夜视频日本 | 国产亚洲精品成人 | 丁香六月色| 99热在线看| 又爽又黄在线观看 | 五月天激情视频在线观看 | 久久免费公开视频 | 中文免费| 天天操综合网站 | 九九热精品在线 | 亚洲一级片 | 久久九九久久九九 | 国产福利在线免费观看 | 国产午夜精品一区二区三区四区 | 美女视频一区 | 亚洲视频一区二区三区在线观看 | avv天堂| 中文字幕首页 | 久久精品视频免费 | 91av九色 | 99这里只有精品99 | 成人国产精品av | 日韩| 99精品视频在线观看播放 | 久久精品国产亚洲 | 日韩在线欧美在线 | 日日爱网址 | 人人爽人人爽人人爽人人爽 | 欧美特一级片 | 欧美日韩激情视频8区 | 欧美一级片在线观看视频 | 免费合欢视频成人app | avove黑丝| 丁香婷婷激情网 | 久久这里只有精品视频首页 | 狠狠干 狠狠操 | 在线导航av | 久久再线视频 | 久久久免费精品 | 一区二区网 | 国产资源网 | 日本在线成人 | 亚洲国产精品成人av | 日韩精品久久一区二区 | 国产69精品久久久久久 | 91av资源网 | 国产精品久久久久久久免费大片 | 精品久久一级片 | 亚州av网站 | 免费观看91视频大全 | 国产精品视频线看 | 亚洲a免费| 久久久久欧美精品999 | 不卡的av在线| 亚洲精品短视频 | 精品国产乱码一区二 | 九九热视频在线免费观看 | www.午夜 | 国产黄av | 怡红院av| 国产福利免费在线观看 | 久草青青在线观看 | 中文字幕一区二区三区视频 | 欧美一级片免费播放 | 天天干天天干天天干天天干天天干天天干 | 久久精品日产第一区二区三区乱码 | 六月丁香久久 | 亚州精品在线视频 | 婷婷国产在线 | 亚洲免费精品一区二区 | 免费成人结看片 | 久久永久免费视频 | 在线成人观看 | 欧美日韩一区二区视频在线观看 | 99精品视频在线观看免费 | 国产剧在线观看片 | 欧美精品一区二区蜜臀亚洲 | 国产精品免费看久久久8精臀av | 国产亚洲综合在线 | 99在线精品视频 | 成人av高清在线 | 国产精品久久久久国产a级 激情综合中文娱乐网 | 久久精品免费电影 | 97韩国电影 | 成 人 黄 色 片 在线播放 | 欧美性春潮 | 最新午夜电影 | 国产精品专区h在线观看 | a色视频 | 国产中文欧美日韩在线 | 国产精品网址在线观看 | 久久久久免费观看 | 国产999久久久 | 四虎影视成人永久免费观看亚洲欧美 | 国产免费激情久久 | 91久久奴性调教 | 91在线观看高清 | 久久国产精品二国产精品中国洋人 | 一区二区亚洲精品 | 日韩系列| 天天曰天天 | 日韩1页 | 成人免费视频网 | 国产尤物在线视频 | 日韩高清一区在线 | 在线观看免费成人av | 欧美va天堂va视频va在线 | 亚洲伊人天堂 | 成人网色| 国产精品乱码一区二三区 | 成人资源网 | 日韩av手机在线看 | 97av精品 | 婷婷丁香自拍 | 人人干人人做 | 久久久www成人免费毛片麻豆 | 久热香蕉视频 | 视频国产一区二区三区 | 高清不卡毛片 | 最新日本中文字幕 | 日韩精品免费在线观看 | 狠狠色伊人亚洲综合成人 | 国产精品v欧美精品v日韩 | 久久久久在线观看 | 天天操网址 | 丁香婷婷久久久综合精品国产 | 日韩精品视频在线免费观看 | 久久久官网| 一级一片免费观看 | 久久国产热 | 中文字幕国产一区二区 | 精品专区| 国产色在线观看 | 碰天天操天天 | 日日精品 | 激情五月婷婷综合网 | 成人av资源站 | 国产手机在线视频 | 国产二区电影 | 又黄又爽又刺激 | av天天澡天天爽天天av | 久久久免费观看视频 | 五月激情视频 | 成全在线视频免费观看 | 欧美一级在线看 | 欧美午夜精品久久久久 | 国产黄色一级片在线 | 欧美片一区二区三区 | 九九免费精品 | 99久久99热这里只有精品 | 日日干,天天干 | 国产黄色av网站 | 亚洲一区二区三区毛片 | 欧美资源在线观看 | 免费在线观看av网站 | 日韩精品一区二区三区高清免费 | 天堂在线免费视频 | 国产在线91精品 | 国产精品乱码久久久 | 午夜精品一区二区三区免费 | 91精品999 | 天天爽夜夜爽精品视频婷婷 | 国语对白少妇爽91 | 视频在线在亚洲 | 99999精品| 日本一区二区免费在线观看 | 色狠狠综合天天综合综合 | 免费视频xnxx com| 国产在线更新 | 免费又黄又爽 | 国产亚洲精品免费 | 亚洲高清在线精品 | 国产成人99久久亚洲综合精品 | 成人一区二区三区在线 | 久久新| 99久久毛片| 国产99久久九九精品免费 | 超碰在线人人爱 | 欧美视屏一区二区 | 六月天综合网 | 亚洲精品成人在线 | 日日婷婷夜日日天干 | 国产一区视频在线观看免费 | 久久久久国 | 欧美成人精品在线 | 欧亚日韩精品一区二区在线 | 伊人五月在线 | 黄色一级大片免费看 | 久久久久久久久福利 | 国产毛片久久 | 在线播放 一区 | 91精品国产91久久久久久三级 | 成人av网站在线观看 | 91亚·色| 亚洲区精品视频 | av再线观看 | 亚洲中字幕 | 国产精品麻豆一区二区三区 | 96久久久 | 天天摸日日摸人人看 | 天天爱天天操天天射 | 91麻豆精品国产自产 | 午夜丁香视频在线观看 | 丁香资源影视免费观看 | 在线观看日本高清mv视频 | 久久国产精品久久国产精品 | av不卡免费在线观看 | 久久这里只精品 | 欧美一级淫片videoshd | 国产成人精品久久久 | 91精品综合在线观看 | 韩国av电影在线观看 | 日韩欧美在线一区 | 香蕉国产91| 中文字幕日韩高清 | 亚洲一区av | 精品国产aⅴ麻豆 | 一区精品久久 | 黄色三级av| 欧美二区在线播放 | 精品久久久久久久久久久久久久久久 | 久久久久久久久艹 | 久久视频免费观看 | 亚州av免费 | 国产精品美女久久久 | 51久久成人国产精品麻豆 |