Symfoware

Symfowareについての考察blog

続:SwiftKueryMySQLを利用してMariaDBに接続

SwiftKueryMySQLを利用して、MariaDBに接続してみました。
Kitura SwiftKueryMySQLを利用してMariaDBに接続

簡単なselectを試しただけなので、データの登録なども試してみたいと思います。


プロジェクトの新規作成



復習も兼ねて、テスト用のプログラムを新規作成します。
実行可能プロジェクトの雛形を作成。


$ mkdir test
$ cd test/
$ swift package init --type executable
Creating executable package: test
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/main.swift
Creating Tests/




Package.swiftに依存関係を追記。


  1. // swift-tools-version:3.1
  2. import PackageDescription
  3. let package = Package(
  4.     name: "test",
  5.     dependencies: [
  6.         .Package(url: "https://github.com/IBM-Swift/SwiftKueryMySQL.git", majorVersion: 0, minor: 13)
  7.     ]
  8. )





main.swiftに検索プログラムを記載


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. let t = MyTable()
  10. // 接続情報
  11. let connection = MySQLConnection(
  12.     host: "localhost",
  13.     user: "admin",
  14.     password: "P@ssw0rd",
  15.     database: "sample",
  16.     port: 3306,
  17.     characterSet: "utf8mb4"
  18. )
  19. connection.connect() { error in
  20.     
  21.     if let error = error {
  22.         print("Error \(error)")
  23.         return
  24.     }
  25.     // クエリー実行
  26.     let query = Select( t.id, t.value, from:t)
  27.                 .where( t.id == 1)
  28.     connection.execute(query: query) { queryResult in
  29.         if let resultSet = queryResult.asResultSet {
  30.             // 結果の取得
  31.             for row in resultSet.rows {
  32.                 for field in row {
  33.                     let val = field ?? ""
  34.                     print("\(val)")
  35.                 }
  36.             }
  37.         } else if let queryError = queryResult.asError {
  38.             print("queryError \(queryError)")
  39.         }
  40.     }
  41. }




ビルドと実行


$ swift build
$ .build/debug/test
1
test




これで前回までの処理に追いつきました。





フィールド名で値取得



ResultSetのtitlesにフィールド名が格納されています。
こんなコードで、[フィールド名:値]の辞書型に変換することができました。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. func fetchRow(_ resultSet:ResultSet, _ row:[Any?]) -> [String:Any?] {
  10.     var dictRow = [String:Any?]();
  11.     for (i, title) in resultSet.titles.enumerated() {
  12.         dictRow[title] = row[i]
  13.     }
  14.     return dictRow
  15. }
  16. let t = MyTable()
  17. // 接続情報
  18. let connection = MySQLConnection(
  19.     host: "localhost",
  20.     user: "admin",
  21.     password: "P@ssw0rd",
  22.     database: "sample",
  23.     port: 3306,
  24.     characterSet: "utf8mb4"
  25. )
  26. connection.connect() { error in
  27.     
  28.     if let error = error {
  29.         print("Error \(error)")
  30.         return
  31.     }
  32.     // クエリー実行
  33.     let query = Select( t.id, t.value, from:t)
  34.                 .where( t.id == 1)
  35.     connection.execute(query: query) { queryResult in
  36.         if let resultSet = queryResult.asResultSet {
  37.             
  38.             // 結果の取得
  39.             for row in resultSet.rows {
  40.                 let dictRow = fetchRow(resultSet, row)
  41.                 print(dictRow["id"] as! Int32)
  42.                 print(dictRow["value"] as! String)
  43.             }
  44.         } else if let queryError = queryResult.asError {
  45.             print("queryError \(queryError)")
  46.         }
  47.     }
  48. }






Iterator



もう少しスマートにIteratorでループするようにしてみます。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. func fetchRows(_ resultSet:ResultSet) -> AnyIterator<[String:Any?]> {
  10.     return AnyIterator<[String:Any?]> {
  11.         // 結果の取得
  12.         for row in resultSet.rows {
  13.             var dictRow = [String:Any?]()
  14.             for (i, title) in resultSet.titles.enumerated() {
  15.                 dictRow[title] = row[i]
  16.             }
  17.             return dictRow
  18.         }
  19.         return nil
  20.     }
  21. }
  22. let t = MyTable()
  23. // 接続情報
  24. let connection = MySQLConnection(
  25.     host: "localhost",
  26.     user: "admin",
  27.     password: "P@ssw0rd",
  28.     database: "sample",
  29.     port: 3306,
  30.     characterSet: "utf8mb4"
  31. )
  32. connection.connect() { error in
  33.     
  34.     if let error = error {
  35.         print("Error \(error)")
  36.         return
  37.     }
  38.     // クエリー実行
  39.     let query = Select( t.id, t.value, from:t)
  40.     connection.execute(query: query) { queryResult in
  41.         if let resultSet = queryResult.asResultSet {
  42.             let rows = fetchRows(resultSet)
  43.             while let row = rows.next() {
  44.                 print(row["id"] as! Int32)
  45.                 print(row["value"] as! String)
  46.             }
  47.         } else if let queryError = queryResult.asError {
  48.             print("queryError \(queryError)")
  49.         }
  50.     }
  51. }








Insert



データ登録のサンプルです。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. let t = MyTable()
  10. // 接続情報
  11. let connection = MySQLConnection(
  12.     host: "localhost",
  13.     user: "admin",
  14.     password: "P@ssw0rd",
  15.     database: "sample",
  16.     port: 3306,
  17.     characterSet: "utf8mb4"
  18. )
  19. connection.connect() { error in
  20.     
  21.     if let error = error {
  22.         print("Error \(error)")
  23.         return
  24.     }
  25.     // クエリー実行
  26.     let query = Insert(into: t, rows: [[1, "apple"], [2, "apricot"], [4, "banana"]])
  27.     
  28.     connection.execute(query: query) { queryResult in
  29.         if let resultSet = queryResult.asResultSet {
  30.             print("query ok")
  31.         } else if let queryError = queryResult.asError {
  32.             print("queryError \(queryError)")
  33.         }
  34.     }
  35. }




実行後のテーブル


MariaDB [sample]> select * from test;
+------+---------+
| id | value |
+------+---------+
|    1 | apple |
|    2 | apricot |
|    4 | banana |
+------+---------+
3 rows in set (0.00 sec)







Update



データ更新のサンプルです。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. let t = MyTable()
  10. // 接続情報
  11. let connection = MySQLConnection(
  12.     host: "localhost",
  13.     user: "admin",
  14.     password: "P@ssw0rd",
  15.     database: "sample",
  16.     port: 3306,
  17.     characterSet: "utf8mb4"
  18. )
  19. connection.connect() { error in
  20.     
  21.     if let error = error {
  22.         print("Error \(error)")
  23.         return
  24.     }
  25.     // クエリー実行
  26.     let query = Update(t, set: [(t.value, "apple-update")])
  27.                 .where(t.id == 1)
  28.     
  29.     connection.execute(query: query) { queryResult in
  30.         if let resultSet = queryResult.asResultSet {
  31.             print("query ok")
  32.         } else if let queryError = queryResult.asError {
  33.             print("queryError \(queryError)")
  34.         }
  35.     }
  36. }




MariaDB [sample]> select * from test;
+------+--------------+
| id | value        |
+------+--------------+
|    1 | apple-update |
|    2 | apricot     |
|    4 | banana     |
+------+--------------+
3 rows in set (0.00 sec)







Delete



削除のサンプルです。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. let t = MyTable()
  10. // 接続情報
  11. let connection = MySQLConnection(
  12.     host: "localhost",
  13.     user: "admin",
  14.     password: "P@ssw0rd",
  15.     database: "sample",
  16.     port: 3306,
  17.     characterSet: "utf8mb4"
  18. )
  19. connection.connect() { error in
  20.     
  21.     if let error = error {
  22.         print("Error \(error)")
  23.         return
  24.     }
  25.     // クエリー実行
  26.     let query = Delete(from: t)
  27.                 .where(t.id == 1)
  28.     
  29.     connection.execute(query: query) { queryResult in
  30.         if let resultSet = queryResult.asResultSet {
  31.             print("query ok")
  32.         } else if let queryError = queryResult.asError {
  33.             print("queryError \(queryError)")
  34.         }
  35.     }
  36. }




MariaDB [sample]> select * from test;
+------+---------+
| id | value |
+------+---------+
|    2 | apricot |
|    4 | banana |
+------+---------+
2 rows in set (0.00 sec)









【参考URL】

Swiftでのenumerateの使い方
Explain Swift Iterators


テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/08/28(月) 00:10:07|
  2. swift
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Kitura SwiftKueryMySQLを利用してMariaDBに接続

UbuntuにSwift 3.1をインストールし、KITURAを動かしてみました。
Web APIフレームワーク「KITURA」をUbuntu + Swift 3.1で動作させる


今回は、SwiftKueryMySQLを使用してMariaDBに接続してみます。
こちらを参考にしました。
Swift-Kueryを利用したMySQLへの接続
SwiftKueryMySQL



MariaDBサーバーの用意とヘッダーファイルのインストール



Swiftをインストールした端末にMariaDB 10.0をインストールしました。
Ubuntu Server 16.04にMariaDB 10.0をインストール

ここで作成したデータベース:sampleに接続してみます。

接続用のライブラリをインストール。


$ sudo apt install libmysqlclient-dev





つづいて、設定ファイルPackage.swiftにSwiftKueryMySQLの依存関係を追記します。


  1. // swift-tools-version:3.1
  2. import PackageDescription
  3. let package = Package(
  4.     name: "myFirstProject",
  5.     dependencies: [
  6.         .Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 1, minor: 7),
  7.         .Package(url: "https://github.com/IBM-Swift/HeliumLogger.git", majorVersion: 1, minor: 7),
  8.         .Package(url: "https://github.com/IBM-Swift/SwiftKueryMySQL.git", majorVersion: 0, minor: 13)
  9.     ]
  10. )




とりあえず検索できたソースコードはこちら。


  1. import Kitura
  2. import SwiftyJSON
  3. import HeliumLogger
  4. import LoggerAPI
  5. import Foundation
  6. import SwiftKuery
  7. import SwiftKueryMySQL
  8. // 検索するテーブルの定義
  9. class MyTable : Table {
  10.     let id = Column("id")
  11.     let value = Column("value")
  12.     let tableName = "test"
  13. }
  14. // Initialize HeliumLogger
  15. let logger = HeliumLogger()
  16. // let logger = HeliumLogger(.warning)で、出力レベルの指定可能
  17. Log.logger = logger
  18. // Create a new router
  19. let router = Router()
  20. // bodyを解析
  21. // ※注意 router.postを設定する前に呼び出すこと
  22. router.all("/hello", middleware: BodyParser())
  23. // Handle HTTP GET requests to /
  24. router.post("/hello") { request, response, next in
  25.     let t = MyTable()
  26.     // 接続情報
  27.     let connection = MySQLThreadSafeConnection(
  28.         host: "localhost",
  29.         user: "admin",
  30.         password: "P@ssw0rd",
  31.         database: "sample",
  32.         port: 3306,
  33.         characterSet: "utf8mb4"
  34.     )
  35.     connection.connect() { error in
  36.         
  37.         if let error = error {
  38.             Log.info("Error \(error)")
  39.             return
  40.         }
  41.         // クエリー実行
  42.         let query = Select( t.id, t.value, from:t)
  43.                     .where( t.id == 1)
  44.         connection.execute(query: query) { queryResult in
  45.             if let resultSet = queryResult.asResultSet {
  46.                 // 結果の取得
  47.                 for row in resultSet.rows {
  48.                     for field in row {
  49.                         let val = field ?? ""
  50.                         Log.info("\(val)")
  51.                     }
  52.                 }
  53.             } else if let queryError = queryResult.asError {
  54.                 Log.info("queryError \(queryError)")
  55.             }
  56.         }
  57.     }
  58.     next()
  59.     
  60. }
  61. // テスト用のpublic/index.htmlを配信
  62. router.all("/static", middleware: StaticFileServer())
  63. // Add an HTTP server and connect it to the router
  64. Kitura.addHTTPServer(onPort: 8080, with: router)
  65. // Start the Kitura runloop (this call never returns)
  66. Kitura.run()




ビルドしてサーバーを起動


$ swift build
$ .build/debug/myFirstProject




/helloに適当な値をpostすると、ログに検索結果が表示されました。


ただ、この方法だと検索結果のフィールドに番号でアクセスすることになりそうです。
フィールド名でアクセスする方法を調べてみます。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/08/27(日) 23:15:06|
  2. swift
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

KITURA BodyParserによるリクエスト内容の取得・分岐

Ubuntu 16.04にSwift 3.1をインストール
Web APIフレームワークの「KITARU」を動かしてみました。

Web APIフレームワーク「KITURA」をUbuntu + Swift 3.1で動作させる
Kitura 1.0 リクエストクエリーの解析(BodyParser)


BodyParser、パース後の状態で送られたデータが何だったのか判定できるようです。
使い方を調べてみます。


BodyParser



https://ibm-swift.github.io/Kitura/index.html

こちらのParsedBodyの項目を見てみると、
https://ibm-swift.github.io/Kitura/Enums/ParsedBody.html


・json
・urlEncoded
・text
・raw
・multipart



と分類できるようです。
それぞれ試してみます。





json



まず、jsonをpostしてみます。
前回も試したのでおさらいになります。
Kitura 1.0 リクエストクエリーの解析(BodyParser)

送信テストはjQueryで行いました。


  1. <!doctype html>
  2. <html lang="ja">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>KITURA</title>
  6.     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  7. <script>
  8. $(function(){
  9.     $('#run').on('click', function() {
  10.         $.ajax({
  11.             url:'../hello',
  12.             type: 'POST',
  13.             contentType: 'application/json',
  14.             data : JSON.stringify({'name': 'Symfo'})
  15.         }).done(function(data) {
  16.             console.log(data);
  17.             $('#result').html(data);
  18.         });
  19.     });
  20. })
  21. </script>
  22. </head>
  23. <body>
  24. <div>
  25.     <input type="button" id="run" value="click">
  26. </div>
  27. <div id="result"></div>
  28. </body>
  29. </html>




受け取ったデータを解析。返信するサンプルです。


  1. import Kitura
  2. import SwiftyJSON
  3. import HeliumLogger
  4. import LoggerAPI
  5. // Initialize HeliumLogger
  6. let logger = HeliumLogger()
  7. // let logger = HeliumLogger(.warning)で、出力レベルの指定可能
  8. Log.logger = logger
  9. // Create a new router
  10. let router = Router()
  11. // bodyを解析
  12. // ※注意 router.postを設定する前に呼び出すこと
  13. router.all("/hello", middleware: BodyParser())
  14. // Handle HTTP GET requests to /
  15. router.post("/hello") { request, response, next in
  16.     guard let parsedBody = request.body else {
  17.         next()
  18.         return
  19.     }
  20.     switch(parsedBody) {
  21.     case .json(let jsonBody):
  22.             let name = jsonBody["name"].string ?? ""
  23.             try response.send("[.json] Hello \(name)").end()
  24.     default:
  25.         break
  26.     }
  27.     next()
  28.     
  29. }
  30. // テスト用のpublic/index.htmlを配信
  31. router.all("/static", middleware: StaticFileServer())
  32. // Add an HTTP server and connect it to the router
  33. Kitura.addHTTPServer(onPort: 8080, with: router)
  34. // Start the Kitura runloop (this call never returns)
  35. Kitura.run()




ちゃんと.jsonの分岐に入って応答してくれたようです。

792_01.png





urlEncoded



続いてurlEncodedのサンプルです。

jQuery側


  1. <!doctype html>
  2. <html lang="ja">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>KITURA</title>
  6.     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  7. <script>
  8. $(function(){
  9.     $('#run').on('click', function() {
  10.         $.ajax({
  11.             url:'../hello',
  12.             type: 'POST',
  13.             data : {'name': 'Symfo'}
  14.         }).done(function(data) {
  15.             console.log(data);
  16.             $('#result').html(data);
  17.         });
  18.     });
  19. })
  20. </script>
  21. </head>
  22. <body>
  23. <div>
  24.     <input type="button" id="run" value="click">
  25. </div>
  26. <div id="result"></div>
  27. </body>
  28. </html>




サーバー側のswift


  1. import Kitura
  2. import SwiftyJSON
  3. import HeliumLogger
  4. import LoggerAPI
  5. // Initialize HeliumLogger
  6. let logger = HeliumLogger()
  7. // let logger = HeliumLogger(.warning)で、出力レベルの指定可能
  8. Log.logger = logger
  9. // Create a new router
  10. let router = Router()
  11. // bodyを解析
  12. // ※注意 router.postを設定する前に呼び出すこと
  13. router.all("/hello", middleware: BodyParser())
  14. // Handle HTTP GET requests to /
  15. router.post("/hello") { request, response, next in
  16.     guard let parsedBody = request.body else {
  17.         next()
  18.         return
  19.     }
  20.     switch(parsedBody) {
  21.     case .json(let jsonBody):
  22.             let name = jsonBody["name"].string ?? ""
  23.             try response.send("[.json] Hello \(name)").end()
  24.     case .urlEncoded(let postParam):
  25.             let name = postParam["name"] ?? ""
  26.             try response.send("[.urlEncoded] Hello \(name)").end()
  27.     default:
  28.         break
  29.     }
  30.     next()
  31.     
  32. }
  33. // テスト用のpublic/index.htmlを配信
  34. router.all("/static", middleware: StaticFileServer())
  35. // Add an HTTP server and connect it to the router
  36. Kitura.addHTTPServer(onPort: 8080, with: router)
  37. // Start the Kitura runloop (this call never returns)
  38. Kitura.run()




狙い通り。

792_02.png





text



textデータの送信を行ってみます。

送信側


  1. <!doctype html>
  2. <html lang="ja">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>KITURA</title>
  6.     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  7. <script>
  8. $(function(){
  9.     $('#run').on('click', function() {
  10.         $.ajax({
  11.             url:'../hello',
  12.             type: 'POST',
  13.             contentType: 'text',
  14.             data : 'Symfo'
  15.         }).done(function(data) {
  16.             console.log(data);
  17.             $('#result').html(data);
  18.         });
  19.     });
  20. })
  21. </script>
  22. </head>
  23. <body>
  24. <div>
  25.     <input type="button" id="run" value="click">
  26. </div>
  27. <div id="result"></div>
  28. </body>
  29. </html>




サーバー側


  1. import Kitura
  2. import SwiftyJSON
  3. import HeliumLogger
  4. import LoggerAPI
  5. // Initialize HeliumLogger
  6. let logger = HeliumLogger()
  7. // let logger = HeliumLogger(.warning)で、出力レベルの指定可能
  8. Log.logger = logger
  9. // Create a new router
  10. let router = Router()
  11. // bodyを解析
  12. // ※注意 router.postを設定する前に呼び出すこと
  13. router.all("/hello", middleware: BodyParser())
  14. // Handle HTTP GET requests to /
  15. router.post("/hello") { request, response, next in
  16.     guard let parsedBody = request.body else {
  17.         next()
  18.         return
  19.     }
  20.     switch(parsedBody) {
  21.     case .json(let jsonBody):
  22.             let name = jsonBody["name"].string ?? ""
  23.             try response.send("[.json] Hello \(name)").end()
  24.     case .urlEncoded(let postParam):
  25.             let name = postParam["name"] ?? ""
  26.             try response.send("[.urlEncoded] Hello \(name)").end()
  27.     case .text(let name):
  28.             try response.send("[.text] Hello \(name)").end()
  29.     default:
  30.         break
  31.     }
  32.     next()
  33.     
  34. }
  35. // テスト用のpublic/index.htmlを配信
  36. router.all("/static", middleware: StaticFileServer())
  37. // Add an HTTP server and connect it to the router
  38. Kitura.addHTTPServer(onPort: 8080, with: router)
  39. // Start the Kitura runloop (this call never returns)
  40. Kitura.run()




792_03.png





raw



rawデータの送信について見てみます。

送信サンプル
※contentTypeは
「application/json」「application/x-www-form-urlencoded」「text」
以外を指定すればOKの模様


  1. <!doctype html>
  2. <html lang="ja">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>KITURA</title>
  6.     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  7. <script>
  8. $(function(){
  9.     $('#run').on('click', function() {
  10.         $.ajax({
  11.             url:'../hello',
  12.             type: 'POST',
  13.             contentType: 'raw',
  14.             data : 'Symfo'
  15.         }).done(function(data) {
  16.             console.log(data);
  17.             $('#result').html(data);
  18.         });
  19.     });
  20. })
  21. </script>
  22. </head>
  23. <body>
  24. <div>
  25.     <input type="button" id="run" value="click">
  26. </div>
  27. <div id="result"></div>
  28. </body>
  29. </html>





サーバー側


  1. import Kitura
  2. import SwiftyJSON
  3. import HeliumLogger
  4. import LoggerAPI
  5. // Initialize HeliumLogger
  6. let logger = HeliumLogger()
  7. // let logger = HeliumLogger(.warning)で、出力レベルの指定可能
  8. Log.logger = logger
  9. // Create a new router
  10. let router = Router()
  11. // bodyを解析
  12. // ※注意 router.postを設定する前に呼び出すこと
  13. router.all("/hello", middleware: BodyParser())
  14. // Handle HTTP GET requests to /
  15. router.post("/hello") { request, response, next in
  16.     guard let parsedBody = request.body else {
  17.         next()
  18.         return
  19.     }
  20.     switch(parsedBody) {
  21.     case .json(let jsonBody):
  22.             let name = jsonBody["name"].string ?? ""
  23.             try response.send("[.json] Hello \(name)").end()
  24.     case .urlEncoded(let postParam):
  25.             let name = postParam["name"] ?? ""
  26.             try response.send("[.urlEncoded] Hello \(name)").end()
  27.     case .text(let name):
  28.             try response.send("[.text] Hello \(name)").end()
  29.     case .raw(let name):
  30.             try response.send("[.raw] Hello \(name)").end()
  31.     default:
  32.         break
  33.     }
  34.     next()
  35.     
  36. }
  37. // テスト用のpublic/index.htmlを配信
  38. router.all("/static", middleware: StaticFileServer())
  39. // Add an HTTP server and connect it to the router
  40. Kitura.addHTTPServer(onPort: 8080, with: router)
  41. // Start the Kitura runloop (this call never returns)
  42. Kitura.run()



792_04.png


.rawの場合、取得できるデータはData型です。
Stringに変換してやれば文字列が表示できます。


  1.     case .raw(let name):
  2.             let nameString = String(data:name, encoding: .utf8) ?? ""
  3.             try response.send("[.raw] Hello \(nameString)").end()




792_05.png





multipart



ファイルのアップロードを行ってみます。

アップロードのサンプル


  1. <!doctype html>
  2. <html lang="ja">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>KITURA</title>
  6.     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  7. <script>
  8. $(function(){
  9.     $('#run').on('click', function() {
  10.         var fd = new FormData();
  11.         fd.append( "file", $("#post_file").prop("files")[0] );
  12.         $.ajax({
  13.             url:'../hello',
  14.             type: 'POST',
  15.             processData : false,
  16.             contentType : false,
  17.             data : fd
  18.         }).done(function(data) {
  19.             console.log(data);
  20.             $('#result').html(data);
  21.         });
  22.     });
  23. })
  24. </script>
  25. </head>
  26. <body>
  27. <div>
  28.     <input type="file" id="post_file">
  29.     <input type="button" id="run" value="click">
  30. </div>
  31. <div id="result"></div>
  32. </body>
  33. </html>




ファイルの受け取り側


  1. import Kitura
  2. import SwiftyJSON
  3. import HeliumLogger
  4. import LoggerAPI
  5. import Foundation
  6. // Initialize HeliumLogger
  7. let logger = HeliumLogger()
  8. // let logger = HeliumLogger(.warning)で、出力レベルの指定可能
  9. Log.logger = logger
  10. // Create a new router
  11. let router = Router()
  12. // bodyを解析
  13. // ※注意 router.postを設定する前に呼び出すこと
  14. router.all("/hello", middleware: BodyParser())
  15. // Handle HTTP GET requests to /
  16. router.post("/hello") { request, response, next in
  17.     guard let parsedBody = request.body else {
  18.         next()
  19.         return
  20.     }
  21.     switch(parsedBody) {
  22.     case .json(let jsonBody):
  23.         let name = jsonBody["name"].string ?? ""
  24.         try response.send("[.json] Hello \(name)").end()
  25.     case .urlEncoded(let postParam):
  26.         let name = postParam["name"] ?? ""
  27.         try response.send("[.urlEncoded] Hello \(name)").end()
  28.     case .text(let name):
  29.         try response.send("[.text] Hello \(name)").end()
  30.     case .raw(let name):
  31.         let nameString = String(data:name, encoding: .utf8) ?? ""
  32.         try response.send("[.raw] Hello \(nameString)").end()
  33.     case .multipart(let parts):
  34.         for part in parts {
  35.             let outputFile = URL(fileURLWithPath: "/tmp/" + part.filename)
  36.             switch(part.body) {
  37.                 case .raw(let file):
  38.                     try file.write( to: outputFile )
  39.                 default:
  40.                     break
  41.             }
  42.         }
  43.         try response.send("[.multipart] Hello").end()
  44.     }
  45.     next()
  46.     
  47. }
  48. // テスト用のpublic/index.htmlを配信
  49. router.all("/static", middleware: StaticFileServer())
  50. // Add an HTTP server and connect it to the router
  51. Kitura.addHTTPServer(onPort: 8080, with: router)
  52. // Start the Kitura runloop (this call never returns)
  53. Kitura.run()





これで/tmpフォルダにアップロードしたファイルを復元出来ました。

792_06.png



【参考URL】

https://github.com/IBM-Swift/Kitura/tree/master/Sources/Kitura/bodyParser




テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/08/27(日) 17:09:24|
  2. swift
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Swift 3.1 コンソール実行でファイルの読み書き

Ubuntu 16.04にインストールしたSwift
Ubuntu 16.04にSwift 3.1.1をインストール

この環境でファイルの読み書きを行ってみます。


テキストファイルの書き込み




"文字列".writeでOK
...なのですが、ずっとto: にファイル名をStringで渡してエラーになりはまってました。

to: URL
toPath: String

toPathでファイル名を指定して出力だと、簡単にファイル出力できます。


  1. import Foundation
  2. //var file_url = URL(string: "file:///var/dev/swift/file/data.txt")!
  3. let file_name = "data.txt"
  4. let text = "ファイルに保存する文字列"
  5. do {
  6.     //try text.write(to: file_url, atomically: true, encoding: String.Encoding.utf8)
  7.     try text.write(toFile: file_name, atomically: true, encoding: String.Encoding.utf8)
  8. } catch let message {
  9.     print("error!")
  10.     print(message)
  11. }




こちらに救われました。
[Swift3.0] パスとファイルURLの違いと相互変換の方法





テキストファイルの読み込み



先ほど出力したファイルを読み込んでみます。


  1. import Foundation
  2. //var file_url = URL(string: "file:///var/dev/swift/file/data.txt")!
  3. let file_name = "data.txt"
  4. do {
  5.     //let text = try String( contentsOf: file_url, encoding: String.Encoding.utf8 )
  6.     let text = try String( contentsOfFile: file_name, encoding: String.Encoding.utf8 )
  7.     print( text )
  8. } catch let message {
  9.     print("error!")
  10.     print(message)
  11. }




contentsOf: URL、またはcontentsOfFile: Stringで読み込めます。


実行結果


$ swift sample.swift
ファイルに保存する文字列







バイナリファイルの読み書き



バイナリファイルを読み込み、別名で出力してみます。


  1. import Foundation
  2. // 入力ファイル
  3. let inputURL = URL(fileURLWithPath: "image.jpg")
  4. // 出力ファイル
  5. let outputURL = URL(fileURLWithPath: "image_copy.jpg")
  6. do {
  7.     let data = try Data( contentsOf: inputURL )
  8.     print( data )
  9.     try data.write( to: outputURL )
  10. } catch let message {
  11.     print("error!")
  12.     print(message)
  13. }




こちらが参考になりました。
swiftでバイナリファイルの読み書きを行いたい

URL(fileURLWithPath: "path/to/file")

という記載方法があるとは。
勉強になります。


これで画像ファイルのコピーが行えました。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/08/24(木) 23:55:28|
  2. swift
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Kitura 1.0 プログラム中からログの出力

Kitura 1.0 リクエストクエリーの解析(BodyParser)

ここで思い通りプログラムが動いてくれず、ログの出力方法を調べたのでメモしておきます。

HeliumLogger



こちらを参考にしました。
HeliumLogger


  1. import Kitura
  2. import SwiftyJSON
  3. import HeliumLogger
  4. import LoggerAPI
  5. // Initialize HeliumLogger
  6. let logger = HeliumLogger()
  7. // let logger = HeliumLogger(.warning)で、出力レベルの指定可能
  8. Log.logger = logger
  9. // Create a new router
  10. let router = Router()
  11. // bodyを解析
  12. // ※注意 router.postを設定する前に呼び出すこと
  13. router.all("/hello", middleware: BodyParser())
  14. // Handle HTTP GET requests to /
  15. router.post("/hello") { request, response, next in
  16.     // infoレベルでログを出力
  17.     Log.info("test log")
  18.     guard let parsedBody = request.body else {
  19.         next()
  20.         return
  21.     }
  22.     switch(parsedBody) {
  23.     case .json(let jsonBody):
  24.             let name = jsonBody["name"].string ?? ""
  25.             try response.send("Hello \(name)").end()
  26.     default:
  27.         break
  28.     }
  29.     next()
  30.     
  31. }
  32. // テスト用のpublic/index.htmlを配信
  33. router.all("/static", middleware: StaticFileServer())
  34. // Add an HTTP server and connect it to the router
  35. Kitura.addHTTPServer(onPort: 8080, with: router)
  36. // Start the Kitura runloop (this call never returns)
  37. Kitura.run()





ロガーの作成


  1. import HeliumLogger
  2. import LoggerAPI
  3. // Initialize HeliumLogger
  4. let logger = HeliumLogger()
  5. // let logger = HeliumLogger(.warning)で、出力レベルの指定可能
  6. Log.logger = logger




ログの出力


  1. // infoレベルでログを出力
  2. Log.info("test log")





出力レベルは以下の通り。


  1. Log.verbose("This is a verbose log message.")
  2. Log.info("This is an informational log message.")
  3. Log.warning("This is a warning.")
  4. Log.error("This is an error.")
  5. Log.debug("This is a debug message.")





こんな感じでコンソールに出力されます。


$ .build/debug/myFirstProject
[2017-08-24T14:07:12.139Z] [VERBOSE] [Router.swift:74 init(mergeParameters:)] Router initialized
[2017-08-24T14:07:12.152Z] [VERBOSE] [Kitura.swift:72 run()] Starting Kitura framework...
[2017-08-24T14:07:12.153Z] [VERBOSE] [Kitura.swift:82 start()] Starting an HTTP Server on port 8080...
[2017-08-24T14:07:12.154Z] [INFO] [HTTPServer.swift:117 listen(on:)] Listening on port 8080
[2017-08-24T14:15:40.498Z] [VERBOSE] [HTTPServerRequest.swift:215 parsingCompleted()] HTTP request from=192.168.1.4; proto=http;
[2017-08-24T14:15:40.499Z] [INFO] [main.swift:21 myFirstProject] test log



テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/08/24(木) 23:17:16|
  2. swift
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ