Родной zlib раздувает / выкачивает для swift3 на iOS

Я хотел бы иметь возможность раздувать / выкачивать структуры данных Swift3. Я нашел GzipSwift, но не ясно, как сделать это доступным для моего приложения для iOS. Наивные вещи, которые я пробовал, включают в себя:

  1. Копирование Data+Gzip.swift файл в мой собственный проект. Это потом жалуется на import zlib в верхней части указанного файла. Я думаю, что это как-то связано с файлами modulemap в каталоге zlib тех же источников. Но я не уверен, что или как воссоздать их в моем собственном проекте.

  2. Клонировал репозиторий из 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)
Другие вопросы по тегам