post Image
ZOZOTOWN iOS アプリで利用している Tips の一部

ZOZOTOWN iOS の内部で利用している UI/NS 系クラス拡張につきまして、ニッチすぎる内容を除き紹介させていただきます!

※下記のコードはすべて、 Swift 4.2 / iOS12 SDK で動作するものです。

Array+Safe

配列の範囲外にアクセスしたさい、クラッシュせず nil を返して欲しい場合に利用します。

Array+Safe.swift
extension Array {

    subscript (safe index: Index) -> Element? {
        return indices.contains(index) ? self[index] : nil
    }

}

Use Case

func xxx(index: Int) {
    let list: [String] = ["a", "b", "c"]

    if let item = list?[safe: index] {
        ...
    }
}

String+HtmlMutableAttributedString

HTMLが格納されている String をHTML形式の NSMutableAttributedString に変換するさいに利用します。
※メインスレッド以外で利用するとクラッシュするため、ご注意ください。

String+HtmlMutableAttributedString.swift
extension String {

    var htmlMutableAttributedString: NSMutableAttributedString? {
        if let encodedData = data(using: .unicode, allowLossyConversion: true) {
            let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [.documentType: NSAttributedString.DocumentType.html]
            let htmlText = try? NSMutableAttributedString(data: encodedData, options: options, documentAttributes: nil)
            return htmlText
        }
        return nil
    }

}

NSMutableParagraphStyle+Initializer

NSAttributedText を作成するさいに利用します。

NSAttributedTextを作成するさい、

let paragraph = NSMutableParagraphStyle()
paragraph.lineSpacing = 6
paragraph.textAlignment = .center
paragraph.lineBreakMode = .byWordWrapping 

上記がリーダブルではなく、コードを書く手間を削減したかったので、下記のように簡単に書けるようにしました。

NSMutableParagraphStyle+Initializer.swift
extension NSMutableParagraphStyle {

    convenience init(lineSpacing: CGFloat? = nil, textAlignment: NSTextAlignment? = nil, lineBreakMode: NSLineBreakMode? = nil, lineHeight: CGFloat? = nil) {
        self.init()

        if let lineSpacing = lineSpacing {
            self.lineSpacing = lineSpacing
        }
        if let textAlignment = textAlignment {
            self.alignment = textAlignment
        }
        if let lineBreakMode = lineBreakMode {
            self.lineBreakMode = lineBreakMode
        }
        if let lineHeight = lineHeight {
            self.maximumLineHeight = lineHeight
            self.minimumLineHeight = lineHeight
        }
    }

}

Use Case

func xxx() {
        let attributes: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 14),
                                                         .foregroundColor: UIColor.black,
                                                         .paragraphStyle: NSMutableParagraphStyle(lineSpacing: 6, textAlignment: .center, lineBreakMode: .byWordWrapping)]
    ...
}

UIColor+Hex

CSSで利用されるような16進数表記文字列( #808080 など)を UIColor にするさいに利用します。

UIColor+Hex.swift
extension UIColor {

    public convenience init(hex: Int, alpha: CGFloat) {
        let b = CGFloat((hex & 0x000000ff) >> 0) / 255.0
        let g = CGFloat((hex & 0x0000ff00) >> 8) / 255.0
        let r = CGFloat((hex & 0x00ff0000) >> 16) / 255.0

        self.init(red: r, green: g, blue: b, alpha: alpha)
    }

    public convenience init(hexWithAlpha: UInt32) {
        let b = CGFloat((hexWithAlpha & 0x000000ff) >> 0) / 255.0
        let g = CGFloat((hexWithAlpha & 0x0000ff00) >> 8) / 255.0
        let r = CGFloat((hexWithAlpha & 0x00ff0000) >> 16) / 255.0
        let a = CGFloat((hexWithAlpha & 0xff000000) >> 24) / 255.0

        self.init(red: r, green: g, blue: b, alpha: a)
    }

    public convenience init(hex: Int) {
        self.init(hex: hex, alpha: 1.0)
    }

    public convenience init(hexString: String) {
        var rgbString = hexString.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
        if rgbString.hasPrefix("#") {
            rgbString.remove(at: rgbString.startIndex)
        }

        switch rgbString.count {
        case 8:
            var argbValue: UInt32 = 0
            Scanner(string: rgbString).scanHexInt32(&argbValue)

            self.init(hexWithAlpha: argbValue)
        case 6:
            var rgbValue: UInt32 = 0
            Scanner(string: rgbString).scanHexInt32(&rgbValue)

            self.init(hex: Int(rgbValue))
        default:
            self.init(hex: 0)
        }
    }

}

Use Case

func xxx() {
    let hexWithAlphaColor1 = UIColor(hex: 0xffffff, alpha: 0.8) // rgba: 1.0 / 1.0 / 1.0 / 0.8
    let hexWithAlphaColor2 = UIColor(hexWithAlpha: 0xffffffcc) // rgba: 1.0 / 1.0 / 1.0 / 0.8
    let hexColor = UIColor(hex: 0xffffff) // rgba: 1.0 / 1.0 / 1.0 / 1.0
    let stringColor1 = UIColor(hexString: "ffffff") // rgba: 1.0 / 1.0 / 1.0 / 1.0
    let stringColor2 = UIColor(hexString: "#ffffff") // rgba: 1.0 / 1.0 / 1.0 / 1.0
    let stringColor3 = UIColor(hexString: "#ffffffcc") // rgba: 1.0 / 1.0 / 1.0 / 0.8
}

URL+Queries

APIに GET リクエストを送信する場合など、クエリーパラメーターを Dictionary で設定するさいに利用します。

URL+Queries.swift
extension URL {

    func addQueries(_ queries: [String: String]) -> URL? {
        if queries.isEmpty {
            return self
        } else {
            if var urlComponents = URLComponents(string: absoluteString) {
                urlComponents.queryItems = (urlComponents.queryItems ?? []) + queries.map({ URLQueryItem(name: $0.key, value: $0.value) })
                return urlComponents.url
            } else {
                return self
            }
        }
    }

}

Use Case

func writeAppStoreReview() {
    guard let appStoreUrl = URL(string: String(format: "itms-apps://itunes.apple.com/app/id%@", "(Apple ID)")) else {
        return
    }

    if let appStoreWithWriteReviewUrl = appStoreUrl.addQueries(["action": "write-review"]) {
        _ = openURL(appStoreWithWriteReviewUrl)
    }
}

おまけ:NSURL+Queries

Objective-C のコードから上記 URL+Queries をそのまま利用できなかったため、 NSURL 版も作成しました。

NSURL+Queries.swift
// MARK: - Definition

extension NSURL {

    @objc func addQueries(_ queries: [String: String]) -> NSURL? {
        return (self as URL).addQueries(queries) as NSURL?
    }

}

最後に

もしご自身のプロダクトに使えそうなら、ご利用いただけると幸いです!


『 Swift 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。