Родной zlib раздувает / выкачивает для swift3 на iOS
Я хотел бы иметь возможность раздувать / выкачивать структуры данных Swift3. Я нашел GzipSwift, но не ясно, как сделать это доступным для моего приложения для iOS. Наивные вещи, которые я пробовал, включают в себя:
Копирование
Data+Gzip.swift
файл в мой собственный проект. Это потом жалуется наimport zlib
в верхней части указанного файла. Я думаю, что это как-то связано с файлами modulemap в каталоге zlib тех же источников. Но я не уверен, что или как воссоздать их в моем собственном проекте.Клонировал репозиторий из github, открыл XCode и встроил (в основном нажал кнопку запуска). Затем попытался добавить это как связанную библиотеку или фреймворк в мой собственный проект. Я почти уверен, что просто выбрать каталог верхнего уровня хранилища - это не то, что я хочу сделать, но я не знал, что еще попробовать.
Я нашел там какой-то другой код, но он выглядит устаревшим и относящимся к Swift2.
4 ответа
Мне только что пришлось добавить именно эту библиотеку и файл в мой проект, и после долгих проблем, наконец, он заработал, так что позвольте мне пройтись по шагам!
Хорошо
1) Перейдите в каталог верхнего уровня вашего проекта в Finder и создайте новую папку с именем Swiftzlib
или как вы хотите, чтобы имя модуля, который вы будете импортировать. (То, что мы сделаем, это добавим библиотеку zlib в качестве модуля, так что думайте об этом как об импорте Foundation или какого-либо другого такого модуля). Чтобы уточнить, это Swiftzlib
каталог окажется дочерним каталогом того же каталога, который содержит ваш *.xcodeproj
а также *.xcworkspace
файлы.
2) Внутри созданной вами папки создайте два файла.
- include.h
- module.modulemap
3) В вашем include.h
файл, введите следующее:
#include<zlib.h>
4) В вашем module.modulemap
файл, введите следующее:
module Swiftzlib [system] {
header "include.h"
export *
}
Где Swiftzlib совпадает с именем созданной вами папки.
5) Откройте свой проект Xcode и выберите цель
- 5a) В Build Phases -> Link Binary with Libraries, добавьте
libz.tbd
- 5b) В настройках сборки -> Swift Compiler - Пути поиска, добавьте
$(PROJECT_DIR)/Swiftzlib
не рекурсивно к путям импорта - 5c) В настройках сборки -> Другие флаги компоновщика добавьте
-lz
как флаг
6) Выберите свой проект в XCode (может быть, нет необходимости, но я сделал это в своем проекте, и он работает)
- 6a) В Настройки сборки -> Swift Compiler - Пути поиска, добавьте
$(PROJECT_DIR)/Swiftzlib
не рекурсивно к путям импорта
7) В Data+Gzip.swfit
, добавлять import Swiftzlib
в начало файла
8) Очистить, построить и запустить!
РеализацияSwift 5 с использованием Compression.
Мне потребовалось несколько дней, чтобы понять, что мне пришлось отбросить первые 2 байта сжатых данных. Надеюсь, что это может помочь кому-то еще.
import Foundation
import Compression
func decompress(_ data: Data) -> String {
let size = 8_000_000
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: size)
let result = data.subdata(in: 2 ..< data.count).withUnsafeBytes ({
let read = compression_decode_buffer(buffer, size, $0.baseAddress!.bindMemory(to: UInt8.self, capacity: 1),
data.count - 2, nil, COMPRESSION_ZLIB)
return String(decoding: Data(bytes: buffer, count:read), as: UTF8.self)
}) as String
buffer.deallocate()
return result
}
Я поддерживаю небольшую оболочку Swift 3+ вокруг собственной платформы libcompression от Apple:
https://github.com/mw99/DataCompression
Пример использования для gzip:
let data: Data! = "https://www.ietf.org/rfc/rfc1952.txt".data(using: .utf8)
let gzipped: Data! = data.zip()
let gunzipped: Data? = gzipped.unzip()
assert(data == gunzipped)
Но если вас интересуют только классические инфляции и дефляции, вы можете использовать .inflate()
а также .deflate()
методы вместо. Это сэкономит 18 байт, потому что заголовок gzip не будет добавлен.
Я сделал небольшое расширение SPM, вдохновленное ответом @vauxhall.
https://github.com/mezhevikin/Zlib
import Zlib
// Decompressed data
print(data.decompressed)
// Decompressed string
print(data.decompressedString)