High performance cache framework for iOS.

Related tags

Cache YYCache
Overview

YYCache

License MIT  Carthage compatible  CocoaPods  CocoaPods  Support  Build Status

High performance cache framework for iOS.
(It's a component of YYKit)

Performance

Memory cache benchmark result

Disk benchmark result

You may download and compile the latest version of sqlite and ignore the libsqlite3.dylib in iOS system to get higher performance.

See Benchmark/CacheBenchmark.xcodeproj for more benchmark case.

Features

  • LRU: Objects can be evicted with least-recently-used algorithm.
  • Limitation: Cache limitation can be controlled with count, cost, age and free space.
  • Compatibility: The API is similar to NSCache, all methods are thread-safe.
  • Memory Cache
    • Release Control: Objects can be released synchronously/asynchronously on main thread or background thread.
    • Automatically Clear: It can be configured to automatically evict objects when receive memory warning or app enter background.
  • Disk Cache
    • Customization: It supports custom archive and unarchive method to store object which does not adopt NSCoding.
    • Storage Type Control: It can automatically decide the storage type (sqlite / file) for each object to get better performance.

Installation

CocoaPods

  1. Add pod 'YYCache' to your Podfile.
  2. Run pod install or pod update.
  3. Import <YYCache/YYCache.h>.

Carthage

  1. Add github "ibireme/YYCache" to your Cartfile.
  2. Run carthage update --platform ios and add the framework to your project.
  3. Import <YYCache/YYCache.h>.

Manually

  1. Download all the files in the YYCache subdirectory.
  2. Add the source files to your Xcode project.
  3. Link with required frameworks:
    • UIKit
    • CoreFoundation
    • QuartzCore
    • sqlite3
  4. Import YYCache.h.

Documentation

Full API documentation is available on CocoaDocs.
You can also install documentation locally using appledoc.

Requirements

This library requires iOS 6.0+ and Xcode 8.0+.

License

YYCache is provided under the MIT license. See LICENSE file for details.



中文介绍

高性能 iOS 缓存框架。
(该项目是 YYKit 组件之一)

性能

iPhone 6 上,内存缓存每秒响应次数 (越高越好): Memory cache benchmark result

iPhone 6 上,磁盘缓存每秒响应次数 (越高越好): Disk benchmark result

推荐到 SQLite 官网下载和编译最新的 SQLite,替换 iOS 自带的 libsqlite3.dylib,以获得更好的性能。

更多测试代码和用例见 Benchmark/CacheBenchmark.xcodeproj

特性

  • LRU: 缓存支持 LRU (least-recently-used) 淘汰算法。
  • 缓存控制: 支持多种缓存控制方法:总数量、总大小、存活时间、空闲空间。
  • 兼容性: API 基本和 NSCache 保持一致, 所有方法都是线程安全的。
  • 内存缓存
    • 对象释放控制: 对象的释放(release) 可以配置为同步或异步进行,可以配置在主线程或后台线程进行。
    • 自动清空: 当收到内存警告或 App 进入后台时,缓存可以配置为自动清空。
  • 磁盘缓存
    • 可定制性: 磁盘缓存支持自定义的归档解档方法,以支持那些没有实现 NSCoding 协议的对象。
    • 存储类型控制: 磁盘缓存支持对每个对象的存储类型 (SQLite/文件) 进行自动或手动控制,以获得更高的存取性能。

安装

CocoaPods

  1. 在 Podfile 中添加 pod 'YYCache'
  2. 执行 pod installpod update
  3. 导入 <YYCache/YYCache.h>。

Carthage

  1. 在 Cartfile 中添加 github "ibireme/YYCache"
  2. 执行 carthage update --platform ios 并将生成的 framework 添加到你的工程。
  3. 导入 <YYCache/YYCache.h>。

手动安装

  1. 下载 YYCache 文件夹内的所有内容。
  2. 将 YYCache 内的源文件添加(拖放)到你的工程。
  3. 链接以下的 frameworks:
    • UIKit
    • CoreFoundation
    • QuartzCore
    • sqlite3
  4. 导入 YYCache.h

文档

你可以在 CocoaDocs 查看在线 API 文档,也可以用 appledoc 本地生成文档。

系统要求

该项目最低支持 iOS 6.0Xcode 8.0

许可证

YYCache 使用 MIT 许可证,详情见 LICENSE 文件。

相关链接

YYCache 设计思路与技术细节

Comments
  • 在个人中心里面清空了所有的Cache,但在进入收藏的时候,个人资料缓存还是没有清空,请问有没可以立即同步的选项

    在个人中心里面清空了所有的Cache,但在进入收藏的时候,个人资料缓存还是没有清空,请问有没可以立即同步的选项

    在个人中心里面清空了所有的Cache,但在进入收藏的时候,个人资料缓存还是没有清空,请问有没可以立即同步的选项? 我用YYCache做了登录之后的个人资料,cookie的保存. 然后,我在每次请求数据的时候,将保存的数据加入到请求头(cookie)里面,用来验证用户. 但我在别的页面清楚所有的Cache之后(RemoveAll),再请求数据发现,并没有清除掉, 用户信息还是保留着. 所以,我想问一下有没有立即执行的选项.

    opened by CodeRabbitYu 8
  • [YYKVStorage] initWithPath should return error when directory already exists

    [YYKVStorage] initWithPath should return error when directory already exists

    The file creation part from YYKVStorage.m:

        NSError *error = nil;
        if (![[NSFileManager defaultManager] createDirectoryAtPath:path
                                       withIntermediateDirectories:YES
                                                        attributes:nil
                                                             error:&error] ||
            ![[NSFileManager defaultManager] createDirectoryAtPath:[path stringByAppendingPathComponent:kDataDirectoryName]
                                       withIntermediateDirectories:YES
                                                        attributes:nil
                                                             error:&error] ||
            ![[NSFileManager defaultManager] createDirectoryAtPath:[path stringByAppendingPathComponent:kTrashDirectoryName]
                                       withIntermediateDirectories:YES
                                                        attributes:nil
                                                             error:&error]) {
            NSLog(@"YYKVStorage init error:%@", error);
            return nil;
        }
    

    This will not result in an error if directory already exists.

    enhancement 
    opened by skyline75489 8
  • Maximum cache size

    Maximum cache size

    Is it possible to set the maximum cache usage to a custom value? If not that would be a great idea to implement. I am using YYImage which caches all images automatically (which is great). But it would be useful if we could change the maximum size of the cache manually.

    opened by koraykoska 6
  • 使用YYCache在项目中会报卡顿异常 -[YYKVStorage _dbClose] (YYKVStorage.m:)

    使用YYCache在项目中会报卡顿异常 -[YYKVStorage _dbClose] (YYKVStorage.m:)

    libsystem_kernel.dylib fcntl + 8 1 libsystem_kernel.dylib fcntl + 128 2 libsqlite3.dylib sqlite3_free_table + 49568 3 libsqlite3.dylib sqlite3_wal_checkpoint + 3456 4 libsqlite3.dylib sqlite3_bind_int64 + 7480 5 libsqlite3.dylib sqlite3_bind_int64 + 6604 6 libsqlite3.dylib sqlite3_bind_int64 + 4892 7 libsqlite3.dylib sqlite3_backup_finish + 756 8 libsqlite3.dylib sqlite3_total_changes + 1024 9 ShunLianPower -YYKVStorage _dbClose 10 ShunLianPower -YYKVStorage dealloc 11 libobjc.A.dylib object_cxxDestructFromClass(objc_object_, objc_class_) + 148 12 libobjc.A.dylib objc_destructInstance + 92 13 libobjc.A.dylib object_dispose + 28 14 ShunLianPower -YYDiskCache dealloc 15 ShunLianPower -YYCache .cxx_destruct 16 libobjc.A.dylib object_cxxDestructFromClass(objc_object_, objc_class_) + 148 17 libobjc.A.dylib objc_destructInstance + 92 18 libobjc.A.dylib object_dispose + 28 19 ShunLianPower destroy_helper_block (SLHttpRequest.m:0) 20 libsystem_blocks.dylib Block_release + 156 21 ShunLianPower -AFURLSessionManagerTaskDelegate .cxx_destruct 22 libobjc.A.dylib object_cxxDestructFromClass(objc_object, objc_class) + 148 23 libobjc.A.dylib objc_destructInstance + 92 24 libobjc.A.dylib object_dispose + 28 25 ShunLianPower _destroy_helper_block (AFURLSessionManager.m:0) 26 libsystem_blocks.dylib _Block_release + 156 27 libdispatch.dylib __dispatch_client_callout + 16 28 libdispatch.dylib _dispatch_main_queue_callback_4CF + 1844 29 CoreFoundation ___CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 12 30 CoreFoundation ___CFRunLoopRun + 1628 31 CoreFoundation CFRunLoopRunSpecific + 384 32 GraphicsServices GSEventRunModal + 180 33 UIKit UIApplicationMain + 204 34 ShunLianPower main (main.m:14) 35 libdyld.dylib _start + 4

    opened by CodeRabbitYu 6
  • 存储JPG图片(1.5M~2M)之后获取不到了

    存储JPG图片(1.5M~2M)之后获取不到了

    想用YYCache来存储本地编辑的图片,测试用几张比较大的图片 1.5M~2M左右,存储完成后在block中移除内存中的图片数据,同时再去获取发现数据为空。当然如果把图片改成一个NSString是正常的。 测试代码:

    // 初始化
        self.yycache = [[YYCache alloc] initWithName:@"yycachedemo"];
    
    // 编辑并保存
    - (void)store {
        self.index += 1;
        UIImage *imageToStore = [UIImage imageNamed:[NSString stringWithFormat:@"pic%@.jpg",@(self.index)]];
    
        __weak typeof(self) weakSelf = self;
        NSString *key = [self keyWithIndex:self.index];
    //    NSString *strToStore = key;
        [self.yycache setObject:imageToStore forKey:key withBlock:^{
            [weakSelf.yycache.memoryCache removeObjectForKey:key];
    
            id obj = [weakSelf.yycache objectForKey:key];
            NSLog(@"get stored obj %@",obj);
    //        [weakSelf.yycache objectForKey:key withBlock:^(NSString * _Nonnull key, id<NSCoding>  _Nonnull object) {
    //            NSLog(@"get stored obj %@",object);
    //        }];
        }];
        self.imageView.image = imageToStore;
    }
    
    - (NSString *)keyWithIndex:(NSInteger)index {
        return [NSString stringWithFormat:@"image%@",@(index)];
    }
    

    不知是否是使用方法不当,

    opened by wuyongrui 6
  • 取出缓存为空

    取出缓存为空

    YYCache *cache = [[YYCache alloc] initWithName:JoyHomeUserCacheName]; NSDictionary *userDic = (NSDictionary *)[cache objectForKey:JoyHomeUserModelCache]; 缓存成功后 有时候取出数据为空

    opened by JLLJHD 4
  • 关于数据库查询不方便的问题

    关于数据库查询不方便的问题

    1.数据库操作是否可以提供分页查询的功能,例如

    • (NSArray *)objectsWithPage:(NSInteger)page pageCount(NSInteger)pageCount;

    2.如果我存的是model对象,例如model有个属性是age,目前是把model归档后存为二进制的,如果我查询数据库,想查age大于20的,目前这样的缓存用起来还不是很方便,有什么好的办法

    opened by spWang 4
  • YYKVStorage _dbOpen may case crash when db can't open

    YYKVStorage _dbOpen may case crash when db can't open

    你好,感谢你分享的YYCache项目,我们在项目中有使用,在使用过程中我们发现一个问题: _dbOpen函数在某些情况下由于打开sqlite数据库失败,但是内部状态维护有点问题,具体是场景是:图片缓存被多次清理,在某次清理时打开sqlite数据库返回SQLITE_CANTOPEN,_dbOpen函数返回了NO,但是内部状态,db,_invalidated等状态都标示为打开成功状态,在下次使用图片缓存时由于_dbStmtCache被置为NULL,导致crash。 这里存在的问题还和sqlite的API有关系,int result = sqlite3_open(_dbPath.UTF8String, &_db);在返回失败是,db被赋值了

    opened by zzzworm 4
  • 求解。。

    求解。。

    清理磁盘存储的时候,经常会崩溃在这一句。

    sqlite3_stmt *stmt = (sqlite3_stmt *)CFDictionaryGetValue(_dbStmtCache, (__bridge const void *)(sql));

    具体在下面这个函数中,报错是Thread34:EXC_BAD_ACCESS

    - (sqlite3_stmt *)_dbPrepareStmt:(NSString *)sql { if (![self _dbIsReady]) return NULL; sqlite3_stmt *stmt = (sqlite3_stmt *)CFDictionaryGetValue(_dbStmtCache, (__bridge const void *)(sql)); if (!stmt) { int result = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stmt, NULL); if (result != SQLITE_OK) { if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite stmt prepare error (%d): %s", __FUNCTION__, __LINE__, result, sqlite3_errmsg(_db)); return NULL; } CFDictionarySetValue(_dbStmtCache, (__bridge const void *)(sql), stmt); } else { sqlite3_reset(stmt); } return stmt; }

    opened by HebeTienCoder 4
  • 报错在这个方法中,不知道什么原因,使用 diskcache,遵守了协议,重写了归档方法

    报错在这个方法中,不知道什么原因,使用 diskcache,遵守了协议,重写了归档方法

    • (int)_dbGetItemCountWithKey:(NSString *)key { NSString *sql = @"select count(key) from manifest where key = ?1;"; sqlite3_stmt *stmt = [self _dbPrepareStmt:sql]; if (!stmt) return -1; sqlite3_bind_text(stmt, 1, key.UTF8String, -1, NULL); int result = sqlite3_step(stmt); if (result != SQLITE_ROW) { if (_errorLogsEnabled) NSLog(@"%s line:%d sqlite query error (%d): %s", FUNCTION, LINE, result, sqlite3_errmsg(_db)); return -1; } return sqlite3_column_int(stmt, 0); }
    opened by imwangxuesen 3
  • YYDiskCache在移除数据时是否与LRU策略相反了?

    YYDiskCache在移除数据时是否与LRU策略相反了?

    你好,YYKVStorage.m 中获取最近访问数据时,是否应该使用 asc 而不是 desc。最近的时间值更大。使用 desc 导致每次移除时把最近使用的元素优先移除掉了。

    - (BOOL)removeItemsToFitCount:(int)maxCount {
            items = [self _dbGetItemSizeInfoOrderByTimeDescWithLimit:perCount];
    
    - (NSMutableArray *)_dbGetItemSizeInfoOrderByTimeDescWithLimit:(int)count {
        NSString *sql = @"select key, filename, size from manifest order by last_access_time desc limit ?1;";
        sqlite3_stmt *stmt = [self _dbPrepareStmt:sql];
    

    测试代码如下:

        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSString *docDir = [(NSArray*)NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
            NSString *testDir = [docDir stringByAppendingPathComponent:@"testDir"];
            NSLog(@"testDir = %@", testDir);
    
            YYDiskCache *diskCache = [[YYDiskCache alloc]initWithPath:testDir inlineThreshold:0];
            diskCache.customFileNameBlock = ^(NSString *key){
                return [key stringByAppendingPathExtension:@"txt"];
            };
    
            [diskCache setObject:@"hello" forKey:@"1"];
            [diskCache setObject:@"world" forKey:@"2"];
    
            NSLog(@"total count : %@",@([diskCache totalCount]));
    //        NSLog(@"key 1 = %@", [diskCache objectForKey:@"1"]);
    //        usleep(1000000);
    //        NSLog(@"key 2 = %@", [diskCache objectForKey:@"2"]);
    
            NSLog(@"key 2 = %@", [diskCache objectForKey:@"2"]);
            usleep(1000000);
            NSLog(@"key 1 = %@", [diskCache objectForKey:@"1"]);
    
            [diskCache trimToCount:1];
            NSLog(@"total count : %@",@([diskCache totalCount]));
            NSLog(@"key 1 = %@", [diskCache objectForKey:@"1"]);
            NSLog(@"key 2 = %@", [diskCache objectForKey:@"2"]);
        });
    
    

    输出如下:

    2016-03-28 00:47:00.696 YYCacheTest[55228:1046537] total count : 2
    2016-03-28 00:47:00.697 YYCacheTest[55228:1046537] key 2 = world
    2016-03-28 00:47:01.700 YYCacheTest[55228:1046537] key 1 = hello
    2016-03-28 00:47:01.701 YYCacheTest[55228:1046537] total count : 1
    2016-03-28 00:47:01.701 YYCacheTest[55228:1046537] key 1 = (null)
    2016-03-28 00:47:01.702 YYCacheTest[55228:1046537] key 2 = world
    
    

    在最近访问 key1之后,应该优先移除 key2。但目前是移除了key1的值。

    bug 
    opened by everettjf 3
  • 关于linkedmap中的字典处理问题

    关于linkedmap中的字典处理问题

    删除节点的代码中_dic似乎是想要持有所有的Node,在队列中释放。

    Node节点也注释说不持有前后节点,交给字典管理。

    但是Map中的字典在赋值的时候用的却是__bridge,不转交对象管辖权,那么字典中的value应该无法持有Node节点才对?

    @interface _YYLinkedMapNode : NSObject {
        @package
        __unsafe_unretained _YYLinkedMapNode *_prev; // retained by dic
        __unsafe_unretained _YYLinkedMapNode *_next; // retained by dic
    ...
    }
    @end
    ...
    - (void)insertNodeAtHead:(_YYLinkedMapNode *)node {
        CFDictionarySetValue(_dic, (__bridge const void *)(node->_key), (__bridge const void *)(node));
       ...
    }
    - (void)removeAll {
         ...
        if (CFDictionaryGetCount(_dic) > 0) {
            CFMutableDictionaryRef holder = _dic;
            _dic = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
            
            if (_releaseAsynchronously) {
                dispatch_queue_t queue = _releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue();
                dispatch_async(queue, ^{
                    CFRelease(holder); // hold and release in specified queue
                });
            }
           ...
        }
    }
    
    opened by leidi0129 0
  • 部分手机在使用YYCache存储时会清除数据

    部分手机在使用YYCache存储时会清除数据

    YYCache *cache = [[YYCache alloc]initWithName: CacheKeyUserManager]; [cache setObject:_strServerIP forKey: KeyStrServerIP]; 你好,我想咨询一下,这种方式创建保存数据 部分手机型号的反馈会自动清除。

    opened by johnchen 5
  • 文件保存,归档/解档 iOS13之后弃用,希望早点看到更新.

    文件保存,归档/解档 iOS13之后弃用,希望早点看到更新.

    • (NSData *)archivedDataWithRootObject:(id)rootObject API_DEPRECATED("Use +archivedDataWithRootObject:requiringSecureCoding:error: instead", macosx(10.2,10.14), ios(2.0,12.0), watchos(2.0,5.0), tvos(9.0,12.0));
    • (nullable id)unarchiveObjectWithFile:(NSString *)path API_DEPRECATED("Use +unarchivedObjectOfClass:fromData:error: instead", macosx(10.2,10.14), ios(2.0,12.0), watchos(2.0,5.0), tvos(9.0,12.0));
    opened by zhbgitHub 0
  • -[YYKVStorage _dbExecute:] line:182 sqlite exec error (5): database is locked

    -[YYKVStorage _dbExecute:] line:182 sqlite exec error (5): database is locked

    如题,在对本地缓存异步读取的时候很频繁的发生这样的错误,然后缓存被删,gg。 -[YYKVStorage _dbExecute:] line:182 sqlite exec error (5): database is locked 2019-12-17 11:38:58.225945+0800 xxxxx[389:27234] [logging] BUG IN CLIENT OF libsqlite3.dylib: database integrity compromised by API violation: vnode unlinked while in use: /private/var/mobile/Containers/Data/Application/6A2C58F1-C93F-4B4E-A16A-014532078A6C/Library/Caches/CacheOfChapters/manifest.sqlite-shm

    opened by jksniper 1
Releases(1.0.3)
Owner
null
Cache - Nothing but Cache.

Cache doesn't claim to be unique in this area, but it's not another monster library that gives you a god's power. It does nothing but caching, but it does it well. It offers a good public API with out-of-box implementations and great customization possibilities. Cache utilizes Codable in Swift 4 to perform serialization.

HyperRedink 2.7k Dec 28, 2022
Apple Asset Cache (Content Cache) Tools

AssetCacheTool A library and tool for interacting with both the local and remote asset caches. This is based on research I did a few years ago on the

Kenneth Endfinger 21 Jan 5, 2023
Cachyr A typesafe key-value data cache for iOS, macOS, tvOS and watchOS written in Swift.

Cachyr A typesafe key-value data cache for iOS, macOS, tvOS and watchOS written in Swift. There already exists plenty of cache solutions, so why creat

Norsk rikskringkasting (NRK) 124 Nov 24, 2022
Carlos - A simple but flexible cache, written in Swift for iOS 13+ and WatchOS 6 apps.

Carlos A simple but flexible cache, written in Swift for iOS 13+ and WatchOS 6 apps. Breaking Changes Carlos 1.0.0 has been migrated from PiedPiper de

National Media & Tech 628 Dec 3, 2022
A lightweight generic cache for iOS written in Swift with extra love for images.

Haneke is a lightweight generic cache for iOS and tvOS written in Swift 4. It's designed to be super-simple to use. Here's how you would initalize a J

Haneke 5.2k Dec 29, 2022
Everyone tries to implement a cache at some point in their iOS app’s lifecycle, and this is ours.

Everyone tries to implement a cache at some point in their app’s lifecycle, and this is ours. This is a library that allows people to cache NSData wit

Spotify 1.2k Dec 28, 2022
Fast, non-deadlocking parallel object cache for iOS, tvOS and OS X

PINCache Fast, non-deadlocking parallel object cache for iOS and OS X. PINCache is a fork of TMCache re-architected to fix issues with deadlocking cau

Pinterest 2.6k Dec 28, 2022
CachyKit - A Caching Library is written in Swift that can cache JSON, Image, Zip or AnyObject with expiry date/TTYL and force refresh.

Nice threadsafe expirable cache management that can cache any object. Supports fetching from server, single object expire date, UIImageView loading etc.

Sadman Samee 122 Dec 28, 2022
MemoryCache - type-safe, thread-safe memory cache class in Swift

MemoryCache is a memory cache class in swift. The MemoryCache class incorporates LRU policies, which ensure that a cache doesn’t

Yusuke Morishita 74 Nov 24, 2022
Track is a thread safe cache write by Swift. Composed of DiskCache and MemoryCache which support LRU.

Track is a thread safe cache write by Swift. Composed of DiskCache and MemoryCache which support LRU. Features Thread safe: Implement by dispatch_sema

Cheer 268 Nov 21, 2022
UITableView cell cache that cures scroll-lags on cell instantiating

UITableView + Cache https://github.com/Kilograpp/UITableView-Cache UITableView cell cache that cures scroll-lags on a cell instantiating. Introduction

null 73 Aug 6, 2021
💾 Simple memory & disk cache

Cache ?? Simple memory & disk cache Usage ??‍?? Default let cache = Cache<String>() try memory.save("MyValue", forKey: "MyKey") let cached = try cac

SeongHo Hong 2 Feb 28, 2022
Cache library for videos for React Native

@lowkey/react-native-cache Cache everything Installation npm install @lowkey/react-native-cache Usage import ReactNativeCache from "@lowkey/react-nati

Max Prokopenko 1 Oct 1, 2021
CachedAsyncImage is the simplest way to add cache to your AsyncImage.

CachedAsyncImage ??️ CachedAsyncImage is AsyncImage, but with cache capabilities. Usage CachedAsyncImage has the exact same API and behavior as AsyncI

Lorenzo Fiamingo 278 Jan 5, 2023
🏈 Cache CocoaPods for faster rebuild and indexing Xcode project.

Motivation Working on a project with a huge amount of pods I had some troubles: - Slow and unnecessary indexing of pods targets, which implementation

Vyacheslav Khorkov 487 Jan 5, 2023
XCRemoteCache is a remote cache tool for Xcode projects.

XCRemoteCache is a remote cache tool for Xcode projects. It reuses target artifacts generated on a remote machine, served from a simple REST server. H

Spotify 737 Dec 27, 2022
A simple cache that can hold anything, including Swift items

CacheIsKing CacheIsKing is a simple cache that allows you to store any item, including objects, pure Swift structs, enums (with associated values), et

Christopher Luu 13 Jan 22, 2018
A simple but flexible cache

Carlos A simple but flexible cache, written in Swift for iOS 13+ and WatchOS 6 apps. Breaking Changes Carlos 1.0.0 has been migrated from PiedPiper de

National Media & Tech 628 Dec 3, 2022
MrCode is a simple GitHub iPhone App that can cache Markdown content (include images in HTML) for read it later.

MrCode is a simple GitHub iPhone App that can cache Markdown content (include images in HTML) for read it later.

hao 448 Dec 19, 2022