2017年5月14日日曜日

JSONを読む(Dictionary編)

こんな感じのデータのvalueを読みます
{"hogedata":"http://hoge.com/image/hoge.png"}




// NSUrlSessionのハンドラ
    func onFinishUri(data: NSData?, res: NSURLResponse?, error: NSError?){
        var dict:NSDictionary
        do{
            dict = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
            // let str = String(data)
            // print(str)        // {"hogedata":"http://hoge.com/image/hoge.png"}
            let uri = dict["hogedata"] as! String // URLを取得
            print(uri)
        } catch {
            print("error")
            return
        }
    }

2017年5月13日土曜日

NSUrlSessionでハンドラを指定して画像を取得・表示する

1. UIImageをMain.storyboardに貼る
2. UIImageからviewController.swiftにIBOutletを貼る
3. NSUrlSessinoで取得した時のハンドラを書く
    // 画像を取得した時に呼び出されるハンドラ
    func onFinishImage(data: NSData?, res: NSURLResponse?, error: NSError?){
        uiImage = UIImage(data: data!)!
        // バックグラウンドだとUIの処理が出来ないので、メインスレッドでUIの処理を行わせる.
        dispatch_async(dispatch_get_main_queue(), {
            self.uiImageView.image = self.uiImage
        })

        // 続きの処理があればこの辺に書いておく
    }
4. NSUrlSessinでデータを取得する処理を書く(データ取得後は↑のハンドラを呼び出すようにする)
    func getImageImg(uri:String){
        let url = NSURL(string: uri)
        let urlSession = NSURLSession.sharedSession()
        let task = urlSession.dataTaskWithURL(url!, completionHandler: onFinishImage)
        task.resume()
    }

5. ViewDidLoadなどで↑を呼び出す
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let urlString = "http://hogehoge.co.jp/hoge.img"
        getImageImg(urlString)
    }

2017年4月20日木曜日

AVSpeechSynthesizerでテキスト読み上げ

 テキストだけ差し替える方法があるかもしれないけど、読み上げテキストで初期化する方法でも大丈夫。

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var talker = AVSpeechSynthesizer()
    let talkTxt = "こんにちわ、今日はいい天気ですね"
    let talkText2 = "テキスト2"
    let talkTextEng = "hello"
   
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
       
        // 読み上げ内容を初期化
        var utterance = AVSpeechUtterance(string: talkTxt)
        // 日本語
        utterance.voice = AVSpeechSynthesisVoice(language: "ja-JP")
        // 読み上げ
        self.talker.speakUtterance(utterance)

        // 2回目
        utterance = AVSpeechUtterance(string: talkText2)
        utterance.voice = AVSpeechSynthesisVoice(language: "ja-JP") // defaultは英語なので毎回指定
        self.talker.speakUtterance(utterance)

        // 英語文を日本語で(読める)
        utterance = AVSpeechUtterance(string: talkTextEng)
        utterance.voice = AVSpeechSynthesisVoice(language: "ja-JP")
        self.talker.speakUtterance(utterance)

        // utterance.speechString = "こんにちわ"  // get onlyなのでテキストのみ差し替えはできない?
        // self.talker.speakUtterance(utterance)
    }

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


}

2017年4月5日水曜日

optionalとアンラップ

- nilを許可する場合はOptional型として "?"をつける
- 使用するときはアンラップ < "!"で強制アンラップ
  let unlap = optionalString! 
- オプショナルバインディングで安全にアンラップ
  if let opt = optionalString {   // オプショナルバインディングでfalse
      print("アンラップしました -> " + opt)
  }

// optionalとは??
var nonOptionalString:String = "hello"  // optionalじゃなくString型
print(nonOptionalString)

nonOptionalString = "hoge"
print(nonOptionalString)

// nonOptionalString = nil     // ここでエラー "nil cannot be assigned to type 'String'
// print(nonOptionalString)     // nilを入れることが出来ない為

// optional型で宣言
var optionalString:String? = "hello"    // ?をつけるとOptional型になる
print(optionalString)           // Optinal("hello")と表示される

optionalString = nil        // nil代入もOK
print(optionalString)       // "nil"と表示される

if let opt = optionalString {   // オプショナルバインディングでfalse
    print("アンラップしました -> " + opt)
} else {
    print("nilが入っている")  // こっちが表示される
}

optionalString = "hoge"
if let opt = optionalString {   // オプショナルバインディングでアンラップ
    print("アンラップしました -> " + opt)    // アンラップされたこっちが表示される
} else {
    print("nilが入っている")
}

2017年4月2日日曜日

http requestをNSURLSessionのdelegateで

NRURLSessionでhttp requestの結果をdelegateで受けてみます。

//
//  ViewController.swift
//

import UIKit

class ViewController: UIViewController, NSURLSessionDelegate, NSURLSessionDataDelegate {

    @IBOutlet weak var urlDataDisp: UITextView!
   
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
       
        getUrlData("http://tantan2014.blogspot.jp/2017/01/mapkit-viewannotation.html")
    }

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


    func getUrlData(targetUri: String){
        // 通信用のConfigを生成.
        let config: NSURLSessionConfiguration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("backgroundTask")
        // Sessionを生成.
        let session: NSURLSession = NSURLSession(configuration: config, delegate: self, delegateQueue: nil)
        // 通信先のURLを生成.
        let url: NSURL = NSURL(string: targetUri as String)!
        // タスクの生成.
        let task: NSURLSessionDataTask = session.dataTaskWithURL(url)
        // タスクの実行.
        task.resume()
    }
   
    /*
     通信が終了したときに呼び出されるデリゲート.
     */
    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
        print("NSURLSessionDataTask")
       
        // 帰ってきたデータを文字列に変換.
        let getData: NSString = NSString(data: data, encoding: NSUTF8StringEncoding)!
       
        // バックグラウンドだとUIの処理が出来ないので、メインスレッドでUIの処理を行わせる.
        dispatch_async(dispatch_get_main_queue(), {
            self.urlDataDisp.text = getData as String
        })
    }
   
    /*
    
     バックグラウンドからフォアグラウンドの復帰時に呼び出されるデリゲート.
    
     */
    func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) {
       
        print("URLSessionDidFinishEventsForBackgroundURLSession")
       
    }
}



ご説明はこちらが詳しいです。
http://qiita.com/aKentaKoyama/items/96a979ab3a140e7b39ec

2017年2月27日月曜日

メールの送信をしてみる

MFMailComposeViewController を使うと、
- Swiftのアプリで送信先・題名・本文を生成
- メール送信アプリで送信(iPhoneなどのアカウントで)
という動作ができるようです。
(androidのintentのような感じ)


準備 : MessageUI.frameworkをlink libraryに追加
1. プロジェクトを選択
2. Build Phasesタブ -> Link Binary With Libralies
3. MessageUI.frameworkを選択

コード上のポイント
- ViewControllerに MFMailComposeViewControllerDelegate を追加
- viewDidLoadedに
 composeVC = MFMailComposeViewController() を追加
- composeVCに対して、to/cc/bcc/subject/bodyを追加する
- self.presentViewController(composeVC, animated: true, completion: nil) でメール画面に遷移
- delegateに以下を追加
 self.dismissViewControllerAnimated(true, completion: nil)

---
import UIKit
import MessageUI

class ViewController: UIViewController, MFMailComposeViewControllerDelegate{

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
       
        // メール対応
        let composeVC = MFMailComposeViewController()
        composeVC.mailComposeDelegate = self
   
    }

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

    @IBAction func buttonA(sender: AnyObject) {
        makeFixedForm("本文a")
    }
   
   
    @IBAction func buttonB(sender: AnyObject) {
        makeFixedForm("本文b")
    }
   
    // メール定型文書作成
    func makeFixedForm(subj:String){
        let toRecipients = ["送信先1", "送信先2"]
        let ccRecipients = ["cc送信先"]
        let bccRecipients = [""]
        let subject = subj
        let messageBody = "本文です"
       
        sendMail(toRecipients, cc: ccRecipients, bcc: bccRecipients, subj: subject, msg: messageBody)
    }
   
    // 終了デリゲート
    func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {
        if result == MFMailComposeResultCancelled {
            print("canceld")
        } else if result == MFMailComposeResultSaved {
            print("saved")
        } else if result == MFMailComposeResultSent {
            print("sent")
        } else if result == MFMailComposeResultFailed {
            print("failed")
        }
        self.dismissViewControllerAnimated(true, completion: nil)
    }
   
    // 引数の内容でメールアプリを起動する
    func sendMail(to:[String], cc:[String], bcc:[String], subj:String, msg: String){
        if !MFMailComposeViewController.canSendMail() {
            print("Mail services are not available")
            return
        }
        let composeVC = MFMailComposeViewController()
        composeVC.mailComposeDelegate = self
       
        var toRecipients:[String] = []
        var ccRecipients:[String] = []
        var bccRecipients:[String] = []
        var subject:String
        var messageBody:String
       
        // TODO:ちゃんとチェックする事
        if(to.count != 0){
            for toMember in to {
                toRecipients.append(toMember)
            }
        }
        if(cc.count != 0){
            for ccMember in cc {
                ccRecipients.append(ccMember)
            }
        }
        if(bcc.count != 0){
            for bccMember in bcc {
                bccRecipients.append(bccMember)
            }
        }
        subject = subj
        messageBody = msg
       
        // Configure the fields of the interface.
        /*
        composeVC.setToRecipients(["送信先1", "送信先2"]
        composeVC.setBccRecipients(["cc送信先"])
        composeVC.setSubject("こんにちわ!")
        composeVC.setMessageBody("Hello from California!", isHTML: false)
        */
       
        if(toRecipients.count > 0){
            composeVC.setToRecipients(toRecipients)
        }
        if(ccRecipients.count > 0){
            composeVC.setCcRecipients(ccRecipients)
        }
        if(bccRecipients.count > 0){
            composeVC.setBccRecipients(bccRecipients)
        }
        if(subject.characters.count > 0){
            composeVC.setSubject(subject)
        }
        if(messageBody.characters.count > 0){
            composeVC.setMessageBody(messageBody, isHTML:false)
        }
       
        // Present the view controller modally.
        self.presentViewController(composeVC, animated: true, completion: nil)
    }
}

2017年2月26日日曜日

配列の使い方と配列を引数とする関数

最も単純な配列を使う例。

カラの配列を作る
メンバを追加する
for inでメンバを取り出す

という最も単純な使い方です

import UIKit

var str = "Hello, playground"

var members:[String] = []   // 空の配列を作って
members.append("sara") // メンバを追加していく
members.append("zara")
members.append("bis")

for member in members {
    print(member)         // 配列の中身を表示してみる
}

print("配列を引数とする関数の定義と受け渡し")
func dispArray(team:[String]) { // 配列を引数として
    for teamMate in team{
        print(teamMate)         // 中身を表示
    }
}

members.append("duka")  // メンバを追加してみる
dispArray(members)      // 配列を引数として上の表示関数を呼んでみる