2016年1月版swift初心者がアプリを作るまで
swift初心者がゴニョゴニョしながら20時間ぐらいで作りました。
swiftらしさとか知りません。存分に汚いですが、とりあえず動きます。
拙いけれど、頑張って作りました。
このアプリケーションは既存のAPIを利用し音楽を楽しむものです。
従前からPC用のインターフェースがあり、そこにスマホ用のインターフェースを追加し、楽しんでいましたが、iPhoneのSafariですとスリープしてしまうと音楽が続かないという問題がありました。今回、swiftでアプリとして作ることでこの問題に対応しようとしました。
以下の仕組みについて調べながらつくっていったメモを記述します。
- 巷のswift情報について、swift2の習得
- ログイン
- そもそもライブラリのインストール方法がわからん
- JSONの取り扱い
- httpリクエストする方法がわからない。
- TouchIDについて
- 型変換まとめ
- MarqueeLabel
- 音楽のバックグランド再生
- バックグラウンド次へ
- UITableViewのCellの自作
- ストーリボード画面遷移
- スリーブさせない
- 検索機能
- バックグラウンド・フォアグラウンド時のフック
- Xcodeがこなれていない
巷のswift情報について、swift2の習得
swiftは現在swift2になり、書籍を一冊購入していましたがswift1系で、使い物になりません。
購入した使い物にならなかった本。
詳細!Swift iPhoneアプリ開発 入門ノート Swift 1.1+Xcode 6.1+iOS 8.1対応
- 作者: 大重美幸
- 出版社/メーカー: ソーテック社
- 発売日: 2014/12/12
- メディア: Kindle版
- この商品を含むブログを見る
そこで、はてな教科書を目次に使いました。
github.com
を参照し、詳しく知りたいときは各要素について更にググる方針にしました。
文法を覚えるのではなく、やりたいことをやるために必要な文法を拾い上げる方式にしました。
ログイン
storyboardにテキストフィールドとパスワード用のテキストフィールドを配置し、ボタンを配置し、ボタンアクションをつなげました。
// ログインアクション @IBAction func loginAction(sender: AnyObject) { let user = User(); if let username = textFieldUserName.text { if let password = textFiledPassword.text { loginok = user.login(username, password: password); } } // 次のストーリーボードに遷移するメソッド。loginokで遷移の可否を判定 nextPage() }
そもそもライブラリのインストール方法わからん
cocoapodsというrubyのbundleみたいな仕組みがあるようです。利用しました。
qiita.com
$ pod init $ emacs Podfile $ pod install / update $ open musicdb.xcworkspace # コレ便利
JSONの取り扱い
qiita.com
github.com
下記のような感じです。
let json = JSON(data: JSONのデータ) let hoge = json[0]["genre"].string!
httpリクエストする方法がわからない。
JSONライブラリはSwiftyJSONを選択しました。
import SwiftyJSON ... let qs = "日本語の文字列" let qqs = qs.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.alphanumericCharacterSet())! let request = NSURLRequest(URL: NSURL(string: "https://hoge.com/api/aaa"+ "?p=1&per=10000000000&qs=" + qqs)!) let data = try NSURLConnection.sendSynchronousRequest(request, returningResponse: nil) let jsondata = JSON(data: data)
TouchID
import LocalAuthentication .. let myAuthContext = LAContext() .. func loginCheckWithTouch() { if myAuthContext.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: nil) { myAuthContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "認証", reply: { success, error in if success { // ここの入力が非常に時間がかかる。今のところ原因不明 self.textFieldUserName.text = "user" self.textFiledPassword.text = "pass" self.lblLogin.text = "ログインできます" } }) } }
型変換まとめ
qiita.com
stackoverflow.com
FloatからIntに落としてStringとかかなり難しそう。30分ぐらい調べたができなかった。
あきらめました。
音楽のバックグランド再生
youtubeアプリがバックグランドでポーズになりますよね。このアプリでもその挙動に合わせました。ちょっと時間がなかったのもありますが。
nackpan.net
使ってない
バックグラウンド次へ
nackpan.net
使ってない
UITableViewのCellの自作
gaku3601.hatenablog.com
デリゲートも必要。デリゲートは本当に必要。そして便利
nukenuke.hatenablog.com
// xibに対応するswiftファイル import UIKit class CustomCellTableViewCell: UITableViewCell { @IBOutlet weak var txtTitle: UILabel! @IBOutlet weak var txtGenre: UILabel! @IBOutlet weak var txtArtist: UILabel! @IBOutlet weak var txtAlbum: UILabel! var title = ""; var genre = ""; var artist = ""; var album = ""; var _id = ""; var pageType:PageType = PageType.Genre var delegate : CellDelegate? // delegate .. // delegate import UIKit // CellDelegate プロトコルを記述 @objc protocol CellDelegate { // デリゲートメソッド定義 func play(cell:CustomCellTableViewCell) func next(cell:CustomCellTableViewCell) } // 通知される側(コントローラー) class ApplicationViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,CellDelegate/*コレ*/, MyPlayerDelegate ,UISearchBarDelegate{ .. override func viewDidLoad() { super.viewDidLoad() // delegate系 tableView.delegate = self tableView.dataSource = self myPlayer.delegate = self self.serchBar.delegate = self // cellの登録 let nib = UINib(nibName: "CustomCellTableViewCell", bundle: nil) tableView.registerNib(nib, forCellReuseIdentifier: "Cell") } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let c = tableView.dequeueReusableCellWithIdentifier("Cell") as? CustomCellTableViewCell c?.clear() // セルの内容をクリアする自作メソッド c?.delegate = self // delegateを取得
ストーリボード画面遷移
mt.hatenadiary.com
ストリーボードのファイル名とストリーボードにつけた名前で遷移する
let sb:UIStoryboard = UIStoryboard(name: "Application",bundle:NSBundle.mainBundle()) let applicationViewController = sb.instantiateViewControllerWithIdentifier("Main") as! ApplicationViewController self.presentViewController(applicationViewController, animated: true, completion: nil)
スリーブさせない
// スリープさせない UIApplication.sharedApplication().idleTimerDisabled = true
検索機能
025 UISearchBarの表示 - Swift Docs
入力キーボードを消すにはUISearchBarのキャンセルボタンを表示させるようにさせて
func searchBarCancelButtonClicked(searchBar: UISearchBar) { searchBar.resignFirstResponder() // これでキーボード収まる } func searchBarSearchButtonClicked(searchBar: UISearchBar) { if let t = searchBar.text { list = SearchGenreModel.bySearch(t) // 検索処理 mode = PageType.Search // 検索処理 tableView.reloadData() // テーブルをリセット } searchBar.resignFirstResponder() // これでキーボード収まる }
とする。
バックグラウンド・フォアグラウンド時のフック
AppDelegateで通知を発行してそれをViewControllerで取得する感じ
// @AppDelegate.swift func applicationWillResignActive(application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. NSNotificationCenter.defaultCenter().postNotificationName("applicationWillResignActive", object: nil) } func applicationDidEnterBackground(application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. NSNotificationCenter.defaultCenter().postNotificationName("applicationDidEnterBackground", object: nil) } // @ViewController override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "enterBackground:", name:"applicationDidEnterBackground", object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "enterForeground:", name:"applicationWillEnterForeground", object: nil) .. func enterBackground(notification: NSNotification){ print("バックグラウンド") myPlayer.pause() } func enterForeground(notification: NSNotification){ print("フォアグラウンド") myPlayer.pause() }