更新日:2017年01月27日

投稿日:2017年01月02日

0. 環境

[Swift] 3.0.2

1. 大文字・小文字処理

  • Swift3から大文字・小文字の処理は下記のようになります。

    (明示的にするため入れていますが型宣言は省略可)

    // ----------------------------------------
    // String型を使った大文字・小文字変換
    // ----------------------------------------
    let uppercase:String = "TEST"
    print( "大文字→小文字:" + uppercase.lowercased() )
    
    let lowercase:String = "test"
    print( "小文字→大文字:" + lowercase.uppercased() )
    
    // ----------------------------------------
    // NSString型による大小文字を無視した比較
    // ----------------------------------------
    import Foundation
    
    let singleByteChar:NSString = "Test" //String型でもOK
    if singleByteChar.caseInsensitiveCompare("test") == ComparisonResult.orderedSame {
        print("testと一致")
    }
    
    //全角文字の比較も可能。
    let doubleByteChar:NSString = "TEST"
    if doubleByteChar.localizedCaseInsensitiveCompare("test") == ComparisonResult.orderedSame {
        print("testと一致")
    }
    
  • 上記コードはIBM Swift Sandboxで動かせます。

    下記リンク先の真ん中にある三角ボタンをクリックして下さい。

    Swift3で大文字・小文字処理

    (ChromeまたはFirefox推奨)

2. 参考ページ

 更新日:2017年02月09日

投稿日:2016年12月29日

0. 環境

[Swift] 3.0.2

1. ループ

  • Swift3からループ処理は下記のようになります。
  • 上記コードはIBM Swift Sandboxで実際に動かすことができます。

    下記リンク先の真ん中にある三角ボタンをクリックして下さい。

    Swift3でのforループ

    (ChromeまたはFirefox推奨)

投稿日:2016年12月24日

0. 環境

[CentOS] 6.8 (64bit版カーネル)
[Apache] 2.2.15

1. 問題

  • ApacheのProxyPassディレクティブ(mod_proxy)を指定して、バックエンドから受け取ったコンテンツを表示しようとするとhtmlタグがそのまま表示されてしまいます。

    • Apache設定ファイルの抜粋

      NameVirtualHost *:80
      
      # 省略
      
      <VirtualHost *:80>
          ServerAdmin test@local
          ServerName test.local
      
          ProxyPreserveHost On
          ProxyPass / http://127.0.0.1:8080/
          ProxyPassReverse / http://127.0.0.1:8080/
      
          ErrorLog logs/test.local-error_log
          CustomLog logs/test.local-access_log combined
      </VirtualHost>
      

2. 対策

  • ChromeのDeveloper Toolsなどで見ると、下記のようにHTTPレスポンスヘッダーで平文が指定されています。

    Content-Type text/plain; charset=UTF-8

  • デフォルトのMIMEタイプ指定を無効にすることで解消しました。

    • Apache設定ファイルの抜粋

      NameVirtualHost *:80
      
      # 省略
      
      <VirtualHost *:80>
          ServerAdmin test@local
          ServerName test.local
      
          # ----- この行を追加 ----- 
          DefaultType None
          # ----- この行を追加 ----- 
      
          ProxyPreserveHost On
          ProxyPass / http://127.0.0.1:8080/
          ProxyPassReverse / http://127.0.0.1:8080/
      
          ErrorLog logs/test.local-error_log
          CustomLog logs/test.local-access_log combined
      </VirtualHost>
      

3. 参考ページ

投稿日:2016年11月20日

0. 環境

[OS] Mac OS X 10.11.6
[IDE] Xcode 8.1
[Swift] 3.0

1. 問題

  • WCSession#sendMessage()を使ってAppleWatchからiPhoneアプリへメッセージを送っても、30秒ほどしないと通知されない。

    • AppleWatch側

      @IBAction func tapButton() {
      
          let message = [ "fromChild": "AppleWatchからのメッセージ" ]
      
          WCSession.default().sendMessage(
                  message
                  , replyHandler: { reply in }
                  , errorHandler: { error in }
          )
      
      }
      
    • iPhone側

      func session(_ session: WCSession, didReceiveMessage message: [String: Any], replyHandler: @escaping ([String: Any]) -> Void) {
      
          if let watchMessage = message["fromChild"] as? String {
              print(watchMessage)
          }
          else{
              print("error")
          }
      
      }
      

2. 対策

  • replyHandlerを設定するなど、いろいろ情報はあったのですが、結局 sendMessage() を諦め、updateApplicationContext() を使うことにしました。

  • ただ updateApplicationContext() は状態が変わった際に通知するためのメソッドなので、二回目以降の値が変わらないとiPhone側のメソッドが呼び出されません。

    API仕様書には明記されていませんがそのような動きをしています。(「3. 参考ページ」参照)

    ですので、sendMessage() と同じように使いたい場合は、毎回変わる値をダミーとして設定すると実現できます。(多少強引ですが、下記例では時間を設定しています)

    • AppleWatch側

      @IBAction func tapButton() {
      
          let dateFormatter = DateFormatter()
          dateFormatter.locale = Locale(identifier: "ja_JP")
          dateFormatter.timeStyle = .medium
          dateFormatter.dateStyle = .medium
      
          let item: Dictionary<String, String> = [
              "message": "AppleWatchからのメッセージ"
              , "date": dateFormatter.string(from: NSDate() as Date)]
      
          let message = [ "fromChild": item ]
      
          do{
              try WCSession.default().updateApplicationContext(message)
          }catch{
              print(error)
          }
      
      }
      
    • iPhone側

      func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
      
          DispatchQueue.main.async { () -> Void in
              if let watchMessage = applicationContext["fromChild"] as? Dictionary<String, String> {
                  self.label.text = watchMessage["message"]! as String
              }
          }
          return
      
      }
      

3. 参考ページ

投稿日:2016年11月14日

0. 環境

[OS] Mac OS X 10.11.6
[IDE] Xcode 8.1
[Swift] 3.0

1. 問題

  • iPhone & AppleWatchアプリを作成中にSwiftを2.2から3へバージョンアップしたところ、iPhone側で下記のエラーが出るようになりました。

    Type 'ViewController' does not conform to protocol 'WCSessionDelegate'

2. 解決

  • ViewControllerに下記メソッドを追加するとエラーが消えました。

    public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
    }
    
    func sessionDidBecomeInactive(_ session: WCSession) {
    }
    
    func sessionDidDeactivate(_ session: WCSession) {
        session.activate()
    }
    

    下記の仕様書にもこれらのメソッドは必須と書かれています。

    [API Reference] WCSessionDelegate

3. 参考ページ

【免責事項】

本ブログのご利用につき、何らかのトラブルや損失・損害等につきましては一切責任を問わないものとします。