Fix category names to match Apple categories (#5)

This commit is contained in:
Niklas Amslgruber
2024-02-20 20:19:46 +01:00
committed by GitHub
parent 5766292d31
commit b57c28995b
7 changed files with 126 additions and 49 deletions

View File

@@ -0,0 +1,56 @@
//
// AppleEmojiCategory.swift
//
//
// Created by Niklas Amslgruber on 19.02.24.
//
import Foundation
public class AppleEmojiCategory: Codable {
public enum Name: String, CaseIterable, Codable {
case flags = "Flags"
case activity = "Activity"
case objects = "Objects"
case travelAndPlaces = "Travel & Places"
case symbols = "Symbols"
case animalsAndNature = "Animals & Nature"
case foodAndDrink = "Food & Drink"
case smileysAndPeople = "Smileys & People"
public static var orderedCases: [Name] {
return allCases.sorted(by: { $0.order < $1.order })
}
public var order: Int {
switch self {
case .flags:
return 8
case .activity:
return 4
case .objects:
return 6
case .travelAndPlaces:
return 5
case .symbols:
return 7
case .animalsAndNature:
return 2
case .foodAndDrink:
return 3
case .smileysAndPeople:
return 1
}
}
}
public let name: Name
public var values: [String]
public init(name: Name, values: [String]) {
self.name = name
self.values = values
}
}

View File

@@ -7,8 +7,10 @@
import Foundation
public typealias EmojiCategory = AppleEmojiCategory
public enum EmojiManager {
public enum Version: Double {
case v13_1 = 13.1
case v14 = 14
@@ -31,7 +33,7 @@ public enum EmojiManager {
return "15.1"
}
}
public static func getSupportedVersion() -> Version {
if #available(iOS 17.4, *) {
return .v15_1
@@ -48,34 +50,55 @@ public enum EmojiManager {
/// Returns all emojis for a specific version
/// - Parameters:
/// - version: The specific version you want to fetch (default: the highest supported version for a device's iOS version)
/// - showAllVariations: Some emojis inlcude skin type variations which increases the number of emojis drastically. (default: only the yellow neutral emojis are returned)
/// - showAllVariations: Some emojis include skin type variations which increases the number of emojis drastically. (default: only the yellow neutral emojis are returned)
/// - url: Specify the location of the `emoji_v<version_number>.json` files if needed (default: bundle resource path)
/// - Returns: Array of categories with all emojis that are assigned to each category
public static func getAvailableEmojis(version: Version = .getSupportedVersion(), showAllVariations: Bool = false, at url: URL? = nil) -> [EmojiCategory] {
let fileUrl = url ?? Bundle.module.url(forResource: version.fileName, withExtension: "json")
if let url = fileUrl, let content = try? Data(contentsOf: url), let result = try? JSONDecoder().decode([EmojiCategory].self, from: content) {
var filteredEmojis: [EmojiCategory] = []
if let url = fileUrl, let content = try? Data(contentsOf: url), let result = try? JSONDecoder().decode([UnicodeEmojiCategory].self, from: content) {
var filteredEmojis: [UnicodeEmojiCategory] = []
var appleCategories: [AppleEmojiCategory] = []
for category in result {
let supportedEmojis = category.values.filter({
showAllVariations ? true : isNeutralEmoji(for: $0)
})
filteredEmojis.append(EmojiCategory(name: category.name, values: supportedEmojis))
let unicodeCategory = UnicodeEmojiCategory(name: category.name, values: supportedEmojis)
filteredEmojis.append(unicodeCategory)
if shouldMergeCategory(category), let index = appleCategories.firstIndex(where: { $0.name == .smileysAndPeople }) {
if category.name == .smileysAndEmotions {
let oldValues = appleCategories[index].values
appleCategories[index].values = supportedEmojis
appleCategories[index].values.append(contentsOf: oldValues)
} else {
appleCategories[index].values.append(contentsOf: supportedEmojis)
}
} else {
guard let appleCategory = unicodeCategory.appleCategory else {
continue
}
appleCategories.append(AppleEmojiCategory(name: appleCategory, values: supportedEmojis))
}
}
return filteredEmojis
return appleCategories.sorted(by: { $0.name.order < $1.name.order })
}
return []
}
private static func shouldMergeCategory(_ category: UnicodeEmojiCategory) -> Bool {
return category.name == .smileysAndEmotions || category.name == .peopleAndBody
}
private static func isNeutralEmoji(for emoji: String) -> Bool {
let unicodes = getUnicodes(emoji: emoji)
let colors = ["1F3FB", "1F3FC", "1F3FD", "1F3FE", "1F3FF"]
for color in colors where unicodes.contains(color) {
return false
}
return true
}
private static func getUnicodes(emoji: String) -> [String] {
let unicodeScalars = emoji.unicodeScalars
let unicodes = unicodeScalars.map { $0.value }

View File

@@ -1,5 +1,5 @@
//
// EmojiCategory.swift
// UnicodeEmojiCategory.swift
//
//
// Created by Niklas Amslgruber on 10.06.23.
@@ -7,7 +7,7 @@
import Foundation
public class EmojiCategory: Codable {
public class UnicodeEmojiCategory: Codable {
public enum Name: String, CaseIterable, Codable {
case flags = "Flags"
@@ -21,47 +21,39 @@ public class EmojiCategory: Codable {
case foodAndDrink = "Food & Drink"
case smileysAndEmotions = "Smileys & Emotion"
public static var orderedCases: [EmojiCategory.Name] {
return EmojiCategory.Name.allCases.sorted(by: { $0.order < $1.order })
}
// The component category does not include relevant emojis
public static var relevantCases: [EmojiCategory.Name] {
return EmojiCategory.Name.orderedCases.filter({ $0 != .components })
}
// Order that Apple uses in their emoji picker
public var order: Int {
var appleName: AppleEmojiCategory.Name? {
switch self {
case .flags:
return 10
return .flags
case .activities:
return 5
return .activity
case .components:
return 8
return nil
case .objects:
return 7
return .objects
case .travelAndPlaces:
return 6
return .travelAndPlaces
case .symbols:
return 9
return .symbols
case .peopleAndBody:
return 2
return .smileysAndPeople
case .animalsAndNature:
return 3
return .animalsAndNature
case .foodAndDrink:
return 4
return .foodAndDrink
case .smileysAndEmotions:
return 1
return .smileysAndPeople
}
}
}
public let name: Name
public let values: [String]
public let appleCategory: AppleEmojiCategory.Name?
public var values: [String]
public init(name: Name, values: [String]) {
self.name = name
self.appleCategory = name.appleName
self.values = values
}
}