Files
2022-01-29 00:49:16 +03:00

200 lines
7.0 KiB
Swift

import Foundation
import UIKit
/// A sticker set
public class StickerSet {
/// A String value that specifies an identifier of the app using the importing library
public let software: String
public enum StickerSetType {
case image
case animation
case video
func validateStickerDataType(_ data: Sticker.StickerData) -> Bool {
switch self {
case .image:
if case .image = data {
return true
} else {
return false
}
case .animation:
if case .animation = data {
return true
} else {
return false
}
case .video:
if case .video = data {
return true
} else {
return false
}
}
}
}
/// A Boolean value that determines whether the sticker set consists of animated stickers
public let type: StickerSetType
/// The thumbnail of the sticker set
public private(set) var thumbnail: Sticker.StickerData?
/// The array of stickers
public private(set) var stickers: [Sticker]
/**
Initializes a new sticker set with provided software identificator and type.
- Parameters:
- software: Identificator of sticker-generator software
- type: Type of the sticker set
- Returns: A sticker set.
*/
public init(software: String, type: StickerSetType) {
self.software = software
self.type = type
self.stickers = []
}
private func validateData(_ data: Sticker.StickerData) throws -> Bool {
switch data {
case let .image(imageData):
if imageData.count == 0 {
throw StickersError.fileIsEmpty
}
if imageData.count > Limits.staticStickerMaxSize {
throw StickersError.fileTooBig
}
if let image = UIImage(data: imageData) {
var dimensionsValid = false
if Int(image.size.width) == Limits.stickerDimensionsSide {
if Int(image.size.height) > 0 && Int(image.size.height) <= Limits.stickerDimensionsSide {
dimensionsValid = true
}
} else if Int(image.size.height) == Limits.stickerDimensionsSide {
if Int(image.size.width) > 0 && Int(image.size.width) <= Limits.stickerDimensionsSide {
dimensionsValid = true
}
}
if !dimensionsValid {
throw StickersError.invalidDimensions
}
}
case let .animation(animationData):
if animationData.count == 0 {
throw StickersError.fileIsEmpty
}
if animationData.count > Limits.animatedStickerMaxSize {
throw StickersError.fileTooBig
}
case let .video(videoData):
if videoData.count == 0 {
throw StickersError.fileIsEmpty
}
if videoData.count > Limits.videoStickerMaxSize {
throw StickersError.fileTooBig
}
}
return true
}
/**
Adds a new sticker to the sticker set using the provided data and associated emojis.
- Parameters:
- data: Data of the sticker
- emojis: Associated emojis of the sticker
- Throws:
`StickersError.countLimitExceeded`
if `stickers` have already reached the maximum number of items (120).
`StickersError.dataTypeMismatch`
if `data` is of an animated sticker while the sticker set is not animated and vice versa.
`StickersError.fileTooBig`
if `data` exceeds the maximum file size for a sticker (PNG: 512Kb, TGS: 64Kb).
`StickersError.invalidDimensions`
if the sticker has invalid dimensions
*/
public func addSticker(data: Sticker.StickerData, emojis: [String]) throws {
if self.stickers.count == Limits.stickerSetStickerMaxCount {
throw StickersError.countLimitExceeded
}
if !self.type.validateStickerDataType(data) {
throw StickersError.dataTypeMismatch
}
if emojis.isEmpty {
throw StickersError.emojiIsEmpty
}
if try self.validateData(data) {
self.stickers.append(Sticker(data: data, emojis: emojis))
}
}
/**
Sets a thumbnail of the sticker set using the provided data.
- Parameters:
- data: Data of the sticker set thumbnail
- Throws:
`StickersError.dataTypeMismatch`
if `data` is of an animated sticker when the sticker set is not animated and vice versa.
`StickersError.fileTooBig`
if `data` exceeds the maximum file size for a sticker (PNG: 512Kb, TGS: 64Kb).
`StickersError.invalidDimensions`
if the sticker has invalid dimensions
*/
public func setThumbnail(data: Sticker.StickerData) throws {
if !self.type.validateStickerDataType(data) {
throw StickersError.dataTypeMismatch
}
if try self.validateData(data) {
self.thumbnail = data
}
}
/**
Initiates an import request for the sticker set
- Throws:
`StickersError.setIsEmpty`
if `stickers` is empty.
`StickersError.telegramNotInstalled`
if Telegram Messenger for iOS is not installed on user's device.
*/
public func `import`() throws {
guard TelegramApp.isInstalled() else {
throw StickersError.telegramNotInstalled
}
guard !self.stickers.isEmpty else {
throw StickersError.setIsEmpty
}
var result: [String: Any] = [:]
result["software"] = self.software
result["thumbnail"] = self.thumbnail?.data.base64EncodedString()
result["isAnimated"] = self.type == .animation
result["isVideo"] = self.type == .video
var stickers: [[String: Any]] = []
for sticker in self.stickers {
var stickerDictionary: [String: Any] = [:]
stickerDictionary["data"] = sticker.data.data.base64EncodedString()
stickerDictionary["mimeType"] = sticker.data.mimeType
stickerDictionary["emojis"] = sticker.emojis
stickers.append(stickerDictionary)
}
result["stickers"] = stickers
TelegramApp.send(json: result)
}
}