LoginSignup
56
66

More than 5 years have passed since last update.

iOSアプリ開発時に使う小ネタ

Last updated at Posted at 2017-01-31

iOSアプリ開発の際に自分がよく使う小ネタです。

環境

  • Swift 3

定数をまとめるApp.swiftを作成

どのファイルからも参照するような定数はこのstructで管理します。
値が途中で変更しなければいけなくなった際に、このファイルの値を変更すれば済みます。

App.swift

import UIKit

struct App {

    static let bundleID = Bundle.main.bundleIdentifier!
    static let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
    static let build = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String

    struct Size {
        static let screenWidth = UIScreen.main.bounds.width
        static let screenHeight = UIScreen.main.bounds.height
        static let navigationBarHeight: CGFloat = 44
        static let toolBarHeight: CGFloat = 44
        static let statusBarHeight = UIApplication.shared.statusBarFrame.height
        static let statusBarAndNavigationBarHeight = Size.statusBarHeight + Size.navigationBarHeight
    }

    struct URL {
        static let itunes: String = ""
        static let devlop: String = ""
        static let production: String = ""
    }

    struct API {
        static let hogeKey: String = ""
        static let fugaKey: String  = ""
    }

    struct Font {
        static func main(_ size: CGFloat) -> UIFont { return App.Font.hiraKakuW3(size: size) }
        static func hiraKakuW6(size: CGFloat) -> UIFont { return UIFont(name: "HiraKakuProN-W6", size: size) ?? UIFont.systemFont(ofSize: size) }
        static func hiraKakuW3(size: CGFloat) -> UIFont { return UIFont(name: "HiraKakuProN-W3", size: size) ?? UIFont.systemFont(ofSize: size) }
    }

    struct Logo {
        static let titleImage: UIImage = R.image.titleImage()
    }
}

参考

R.swiftを導入

コード補完でリソース管理できるので名前の打ち間違えを防げます。
又、呼び出す際のコードも短縮することができます。

mac-cain13/R.swift

Demo:

DemoUseImage.gif

R.swiftを使わない書き方:

let icon = UIImage(named: "settings-icon")
let font = UIFont(name: "San Francisco", size: 42)
let viewController = CustomViewController(nibName: "CustomView", bundle: nil)
let string = String(format: NSLocalizedString("welcome.withName", comment: ""), locale: NSLocale.current, "Arthur Dent")

R.swiftを使った書き方:

let icon = R.image.settingsIcon()
let font = R.font.sanFrancisco(size: 42)
let viewController = CustomViewController(nib: R.nib.customView)
let string = R.string.localizable.welcomeWithName("Arthur Dent")

よく使うパターン

// Custom Cellを取得

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.hogeCell) else { abort() }

    let hoge = hoges[indexPath.row]
    cell.update(hoge)
    return cell
}

// 画面遷移

guard let vc = R.storyboard.setting.instantiateInitialViewController()?.topViewController else { return }
vc.navigationItem.hidesBackButton = true
self.navigationController?.pushViewController(vc, animated: true )

参考

synxでGroupとディレクトリの構成と合わせる

Xcode上でGroupを作成しても、実際のディレクトリ構成は変更されないのでツールを使って整理します。

synx というコマンドラインツールを使うと、
Xcode上のGroupに沿って実際のディレクトリ構成を合わせてくれます。

Demo:
synx.gif

参考

APIKitとHimotokiの組み合わせでRealmを使う


import Foundation
import APIKit
import Himotoki
import RealmSwift

// finalを付ける
final class User: Object {

    dynamic var id: Int = 0
    dynamic var token: String = ""
    dynamic var deviceToken: String = ""

    override static func primaryKey() -> String? {
        return "id"
    }
}

extension User: Decodable {

    static func decode(_ e: Extractor) throws -> User {
        // インスタンス作成
        let user = User()
        user.token = try e <| "token"
        return user
    }
}


struct AccessTokenRequst: HogeRequest {

    typealias Response = User

    let deviceToken: String

    init(deviceToken: String) {
        self.deviceToken = deviceToken
    }

    var method: HTTPMethod {
        return .post
    }

    var path: String {
        return "/auth/login"
    }

    var headerFields: [String: String] {
        return [
            "Content-Type": "application/json"
        ]
    }

    var parameters: Any? {
        return [
            "platform": "iOS",
            "device_token": deviceToken,
        ]
    }

    func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {
        return try decodeValue(object)
    }
}

参考

Extension集

base64の文字列をデコード

import UIKit

extension UIImage {

    static func stringToImage(imageString: String) -> UIImage? {

        let base64String = imageString.replacingOccurrences(of: " ", with: "+")

        let decodeBase64: NSData? =
            NSData(base64Encoded: base64String, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)

        if let decodeSuccess = decodeBase64 {
            let img = UIImage(data: decodeSuccess as Data)
            return img
        }
        return nil
    }
}

フェードイン/フェードアウトアニメーションを追加


import UIKit

enum FadeType: TimeInterval {
    case
    Normal = 0.2,
    Slow = 1.0
}

extension UIView {
    func fadeIn(type: FadeType = .Normal, completed: (() -> ())? = nil) {
        fadeIn(duration: type.rawValue, completed: completed)
    }

    /** For typical purpose, use "public func fadeIn(type: FadeType = .Normal, completed: (() -> ())? = nil)" instead of this */
    func fadeIn(duration: TimeInterval = FadeType.Slow.rawValue, completed: (() -> ())? = nil) {
        alpha = 0
        isHidden = false
        UIView.animate(withDuration: duration,
                                   animations: {
                                    self.alpha = 1
        }) { finished in
            completed?()
        }
    }
    func fadeOut(type: FadeType = .Normal, completed: (() -> ())? = nil) {
        fadeOut(duration: type.rawValue, completed: completed)
    }

    /** For typical purpose, use "public func fadeOut(type: FadeType = .Normal, completed: (() -> ())? = nil)" instead of this */
    func fadeOut(duration: TimeInterval = FadeType.Slow.rawValue, completed: (() -> ())? = nil) {
        UIView.animate(withDuration: duration, animations: {
            self.alpha = 0
        }) { [weak self] finished in
            self?.isHidden = true
            self?.alpha = 1
            completed?()
        }
    }
}

日付フォーマットを変更

import UIKit

extension Date {
    func toString() -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy/MM/dd HH:mm"
        return dateFormatter.string(from: self)
    }
}

56
66
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
56
66