Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
67
Help us understand the problem. What is going on with this article?
@yamshta

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

More than 1 year has passed since last update.

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)
    }
}

67
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
yamshta
lclco
業界最大手高速バス料金比較サイト「バス比較なび」やLCCなど飛行機との比較ができる「格安移動」を運営

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
67
Help us understand the problem. What is going on with this article?