iOS swiftでQRコード認識時に時々クラッシュする際対策!

iphone swiftでQRコード認識時にクラッシュする事がある。その対策

QRコードリーダーアプリで、下記のようにカメラ内のQRコードを読み取る時に、
クラッシュする事が一定確率であった。

エラー内容


fatal error: unexpectedly found nil while unwrapping an Optional value

クラッシュ対象のコード


qrCodeObject = previewLayer.transformedMetadataObjectForMetadataObject( metadata as! AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject

この部分で、クラッシュする事がある。。

色々調べたら、AVCaptureVideoPreviewLayer内のメソッドでnilが入る事があるらしい。

超参考:http://ja.stackoverflow.com/questions/14968/%E4%B8%8B%E8%A8%98%E3%83%9A%E3%83%BC%E3%82%B8%E3%82%92%E5%8F%82%E8%80%83%E3%81%AB%EF%BC%92%E6%AC%A1%E5%85%83%E3%83%90%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89%E8%AA%AD%E3%81%BF%E5%8F%96%E3%82%8A%E3%82%92swift2%E3%81%A7%E6%9B%B8%E3%81%84%E3%81%9F%E3%81%AE%E3%81%A7%E3%81%99%E3%81%8C-%E5%AE%9F%E6%A9%9F%E3%83%87%E3%83%90%E3%83%83%E3%82%AF%E6%99%82%E3%81%AB%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E7%94%BB%E9%9D%A2%E3%81%AE-fatal-error-unexpectedly

ボクが対策したコード


if previewLayer.transformedMetadataObjectForMetadataObject( metadata as! AVMetadataMachineReadableCodeObject) != nil { //nilチェックしてから処理 qrCodeObject = previewLayer.transformedMetadataObjectForMetadataObject( metadata as! AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject }else { // キャプチャセッション再始動 captureSession.startRunning() }

nilチェックをおこなってら処理する事で解決しました。
また、ただのnilの場合はカメラが動かなくなってしまうので、
キャプチャーセッション等を、再度走らせる事で思い通りの動作になりました。!
参考になれば幸いです!!

iOS 画面を(portrait)縦固定にしても、window が横画面サイズになる。

xcode8 general

全部縦固定していたはずなのに、なぜかipadだけランドスケープ(横画面)で起動する。。
ちょっとおかしいと思って色々調べたメモ


環境

  • xcode8
  • Mac OS El Capitan

症状

  • xcodeの設定で General で
    Devices : Universal で、
    Device Orientation: Portrait のみの設定
  • iPadで横画面状態で、アプリを起動

するとUIWindowでサイズを取得すると縦画面のサイズと違うサイズが取得される、
むしろ、縦より横のサイズが大きい!
横画面のサイズになっているっぽい。。

DevicesをiPhoneにし、Portrait のみでも結果同じだった。

画面サイズを取得して、UIViewとか、UIを作っているところが、
予想外の動きにになりまくり。。


対策

設定画面のGeneralの

  • Devices: Universalに。
  • info.plistファイルにて記述されている UISupportedInterfaceOrientations~ipad
    の中を UIInterfaceOrientationPortrait のみにする。

設定画面のDevicesでプルダウン切り替えでipadの内容が保持されているのはあとから知ったw

info.plist

〜
<key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
    </array>
</dict>
</plist>
〜
  • General設定画面の Required full screen にチェックを入れる
xcode8 general
xcode8 general

ただ、iPadでは、マルチタスキング機能というものがあって(Slide OverやSplitView)が使えなくなってしまうようなのでご注意を。

参考記事さま http://qiita.com/jollyjoester/items/c8bb1592d01fdef663f9

swift2.3 シェア機能で、「Cannot assign value of type ‘(_, Bool, Array<_>!, NSError!) -> ()’ to type ‘UIActivityViewControllerCompletionWithItemsHandler?’」エラーが

swift2.3で友達いないけど、友達にシェアする機能を実装してたら、

こんなエラーが。。w


Cannot assign value of type '(_, Bool, Array<_>!, NSError!) -> ()' to type 'UIActivityViewControllerCompletionWithItemsHandler?'

いままでつい最近までエラーじゃなかったのに、xcode8&swift2.3に更新したからか。。

UIActivityViewControllerでシェア機能を実装していると、
皆さんぶつかると思うので対応方法。
英語の記事はめちゃくちゃあったのですが、何故か日本の記事はなかったので一応。


activityVC.completionWithItemsHandler = { (s: String?, complete: Bool, items: [AnyObject]?, err:NSError?) -> Void in if (complete) { printf("完了") }else{ printf("失敗") } }

completionWithItemsHandlerの引数を調整すればOKでした!

これでtwitterfacebook等に投稿したかどうか判定できる!

やっほい

xcode8 swift2.3でRealmSwiftを使う際にpod installで下記エラーがでた

最近xcodeをxcode8にして、色々かわりすぎて戸惑いを隠せない、
小心者筆者です。。

いままでxcode7.3かな?で動かしていたRealm Swiftが使えなくなったのでメモ。
前提として、xcode8でswift2.3を使った場合です。

Podfileで下記のようにrealmをインストールしていたのですが


pod 'RealmSwift'

pod install するとっこのようなエラー


$ pod install /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/universal-darwin15/rbconfig.rb:213: warning: Insecure world writable dir /Applications/Cocos/tools/ant/bin in PATH, mode 040777 Analyzing dependencies Pre-downloading: `RealmSwift` from `https://github.com/realm/realm-cocoa.git`, branch `master`, submodules `true` [!] Unable to satisfy the following requirements: - `Realm (= 2.0.2)` required by `RealmSwift (2.0.2)` None of your spec sources contain a spec satisfying the dependency: `Realm (= 2.0.2)`. You have either: * out-of-date source repos which you can update with `pod repo update`. * mistyped the name or version. * not added the source repo that hosts the Podspec to your Podfile. Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.

で、下記で解決


pod 'Realm', :git => 'https://github.com/realm/realm-cocoa.git', :branch => 'master', :submodules => true pod 'RealmSwift', :git => 'https://github.com/realm/realm-cocoa.git', :branch => 'master', :submodules => true

はいそれだけ。っす

storyboradのsegueに紐付けないViewController(画面)に遷移する方法&引数も渡せます!

タイトルの通り、
storyboradのsegueに紐付けないViewController(画面)に、
遷移する方法。。+引数も渡せます!

自作のポップアップ画面等を実装する際に便利なので、
忘れないようにφ(..)メモメモ


// ストーリーボードのMain.storyboardファイルを指定 let storyboard = UIStoryboard(name: "Main", bundle: nil) // ストーリーボードで指定した「CustomPopupViewController」を指定 let vc = storyboard.instantiateViewControllerWithIdentifier("CustomPopupViewController") as! CustomPopupViewController // 予め、CustomPopupViewControllerで宣言してあるpopupNameメンバ変数に値を渡す! vc.popupName = hogeName

味噌は、


as! CustomPopupViewController

ちゃんとクラス名でaliasしてあげないと、


vc.popupName = hogeName

で、引数がわたせないので注意!

swiftで画質を担保したままUIImageをリサイズ

粗い画像

UIImageを高画質のままリサイズするメソッド

extension UIImage{

    // 画質を担保したままResizeするクラスメソッド.
    func ResizeUIImage(width : CGFloat, height : CGFloat)-> UIImage!{

        let size = CGSize(width: width, height: height)

        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        var context = UIGraphicsGetCurrentContext()

        self.drawInRect(CGRectMake(0, 0, size.width, size.height))
        var image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }

}

使い方


// 80x80にリサイズだけど画像も高画質のまま! let resizeSelectedImage = UIImage(named: "hoge.png")!.ResizeUIImage(80, height: 80)

綺麗な画像のままリサイズできました!

GameCenterのスコアボードを独自UI等で利用(swift版)

gamecenter アイコン

GameCenterのスコアボードを、swiftを使って独自UI等で利用する方法を〜〜〜φ(..)メモメモ

出来合いのスコアボードを自分のアプリデザインに合わせた形で表示したかったので、
GameCenterのスコアを取得し好きな方法で使ってみた。



var leaderboardRequest: GKLeaderboard = GKLeaderboard() leaderboardRequest.playerScope = .Global leaderboardRequest.timeScope = .Today leaderboardRequest.identifier = "itunes connectで指定したleaderboardID" leaderboardRequest.range = NSMakeRange(1, 10) // Request leaderboardRequest.loadScoresWithCompletionHandler{ (scores, error) -> Void in if error != nil { println("Error \(error))") } else if scores != nil { println("leaderboards \(scores)") // scoresという情報に配列で格納されている } }

scoresは、GKScoreという型で配列で入っているので、
TableViewのデータとして使う事も柔軟に対応できました!

デバッグログを確認すればわかりますが、


println("\(scores.player.alias)") // プレイヤー名 println("\(scores.value)") // スコア

上記のように、プレイヤーの名前や、スコアを取得できます。

参考にさせて頂いたサイト

http://iorisomo.hatenablog.com/entry/2014/04/09/193007

http://stackoverflow.com/questions/28519503/gkleaderboard-localplayerscore-returns-nil-on-ios-8-1-3

http://qiita.com/moco3/items/d9c2a8956d4377bad264

storyboard等で利用しているラベルのフォントを一括で変更(swift版)

swift フォント一括指定

swiftのコードで、ラベルのフォントを一括で変更

AppDelegate.swift


〜省略〜 @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. // 一括でLabelのフォントを変更 UILabel.appearance().font = UIFont(name: "Helvetica Bold Oblique", size: 18.0) 〜省略〜

もちろん UILabel以外も可能!

また、”Helvetica Bold Oblique” みたいに、

コードから呼び出す際に指定するフォント名の確認は下記で可能です!

iphoneアプリをappstoreに申請する際に、launchImage周りでエラーがでる場合

iphoneアプリをappstoreに申請する際に、launchImage周りでエラーがでる場合に、
エラーがでる事がある。

xcodeのバージョンは、xcode7.2.1

xcodeのLaunchImageは、レイアウトファイルをちゃんと指定しているのなになぜか、、
色々調べたところ。

通常は画像ファイルか、storyboardファイルの指定の必要があるが、
昔に作ったアプリなので、storyboardの拡張子ではなく、xibファイルの指定だったからのようでした。

xcode

LaunchScreen.xib → LaunchScreen.storyboard

これをxibからstoryboardで作り直しして指定したら、
無事解決!!!
同じようなシチュエーションの人で、参考なれば嬉しいです!

Unity5で対象物を一定速度でドラッグ&ドロップ

Unity5で、タップした位置に対象物を移動。

タップした位置に、パズルのピースのようにものを移動する場合。

using UnityEngine;
using System.Collections;

public class dragSample : MonoBehaviour {
    float touchX;
    float touchY;

    void Update(){
        touchX = Input.mousePosition.x;
        touchY = Input.mousePosition.y;

        if(Input.GetMouseButton(0)){
            OnDrag();
        }
    }

    void OnDrag(){

        gameObject.transform.position = Vector3.MoveTowards (gameObject.transform.position,Camera.main.ScreenToWorldPoint(new Vector3(touchX,touchY,10.0f)), 0.1f);
    }
}

解説

  • Camera.main.ScreenToWorldでタップ位置の座標に変換
  • MoveTowordsで、対象物と、持って行きたい位置、それとそこまで移動する速度

マウスのドラッグ&ドロップするように移動する場合は、

MoveTowordsを除けばOK、下記のように。

transform.position = Camera.main.ScreenToWorldPoint(new Vector3(touchX,touchY,10.0f));