asklife

IT&Life

Author: TaK (page 2 of 169)

SwiftでiPhoneアプリ開発 – Part.6

スクリーンショット 2015-06-30 21.13.30

位置情報を取得するアプリを作ります。

Xcodeをいじるのでポイントは以下
1.Core Location フレームワークを追加

スクリーンショット 2015-06-30 21.17.17

2.info.plistにkey:NSLocation… value:任意の文言 を追加する。
・アプリ使用中のみ許可: NSLocationWhenInUseUsageDescription
・アプリ使用中以外も常に許可: NSLocationAlwaysUsageDescription

スクリーンショット 2015-06-30 21.18.35

スクリーンショット 2015-06-30 21.18.23

3.実装する
実装サンプルはSwift Docsまんまです。

//
//  ViewController.swift
//  CoreLocation001
//

import UIKit
import CoreLocation

class ViewController: UIViewController , CLLocationManagerDelegate{
    
    var myLocationManager:CLLocationManager!
    
    // 緯度表示用のラベル.
    var myLatitudeLabel:UILabel!
    
    // 経度表示用のラベル.
    var myLongitudeLabel:UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // ボタンの生成.
        let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        myButton.backgroundColor = UIColor.orangeColor()
        myButton.layer.masksToBounds = true
        myButton.setTitle("Get", forState: .Normal)
        myButton.layer.cornerRadius = 50.0
        myButton.layer.position = CGPoint(x: self.view.bounds.width/2, y:self.view.bounds.height/2)
        myButton.addTarget(self, action: "onClickMyButton:", forControlEvents: .TouchUpInside)
        
        // 緯度表示用のラベルを生成.
        myLatitudeLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 30))
        myLatitudeLabel.layer.position = CGPoint(x: self.view.bounds.width/2, y:self.view.bounds.height/2+100)
        
        // 軽度表示用のラベルを生成.
        myLongitudeLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 30))
        myLongitudeLabel.layer.position = CGPoint(x: self.view.bounds.width/2, y:self.view.bounds.height/2+130)
        
        
        // 現在地の取得.
        myLocationManager = CLLocationManager()
        
        myLocationManager.delegate = self
        
        // セキュリティ認証のステータスを取得.
        let status = CLLocationManager.authorizationStatus()
        
        // まだ認証が得られていない場合は、認証ダイアログを表示.
        if(status == CLAuthorizationStatus.NotDetermined) {
            println("didChangeAuthorizationStatus:\(status)");
            // まだ承認が得られていない場合は、認証ダイアログを表示.
            self.myLocationManager.requestAlwaysAuthorization()
        }
        
        // 取得精度の設定.
        myLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        // 取得頻度の設定.
        myLocationManager.distanceFilter = 100
        
        self.view.addSubview(myButton)
    }
    
    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        
        println("didChangeAuthorizationStatus");
        
        // 認証のステータスをログで表示.
        var statusStr = "";
        switch (status) {
        case .NotDetermined:
            statusStr = "NotDetermined"
        case .Restricted:
            statusStr = "Restricted"
        case .Denied:
            statusStr = "Denied"
        case .AuthorizedAlways:
            statusStr = "AuthorizedAlways"
        case .AuthorizedWhenInUse:
            statusStr = "AuthorizedWhenInUse"
        }
        println(" CLAuthorizationStatus: \(statusStr)")
    }
    
    // ボタンイベントのセット.
    func onClickMyButton(sender: UIButton){
        // 現在位置の取得を開始.
        myLocationManager.startUpdatingLocation()
    }
    
    // 位置情報取得に成功したときに呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didUpdateLocations locations: [AnyObject]!){
        
        // 緯度・経度の表示.
        myLatitudeLabel.text = "緯度:\(manager.location.coordinate.latitude)"
        myLatitudeLabel.textAlignment = NSTextAlignment.Center
        
        myLongitudeLabel.text = "経度:\(manager.location.coordinate.longitude)"
        myLongitudeLabel.textAlignment = NSTextAlignment.Center
        
        
        self.view.addSubview(myLatitudeLabel)
        self.view.addSubview(myLongitudeLabel)
        
    }
    
    // 位置情報取得に失敗した時に呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didFailWithError error: NSError!){
        print("error")
    }
    
}

4.iOSシュミレータで動かす時には、Debugモードで位置情報を付与してあげる。

シュミレータ起動->Debug->Simular location

スクリーンショット 2015-06-30 21.23.43

ここで先ほどinfo.plistに入れたvalueの文言が表示されてますね。
スクリーンショット 2015-06-30 21.28.42

Allowを選んで、位置情報が表示されました。
スクリーンショット 2015-06-30 21.13.30

5.シュミレータのAllow情報などを消すには
iOS Simulator -> Reset Content and Settings

スクリーンショット 2015-06-30 21.28.03

 

6.位置情報の取得タイミング!

めっちゃはまりました。位置情報の取得タイミングは非同期です。
locationManagerが動くと、位置情報は取得されています。(おそらく)

そのため、位置情報を取得して、fooサーバにlat/lngを付与して情報を取得するような処理を書きたい時は
locationManagerの中で、位置情報が取得できた後に、記述する必要があります。

こう書くと当たり前ですが、結構な時間詰まってしまいました。。。

//
//  ViewController.swift
//

import UIKit
import CoreLocation

class ViewController: UIViewController,CLLocationManagerDelegate {
    
    
    var myLocationManager:CLLocationManager!
    
    struct location{
        static var lat = ""
        static var lng = ""
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Geo Request
        self.getGeo()

    }
    
    func getGeo(){
        // 現在地の取得.
        myLocationManager = CLLocationManager()
        
        myLocationManager.delegate = self
        // セキュリティ認証のステータスを取得.
        let status = CLLocationManager.authorizationStatus()
        // まだ認証が得られていない場合は、認証ダイアログを表示.
        if(status == CLAuthorizationStatus.NotDetermined) {
            println("didChangeAuthorizationStatus:\(status)");
            // まだ承認が得られていない場合は、認証ダイアログを表示.
            self.myLocationManager.requestAlwaysAuthorization()
        }
        // 取得精度の設定.
        myLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        // 取得頻度の設定.
        myLocationManager.distanceFilter = 100

        // 現在位置の取得を開始.
        myLocationManager.startUpdatingLocation()
    }
    
    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        
        println("didChangeAuthorizationStatus");
        
        // 認証のステータスをログで表示.
        var statusStr = "";
        switch (status) {
        case .NotDetermined:
            statusStr = "NotDetermined"
        case .Restricted:
            statusStr = "Restricted"
        case .Denied:
            statusStr = "Denied"
        case .AuthorizedAlways:
            statusStr = "AuthorizedAlways"
        case .AuthorizedWhenInUse:
            statusStr = "AuthorizedWhenInUse"
        }
        println(" CLAuthorizationStatus: \(statusStr)")
    }
    
    // 位置情報取得に成功したときに呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didUpdateLocations locations: [AnyObject]!){
        
        location.lat = String(stringInterpolationSegment: manager.location.coordinate.latitude)
        location.lng = String(stringInterpolationSegment: manager.location.coordinate.longitude)
        
        println(location.lat)
        println(location.lng)
        
        // HTTP Request ★★★
        self.reqHttp()
        
    }
    
    // 位置情報取得に失敗した時に呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didFailWithError error: NSError!){
        print("error")
    }
    
    
    func reqHttp(){
        // 通信先のURLを生成.
        var myUrl:NSURL = NSURL(string:"http://foo/bar?lat=" + String(location.lat) + "&lng="+String(location.lng)+"/")!
        
        // リクエストを生成.
        var myRequest:NSURLRequest  = NSURLRequest(URL: myUrl)
        // 送信処理を始める.
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
        println(myUrl)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        // NSData -> NSDictionary
        let json:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments, error: nil) as! NSDictionary
    }
        
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }


}

 

以上で、位置情報の取得方法でした!

参考
https://sites.google.com/a/gcl……hino-qu-de
http://dev.classmethod.jp/refe……ification/
http://swift-studying.com/blog……ft/?p=1078
http://shirokai.hatenablog.com……/swift-gps
http://www.hnyssh.net/?p=577

SwiftでiPhoneアプリ開発 – Part.5

実装を進めるに辺り、Swift文法に不慣れな内はいろいろと躓くかと思います。

便利なリンク集を紹介します。

Swiftライブラリ検索
https://developer.apple.com/search/

定番のSwift逆引き辞書
https://sites.google.com/a/gcl……wift-docs/

Swiftのコンパイルエラー寄せ集め かなり役立ちます。
http://samekard.blogspot.com/2……error.html

SwiftでiPhoneアプリ開発 – Part.4

Swift DocのサンプルでiOSからHTTP通信の実装。

スクリーンショット 2015-06-29 15.40.41

ViewConrtroller.swift

import UIKit

class ViewController: UIViewController {

    var myTextView: UITextView!
    

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.lightGrayColor()
        
        // 表示用のTextViewを用意.
        myTextView = UITextView(frame: CGRectMake(10, 50, self.view.frame.width - 20, 500))
        
        myTextView.backgroundColor = UIColor(red: 0.9, green: 0.9, blue: 1, alpha: 1.0)
        myTextView.layer.masksToBounds = true
        myTextView.layer.cornerRadius = 20.0
        myTextView.layer.borderWidth = 1
        myTextView.layer.borderColor = UIColor.blackColor().CGColor
        myTextView.font = UIFont.systemFontOfSize(CGFloat(20))
        myTextView.textColor = UIColor.blackColor()
        myTextView.textAlignment = NSTextAlignment.Left
        myTextView.dataDetectorTypes = UIDataDetectorTypes.All
        myTextView.layer.shadowOpacity = 0.5
        myTextView.layer.masksToBounds = false
        myTextView.editable = false
        self.view.addSubview(myTextView)
        
        // 通信先のURLを生成.
        var myUrl:NSURL = NSURL(string:"http://asklife.info/feed")!
        // リクエストを生成.
        var myRequest:NSURLRequest  = NSURLRequest(URL: myUrl)
        // 送信処理を始める.
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        
        // 帰ってきたデータを文字列に変換.
        var myData:NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
        println(myData)
        
        // TextViewにセット.
        myTextView.text = myData as String
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }


}

次にjson取得版

スクリーンショット 2015-06-29 17.01.34

 

import UIKit

class ViewController: UIViewController {

    var myTextView: UITextView!
    

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.lightGrayColor()
        
        // 表示用のTextViewを用意.
        myTextView = UITextView(frame: CGRectMake(10, 50, self.view.frame.width - 20, 500))
        
        myTextView.backgroundColor = UIColor(red: 0.9, green: 0.9, blue: 1, alpha: 1.0)
        myTextView.layer.masksToBounds = true
        myTextView.layer.cornerRadius = 20.0
        myTextView.layer.borderWidth = 1
        myTextView.layer.borderColor = UIColor.blackColor().CGColor
        myTextView.font = UIFont.systemFontOfSize(CGFloat(20))
        myTextView.textColor = UIColor.blackColor()
        myTextView.textAlignment = NSTextAlignment.Left
        myTextView.dataDetectorTypes = UIDataDetectorTypes.All
        myTextView.layer.shadowOpacity = 0.5
        myTextView.layer.masksToBounds = false
        myTextView.editable = false
        self.view.addSubview(myTextView)
        
        // 通信先のURLを生成.(都道府県json取得)
        var myUrl:NSURL = NSURL(string:"http://express.heartrails.com/api/json?method=getPrefectures")!
        // リクエストを生成.
        var myRequest:NSURLRequest  = NSURLRequest(URL: myUrl)
        // 送信処理を始める.
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        
        // jsonを配列を文字列に変換
        let json:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments, error: nil) as! NSDictionary
        
        let res:NSDictionary = json.objectForKey("response") as! NSDictionary
        let pref:NSArray = res.objectForKey("prefecture") as! NSArray
        
        for var i=0 ; i<pref.count; i++ {
            println(pref[i])
        }
        
        // TextViewにセット.
        myTextView.text = pref[12] as! String
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }


}

参考
https://sites.google.com/a/gcl……ong-qihttp
http://dev.classmethod.jp/refe……-api-json/

SwiftでiPhoneアプリ開発 – Part.3

気がつけば、2ヶ月近く放置していました。
心機一転、nagaramiというアプリを開発中です。

swiftの勉強をかねて、だらだらっとYoutubeの動画を見れるアプリを作ろうと思います。

といっても、swiftわからないのでSwiftビギナーズ勉強会に参加してきました。

いくつか学びがありましたが、外部ライブラリの読み込み方を備忘として残しておきます。

sudo gem update --system
sudo gem install cocoapods
pod --version
pod setup

cd nagarami/
pod init

ここまでやると、Podfileができています。
このPodfileを修正します。
なんとなくわかるかと思いますが、
CocoaPodsの取得もとはgithubで
iosのバージョンは8.0で
use_frameworks!とするとswiftの指定(らしい)
pod ‘Alamofire’,’~> 1.2’はAlamofireというライブラリの1.2以上をインストールするという設定です。

AlamofireというのはHTTP通信を実現してくれるライブラリです。

# Uncomment this line to define a global platform for your project
# platform :ios, '6.0'

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

target 'nagarami' do

pod 'Alamofire', '~> 1.2'

end

target 'nagaramiTests' do

end

その後、

pod install

Homebrewをインストールしてください

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Carthageをインストールします。これは依存関係を解消するもの(らしい)

brew update
brew install carthage
git submodule add https://github.com/Alamofire/Alamofire.git

ここでxcodeを起動し、Alamofire.xcodeprojをドラッグ&ドロップしてください。
xcodeのプロジェクトの同じディレクトリにいます。
xcodeはGUIでドラッグ&ドロップしないと反映されないんですね。
CUIでは完結しないと。。

スクリーンショット 2015-05-09 17.16.22

次に、
nagaramiプロジェクトを開いて、
General->Embed binary-> +を押して->Alamofire.frameworkを選んで->Add
(xcodeめんどくさいな。。。)

スクリーンショット 2015-05-09 17.25.27

とやると、ソースが読み込まれて、依存関係が解消される!
import Alamofire

と、ここで時間が来てしまったので続きは公式をみてください。
https://github.com/Alamofire/Alamofire

※GemのversionUPがうまくいかないとき

$ [sudo] gem update cocoapods
うまく行かない時

$ [sudo] gem uninstall cocoapods
$ [sudo] gem install cocoapods
アップデート後にやったほうがいいこと

$ pod setup

SwiftでiPhoneアプリ開発 – Part.2

Swiftでタップした場所にキャラクターを移動させる

//
//  GameScene.swift
//  SpriteKitGame
//
//

import SpriteKit

class GameScene: SKScene {
    
        var player : SKSpriteNode!
        var targetMarker : SKSpriteNode!
        
        override func didMoveToView(view: SKView) {
            //背景画像。SKSPriteNodeで画像を読み込む。
            let backGround = SKSpriteNode(imageNamed:"bg-space.png")
            self.addChild(backGround)
            backGround.position = CGPointMake(500,300)
            
            //画面をタッチした場所を示すターゲットマーカー
            self.targetMarker = SKSpriteNode(imageNamed:"marker.png")
            self.addChild(targetMarker)
            self.targetMarker.position = CGPointMake(300,300)
            
            //プレイヤーとなるキャラクター画像
            self.player = SKSpriteNode(imageNamed:"player.png")
            self.addChild(player)
            self.player.position = CGPointMake(300,300)
        }
        
        override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
            /* Called when a touch begins */
            for touch: AnyObject in touches {
                let location = touch.locationInNode(self)
                //タッチした場所にターゲットマーカーを動かす
                self.targetMarker.position = location
            }
        }
        
        override func update(currentTime: CFTimeInterval) {
            /* Called before each frame is rendered */
            //ターゲットマーカーの場所にプレイヤーを移動させる。
            if(self.player.position.x < self.targetMarker.position.x){
                self.player.position.x += 1;
            }else if(self.player.position.x > self.targetMarker.position.x){
                self.player.position.x -= 1;
            }
            if(self.player.position.y < self.targetMarker.position.y){
                self.player.position.y += 1;
            }else if(self.player.position.y > self.targetMarker.position.y){
                self.player.position.y -= 1;
            }
        }
}

参考
SwiftとSpriteKitを使って1分でゲームを作る
http://qiita.com/oggata/items/……aeebf738fe

Older posts Newer posts

© 2017 asklife

Theme by Anders NorenUp ↑