diff --git a/Cartfile b/Cartfile new file mode 100644 index 0000000..db752f0 --- /dev/null +++ b/Cartfile @@ -0,0 +1,16 @@ + +github "zixun/AppBaseKit" >= 0.2.0 +github "zixun/Log4G" >= 0.2.0 +github "zixun/AppSwizzle" >= 1.1.1 +github "zixun/AssistiveButton" >= 1.1.0 +github "zixun/ASLEye" >= 1.1.0 +github "zixun/CrashEye" >= 1.1.0 +github "zixun/ANREye" >= 1.1.0 +github "zixun/SystemEye" >= 0.2.0 +github "zixun/NetworkEye" >= 1.1.1 +github "zixun/LeakEye" >= 1.1.1 + +github "marmelroy/FileBrowser" >= 0.2.0 +github "startry/SwViewCapture" >= 1.0.5 +github "stephencelis/SQLite.swift" ~> 0.11.1 +github "eggswift/pull-to-refresh" ~> 2.6 \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved new file mode 100644 index 0000000..de5e142 --- /dev/null +++ b/Cartfile.resolved @@ -0,0 +1,14 @@ +github "eggswift/pull-to-refresh" "2.6" +github "marmelroy/FileBrowser" "0.2.0" +github "startry/SwViewCapture" "1.0.5" +github "stephencelis/SQLite.swift" "0.11.2" +github "zixun/ANREye" "1.1.0" +github "zixun/ASLEye" "1.1.0" +github "zixun/AppBaseKit" "0.2.0" +github "zixun/AppSwizzle" "1.1.1" +github "zixun/AssistiveButton" "1.1.0" +github "zixun/CrashEye" "1.1.0" +github "zixun/LeakEye" "1.1.1" +github "zixun/Log4G" "0.2.0" +github "zixun/NetworkEye" "1.1.1" +github "zixun/SystemEye" "0.2.0" diff --git a/Carthage/Checkouts/ANREye/.gitignore b/Carthage/Checkouts/ANREye/.gitignore new file mode 100644 index 0000000..1de2633 --- /dev/null +++ b/Carthage/Checkouts/ANREye/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/ANREye/ANREye.podspec b/Carthage/Checkouts/ANREye/ANREye.podspec new file mode 100644 index 0000000..2ee0495 --- /dev/null +++ b/Carthage/Checkouts/ANREye/ANREye.podspec @@ -0,0 +1,26 @@ +# +# Be sure to run `pod lib lint ANREye.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'ANREye' + s.version = '1.1.0' +s.summary = 'Class for monitor excessive blocking on the main thread.' + + s.description = <<-DESC +Class for monitor excessive blocking on the main thread and return the stacetrace of all threads. + DESC + + s.homepage = 'https://github.com/zixun/ANREye' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'zixun' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/ANREye.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + s.source_files = 'ANREye/Classes/**/*' +end diff --git a/Carthage/Checkouts/ANREye/ANREye/Classes/ANREye.swift b/Carthage/Checkouts/ANREye/ANREye/Classes/ANREye.swift new file mode 100644 index 0000000..3e17484 --- /dev/null +++ b/Carthage/Checkouts/ANREye/ANREye/Classes/ANREye.swift @@ -0,0 +1,127 @@ +// +// ANREye.swift +// Pods +// +// Created by zixun on 16/12/24. +// +// + +import Foundation + +//-------------------------------------------------------------------------- +// MARK: - ANREyeDelegate +//-------------------------------------------------------------------------- +@objc public protocol ANREyeDelegate: class { + @objc optional func anrEye(anrEye:ANREye, + catchWithThreshold threshold:Double, + mainThreadBacktrace:String?, + allThreadBacktrace:String?) +} + +//-------------------------------------------------------------------------- +// MARK: - ANREye +//-------------------------------------------------------------------------- +open class ANREye: NSObject { + + //-------------------------------------------------------------------------- + // MARK: OPEN PROPERTY + //-------------------------------------------------------------------------- + open weak var delegate: ANREyeDelegate? + + open var isOpening: Bool { + get { + guard let pingThread = self.pingThread else { + return false + } + return !pingThread.isCancelled + } + } + //-------------------------------------------------------------------------- + // MARK: OPEN FUNCTION + //-------------------------------------------------------------------------- + + open func open(with threshold:Double) { + if Thread.current.isMainThread { + AppBacktrace.main_thread_id = mach_thread_self() + }else { + DispatchQueue.main.async { + AppBacktrace.main_thread_id = mach_thread_self() + } + } + + self.pingThread = AppPingThread() + self.pingThread?.start(threshold: threshold, handler: { [weak self] in + guard let sself = self else { + return + } + + let main = AppBacktrace.mainThread() + let all = AppBacktrace.allThread() + sself.delegate?.anrEye?(anrEye: sself, + catchWithThreshold: threshold, + mainThreadBacktrace: main, + allThreadBacktrace: all) + + }) + } + + open func close() { + self.pingThread?.cancel() + } + + //-------------------------------------------------------------------------- + // MARK: LIFE CYCLE + //-------------------------------------------------------------------------- + deinit { + self.pingThread?.cancel() + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE PROPERTY + //-------------------------------------------------------------------------- + private var pingThread: AppPingThread? + +} + +//-------------------------------------------------------------------------- +// MARK: - GLOBAL DEFINE +//-------------------------------------------------------------------------- +public typealias AppPingThreadCallBack = () -> Void + +//-------------------------------------------------------------------------- +// MARK: - AppPingThread +//-------------------------------------------------------------------------- +private class AppPingThread: Thread { + + func start(threshold:Double, handler: @escaping AppPingThreadCallBack) { + self.handler = handler + self.threshold = threshold + self.start() + } + + override func main() { + + while self.isCancelled == false { + self.isMainThreadBlock = true + DispatchQueue.main.async { + self.isMainThreadBlock = false + self.semaphore.signal() + } + + Thread.sleep(forTimeInterval: self.threshold) + if self.isMainThreadBlock { + self.handler?() + } + + self.semaphore.wait(timeout: DispatchTime.distantFuture) + } + } + + private let semaphore = DispatchSemaphore(value: 0) + + private var isMainThreadBlock = false + + private var threshold: Double = 0.4 + + fileprivate var handler: (() -> Void)? +} diff --git a/Carthage/Checkouts/ANREye/ANREye/Classes/Backtrace/AppBacktrace.swift b/Carthage/Checkouts/ANREye/ANREye/Classes/Backtrace/AppBacktrace.swift new file mode 100644 index 0000000..b2d5215 --- /dev/null +++ b/Carthage/Checkouts/ANREye/ANREye/Classes/Backtrace/AppBacktrace.swift @@ -0,0 +1,100 @@ +// +// AppBacktrace.swift +// Pods +// +// Created by zixun on 16/12/19. +// +// + +import Foundation + +class AppBacktrace: NSObject { + + + class func with(thread: Thread) -> String { + let machThread = self.bs_machThread(from: thread) + return BSBacktraceLogger.backtrace(ofMachthread: machThread) + } + + class func currentThread() -> String { + return self.with(thread: Thread.current) + } + + class func mainThread() -> String { + return self.with(thread: Thread.main) + } + + class func allThread() -> String { + + var threads: thread_act_array_t? = nil + var thread_count = mach_msg_type_number_t() + + if task_threads(mach_task_self_, &(threads), &thread_count) != KERN_SUCCESS { + return "" + } + + var resultString = "Call Backtrace of \(thread_count) threads:\n" + + for i in 0.. thread_t { + + var name:[Int8] = Array(repeating:0, count:256) + + var list: thread_act_array_t? = nil + var count = mach_msg_type_number_t() + + if task_threads(mach_task_self_, &(list), &count) != KERN_SUCCESS { + return mach_thread_self() + } + + let currentTimestamp = NSDate().timeIntervalSince1970 + let originName = nsthread.name + nsthread.name = "\(currentTimestamp)" + + if nsthread.isMainThread { + return self.main_thread_id + } + + for i in 0.. + +#import +#include +#include +#include +#include +#include +#include +#include + +@interface BSBacktraceLogger : NSObject + ++ (NSString *)backtraceOfMachthread:(thread_t)thread; + +@end diff --git a/Carthage/Checkouts/ANREye/ANREye/Classes/Backtrace/BSBacktraceLogger.m b/Carthage/Checkouts/ANREye/ANREye/Classes/Backtrace/BSBacktraceLogger.m new file mode 100755 index 0000000..d56c086 --- /dev/null +++ b/Carthage/Checkouts/ANREye/ANREye/Classes/Backtrace/BSBacktraceLogger.m @@ -0,0 +1,357 @@ +// +// BSBacktraceLogger.m +// BSBacktraceLogger +// +// Created by 张星宇 on 16/8/27. +// Copyright © 2016年 bestswifter. All rights reserved. +// + +// Modified from https://github.com/bestswifter/BSBacktraceLogger +// I dont know how to use _STRUCT_MCONTEXT in swift, so this code is still in objective-c +// if you know it, please tell me at http://stackoverflow.com/questions/41314775/how-to-use-struct-mcontext-in-swift + +#import "BSBacktraceLogger.h" +#import +#include +#include +#include +#include +#include +#include +#include + +#pragma -mark DEFINE MACRO FOR DIFFERENT CPU ARCHITECTURE +#if defined(__arm64__) +#define DETAG_INSTRUCTION_ADDRESS(A) ((A) & ~(3UL)) +#define BS_THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT +#define BS_THREAD_STATE ARM_THREAD_STATE64 +#define BS_FRAME_POINTER __fp +#define BS_STACK_POINTER __sp +#define BS_INSTRUCTION_ADDRESS __pc + +#elif defined(__arm__) +#define DETAG_INSTRUCTION_ADDRESS(A) ((A) & ~(1UL)) +#define BS_THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT +#define BS_THREAD_STATE ARM_THREAD_STATE +#define BS_FRAME_POINTER __r[7] +#define BS_STACK_POINTER __sp +#define BS_INSTRUCTION_ADDRESS __pc + +#elif defined(__x86_64__) +#define DETAG_INSTRUCTION_ADDRESS(A) (A) +#define BS_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT +#define BS_THREAD_STATE x86_THREAD_STATE64 +#define BS_FRAME_POINTER __rbp +#define BS_STACK_POINTER __rsp +#define BS_INSTRUCTION_ADDRESS __rip + +#elif defined(__i386__) +#define DETAG_INSTRUCTION_ADDRESS(A) (A) +#define BS_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT +#define BS_THREAD_STATE x86_THREAD_STATE32 +#define BS_FRAME_POINTER __ebp +#define BS_STACK_POINTER __esp +#define BS_INSTRUCTION_ADDRESS __eip + +#endif + +#define CALL_INSTRUCTION_FROM_RETURN_ADDRESS(A) (DETAG_INSTRUCTION_ADDRESS((A)) - 1) + +#if defined(__LP64__) +#define TRACE_FMT "%-4d%-31s 0x%016lx %s + %lu" +#define POINTER_FMT "0x%016lx" +#define POINTER_SHORT_FMT "0x%lx" +#define BS_NLIST struct nlist_64 +#else +#define TRACE_FMT "%-4d%-31s 0x%08lx %s + %lu" +#define POINTER_FMT "0x%08lx" +#define POINTER_SHORT_FMT "0x%lx" +#define BS_NLIST struct nlist +#endif + + +typedef struct BSStackFrameEntry{ + const struct BSStackFrameEntry *const previous; + const uintptr_t return_address; +} BSStackFrameEntry; + +@implementation BSBacktraceLogger + ++ (NSString *)backtraceOfMachthread:(thread_t)thread { + return _bs_backtraceOfThread(thread); +} + +#pragma -mark Get call backtrace of a mach_thread +NSString *_bs_backtraceOfThread(thread_t thread) { + uintptr_t backtraceBuffer[50]; + int i = 0; + NSMutableString *resultString = [[NSMutableString alloc] initWithFormat:@"Backtrace of Thread %u:\n", thread]; + + _STRUCT_MCONTEXT machineContext; + if(!bs_fillThreadStateIntoMachineContext(thread, &machineContext)) { + return [NSString stringWithFormat:@"Fail to get information about thread: %u", thread]; + } + + const uintptr_t instructionAddress = bs_mach_instructionAddress(&machineContext); + backtraceBuffer[i] = instructionAddress; + ++i; + + uintptr_t linkRegister = bs_mach_linkRegister(&machineContext); + if (linkRegister) { + backtraceBuffer[i] = linkRegister; + i++; + } + + if(instructionAddress == 0) { + return @"Fail to get instruction address"; + } + + BSStackFrameEntry frame = {0}; + const uintptr_t framePtr = bs_mach_framePointer(&machineContext); + if(framePtr == 0 || + bs_mach_copyMem((void *)framePtr, &frame, sizeof(frame)) != KERN_SUCCESS) { + return @"Fail to get frame pointer"; + } + + for(; i < 50; i++) { + backtraceBuffer[i] = frame.return_address; + if(backtraceBuffer[i] == 0 || + frame.previous == 0 || + bs_mach_copyMem(frame.previous, &frame, sizeof(frame)) != KERN_SUCCESS) { + break; + } + } + + int backtraceLength = i; + Dl_info symbolicated[backtraceLength]; + bs_symbolicate(backtraceBuffer, symbolicated, backtraceLength, 0); + for (int i = 0; i < backtraceLength; ++i) { + [resultString appendFormat:@"%@", bs_logBacktraceEntry(i, backtraceBuffer[i], &symbolicated[i])]; + } + [resultString appendFormat:@"\n"]; + return [resultString copy]; +} + +#pragma -mark GenerateBacbsrackEnrty +NSString* bs_logBacktraceEntry(const int entryNum, + const uintptr_t address, + const Dl_info* const dlInfo) { + char faddrBuff[20]; + char saddrBuff[20]; + + const char* fname = bs_lastPathEntry(dlInfo->dli_fname); + if(fname == NULL) { + sprintf(faddrBuff, POINTER_FMT, (uintptr_t)dlInfo->dli_fbase); + fname = faddrBuff; + } + + uintptr_t offset = address - (uintptr_t)dlInfo->dli_saddr; + const char* sname = dlInfo->dli_sname; + if(sname == NULL) { + sprintf(saddrBuff, POINTER_SHORT_FMT, (uintptr_t)dlInfo->dli_fbase); + sname = saddrBuff; + offset = address - (uintptr_t)dlInfo->dli_fbase; + } + return [NSString stringWithFormat:@"%-30s 0x%08" PRIxPTR " %s + %lu\n" ,fname, (uintptr_t)address, sname, offset]; +} + +const char* bs_lastPathEntry(const char* const path) { + if(path == NULL) { + return NULL; + } + + char* lastFile = strrchr(path, '/'); + return lastFile == NULL ? path : lastFile + 1; +} + +#pragma -mark HandleMachineContext +bool bs_fillThreadStateIntoMachineContext(thread_t thread, _STRUCT_MCONTEXT *machineContext) { + mach_msg_type_number_t state_count = BS_THREAD_STATE_COUNT; + kern_return_t kr = thread_get_state(thread, BS_THREAD_STATE, (thread_state_t)&machineContext->__ss, &state_count); + return (kr == KERN_SUCCESS); +} + +uintptr_t bs_mach_framePointer(mcontext_t const machineContext){ + return machineContext->__ss.BS_FRAME_POINTER; +} + +uintptr_t bs_mach_stackPointer(mcontext_t const machineContext){ + return machineContext->__ss.BS_STACK_POINTER; +} + +uintptr_t bs_mach_instructionAddress(mcontext_t const machineContext){ + return machineContext->__ss.BS_INSTRUCTION_ADDRESS; +} + +uintptr_t bs_mach_linkRegister(mcontext_t const machineContext){ +#if defined(__i386__) || defined(__x86_64__) + return 0; +#else + return machineContext->__ss.__lr; +#endif +} + +kern_return_t bs_mach_copyMem(const void *const src, void *const dst, const size_t numBytes){ + vm_size_t bytesCopied = 0; + return vm_read_overwrite(mach_task_self(), (vm_address_t)src, (vm_size_t)numBytes, (vm_address_t)dst, &bytesCopied); +} + +#pragma -mark Symbolicate +void bs_symbolicate(const uintptr_t* const backtraceBuffer, + Dl_info* const symbolsBuffer, + const int numEntries, + const int skippedEntries){ + int i = 0; + + if(!skippedEntries && i < numEntries) { + bs_dladdr(backtraceBuffer[i], &symbolsBuffer[i]); + i++; + } + + for(; i < numEntries; i++) { + bs_dladdr(CALL_INSTRUCTION_FROM_RETURN_ADDRESS(backtraceBuffer[i]), &symbolsBuffer[i]); + } +} + +bool bs_dladdr(const uintptr_t address, Dl_info* const info) { + info->dli_fname = NULL; + info->dli_fbase = NULL; + info->dli_sname = NULL; + info->dli_saddr = NULL; + + const uint32_t idx = bs_imageIndexContainingAddress(address); + if(idx == UINT_MAX) { + return false; + } + const struct mach_header* header = _dyld_get_image_header(idx); + const uintptr_t imageVMAddrSlide = (uintptr_t)_dyld_get_image_vmaddr_slide(idx); + const uintptr_t addressWithSlide = address - imageVMAddrSlide; + const uintptr_t segmentBase = bs_segmentBaseOfImageIndex(idx) + imageVMAddrSlide; + if(segmentBase == 0) { + return false; + } + + info->dli_fname = _dyld_get_image_name(idx); + info->dli_fbase = (void*)header; + + // Find symbol tables and get whichever symbol is closest to the address. + const BS_NLIST* bestMatch = NULL; + uintptr_t bestDistance = ULONG_MAX; + uintptr_t cmdPtr = bs_firstCmdAfterHeader(header); + if(cmdPtr == 0) { + return false; + } + for(uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + const struct load_command* loadCmd = (struct load_command*)cmdPtr; + if(loadCmd->cmd == LC_SYMTAB) { + const struct symtab_command* symtabCmd = (struct symtab_command*)cmdPtr; + const BS_NLIST* symbolTable = (BS_NLIST*)(segmentBase + symtabCmd->symoff); + const uintptr_t stringTable = segmentBase + symtabCmd->stroff; + + for(uint32_t iSym = 0; iSym < symtabCmd->nsyms; iSym++) { + // If n_value is 0, the symbol refers to an external object. + if(symbolTable[iSym].n_value != 0) { + uintptr_t symbolBase = symbolTable[iSym].n_value; + uintptr_t currentDistance = addressWithSlide - symbolBase; + if((addressWithSlide >= symbolBase) && + (currentDistance <= bestDistance)) { + bestMatch = symbolTable + iSym; + bestDistance = currentDistance; + } + } + } + if(bestMatch != NULL) { + info->dli_saddr = (void*)(bestMatch->n_value + imageVMAddrSlide); + info->dli_sname = (char*)((intptr_t)stringTable + (intptr_t)bestMatch->n_un.n_strx); + if(*info->dli_sname == '_') { + info->dli_sname++; + } + // This happens if all symbols have been stripped. + if(info->dli_saddr == info->dli_fbase && bestMatch->n_type == 3) { + info->dli_sname = NULL; + } + break; + } + } + cmdPtr += loadCmd->cmdsize; + } + return true; +} + +uintptr_t bs_firstCmdAfterHeader(const struct mach_header* const header) { + switch(header->magic) { + case MH_MAGIC: + case MH_CIGAM: + return (uintptr_t)(header + 1); + case MH_MAGIC_64: + case MH_CIGAM_64: + return (uintptr_t)(((struct mach_header_64*)header) + 1); + default: + return 0; // Header is corrupt + } +} + +uint32_t bs_imageIndexContainingAddress(const uintptr_t address) { + const uint32_t imageCount = _dyld_image_count(); + const struct mach_header* header = 0; + + for(uint32_t iImg = 0; iImg < imageCount; iImg++) { + header = _dyld_get_image_header(iImg); + if(header != NULL) { + // Look for a segment command with this address within its range. + uintptr_t addressWSlide = address - (uintptr_t)_dyld_get_image_vmaddr_slide(iImg); + uintptr_t cmdPtr = bs_firstCmdAfterHeader(header); + if(cmdPtr == 0) { + continue; + } + for(uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + const struct load_command* loadCmd = (struct load_command*)cmdPtr; + if(loadCmd->cmd == LC_SEGMENT) { + const struct segment_command* segCmd = (struct segment_command*)cmdPtr; + if(addressWSlide >= segCmd->vmaddr && + addressWSlide < segCmd->vmaddr + segCmd->vmsize) { + return iImg; + } + } + else if(loadCmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64* segCmd = (struct segment_command_64*)cmdPtr; + if(addressWSlide >= segCmd->vmaddr && + addressWSlide < segCmd->vmaddr + segCmd->vmsize) { + return iImg; + } + } + cmdPtr += loadCmd->cmdsize; + } + } + } + return UINT_MAX; +} + +uintptr_t bs_segmentBaseOfImageIndex(const uint32_t idx) { + const struct mach_header* header = _dyld_get_image_header(idx); + + // Look for a segment command and return the file image address. + uintptr_t cmdPtr = bs_firstCmdAfterHeader(header); + if(cmdPtr == 0) { + return 0; + } + for(uint32_t i = 0;i < header->ncmds; i++) { + const struct load_command* loadCmd = (struct load_command*)cmdPtr; + if(loadCmd->cmd == LC_SEGMENT) { + const struct segment_command* segmentCmd = (struct segment_command*)cmdPtr; + if(strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) { + return segmentCmd->vmaddr - segmentCmd->fileoff; + } + } + else if(loadCmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64* segmentCmd = (struct segment_command_64*)cmdPtr; + if(strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) { + return (uintptr_t)(segmentCmd->vmaddr - segmentCmd->fileoff); + } + } + cmdPtr += loadCmd->cmdsize; + } + return 0; +} + +@end diff --git a/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/project.pbxproj b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0252b5e --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/project.pbxproj @@ -0,0 +1,765 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 26460D64FF89CA404F6F9D81 /* Pods_ANREye_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D477BAA2D2C568E57014022E /* Pods_ANREye_Tests.framework */; }; + 4C41E60C351787236285654C /* Pods_ANREye_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17C8179D6BA79973C5639ED7 /* Pods_ANREye_Example.framework */; }; + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 9E24FA1C1E800235001AD0D7 /* ANREye.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24FA1A1E800235001AD0D7 /* ANREye.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FA2C1E800248001AD0D7 /* ANREye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA251E800248001AD0D7 /* ANREye.swift */; }; + 9E24FA2D1E800248001AD0D7 /* AppBacktrace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA271E800248001AD0D7 /* AppBacktrace.swift */; }; + 9E24FA2E1E800248001AD0D7 /* BSBacktraceLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24FA281E800248001AD0D7 /* BSBacktraceLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FA2F1E800248001AD0D7 /* BSBacktraceLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA291E800248001AD0D7 /* BSBacktraceLogger.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = ANREye; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 17C8179D6BA79973C5639ED7 /* Pods_ANREye_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ANREye_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 35ED069C36A11AD2F07466B2 /* Pods-ANREye_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ANREye_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ANREye_Tests/Pods-ANREye_Tests.debug.xcconfig"; sourceTree = ""; }; + 4DA125C2EC1048CAF2DA4F0C /* Pods-ANREye_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ANREye_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ANREye_Tests/Pods-ANREye_Tests.release.xcconfig"; sourceTree = ""; }; + 59386A9F151384074DAC6FE1 /* Pods-ANREye_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ANREye_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ANREye_Example/Pods-ANREye_Example.debug.xcconfig"; sourceTree = ""; }; + 607FACD01AFB9204008FA782 /* ANREye_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ANREye_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 607FACE51AFB9204008FA782 /* ANREye_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ANREye_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + 7189F980354AB0955EDDDD72 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 9E24FA181E800235001AD0D7 /* ANREye.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ANREye.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24FA1A1E800235001AD0D7 /* ANREye.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ANREye.h; sourceTree = ""; }; + 9E24FA1B1E800235001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24FA251E800248001AD0D7 /* ANREye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ANREye.swift; sourceTree = ""; }; + 9E24FA271E800248001AD0D7 /* AppBacktrace.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppBacktrace.swift; sourceTree = ""; }; + 9E24FA281E800248001AD0D7 /* BSBacktraceLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSBacktraceLogger.h; sourceTree = ""; }; + 9E24FA291E800248001AD0D7 /* BSBacktraceLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSBacktraceLogger.m; sourceTree = ""; }; + A97E529EF46C0E73BCF0936E /* Pods-ANREye_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ANREye_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-ANREye_Example/Pods-ANREye_Example.release.xcconfig"; sourceTree = ""; }; + AEFB82F5E8C0849859110DCC /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + D477BAA2D2C568E57014022E /* Pods_ANREye_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ANREye_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F96FDA0B77D1A8DA5B6C3421 /* ANREye.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = ANREye.podspec; path = ../ANREye.podspec; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C41E60C351787236285654C /* Pods_ANREye_Example.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 26460D64FF89CA404F6F9D81 /* Pods_ANREye_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA141E800235001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for ANREye */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24FA191E800235001AD0D7 /* ANREye */, + 607FACD11AFB9204008FA782 /* Products */, + F481CFB638555D2CB490175F /* Pods */, + BAD394CD69BF5C6D7739C24B /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* ANREye_Example.app */, + 607FACE51AFB9204008FA782 /* ANREye_Tests.xctest */, + 9E24FA181E800235001AD0D7 /* ANREye.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for ANREye */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 607FACD91AFB9204008FA782 /* Main.storyboard */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for ANREye"; + path = ANREye; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* Tests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + F96FDA0B77D1A8DA5B6C3421 /* ANREye.podspec */, + 7189F980354AB0955EDDDD72 /* README.md */, + AEFB82F5E8C0849859110DCC /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 9E24FA191E800235001AD0D7 /* ANREye */ = { + isa = PBXGroup; + children = ( + 9E24FA201E800248001AD0D7 /* ANREye */, + 9E24FA1A1E800235001AD0D7 /* ANREye.h */, + 9E24FA1B1E800235001AD0D7 /* Info.plist */, + ); + path = ANREye; + sourceTree = ""; + }; + 9E24FA201E800248001AD0D7 /* ANREye */ = { + isa = PBXGroup; + children = ( + 9E24FA231E800248001AD0D7 /* Classes */, + ); + name = ANREye; + path = ../../ANREye; + sourceTree = ""; + }; + 9E24FA231E800248001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24FA251E800248001AD0D7 /* ANREye.swift */, + 9E24FA261E800248001AD0D7 /* Backtrace */, + ); + path = Classes; + sourceTree = ""; + }; + 9E24FA261E800248001AD0D7 /* Backtrace */ = { + isa = PBXGroup; + children = ( + 9E24FA271E800248001AD0D7 /* AppBacktrace.swift */, + 9E24FA281E800248001AD0D7 /* BSBacktraceLogger.h */, + 9E24FA291E800248001AD0D7 /* BSBacktraceLogger.m */, + ); + path = Backtrace; + sourceTree = ""; + }; + BAD394CD69BF5C6D7739C24B /* Frameworks */ = { + isa = PBXGroup; + children = ( + 17C8179D6BA79973C5639ED7 /* Pods_ANREye_Example.framework */, + D477BAA2D2C568E57014022E /* Pods_ANREye_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + F481CFB638555D2CB490175F /* Pods */ = { + isa = PBXGroup; + children = ( + 59386A9F151384074DAC6FE1 /* Pods-ANREye_Example.debug.xcconfig */, + A97E529EF46C0E73BCF0936E /* Pods-ANREye_Example.release.xcconfig */, + 35ED069C36A11AD2F07466B2 /* Pods-ANREye_Tests.debug.xcconfig */, + 4DA125C2EC1048CAF2DA4F0C /* Pods-ANREye_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24FA151E800235001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA2E1E800248001AD0D7 /* BSBacktraceLogger.h in Headers */, + 9E24FA1C1E800235001AD0D7 /* ANREye.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* ANREye_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ANREye_Example" */; + buildPhases = ( + F16460948FCD9B5B25284597 /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + A96451F5DA7D704B7664BC42 /* [CP] Embed Pods Frameworks */, + 318E782D9D4D2506721DCC6B /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ANREye_Example; + productName = ANREye; + productReference = 607FACD01AFB9204008FA782 /* ANREye_Example.app */; + productType = "com.apple.product-type.application"; + }; + 607FACE41AFB9204008FA782 /* ANREye_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ANREye_Tests" */; + buildPhases = ( + 615430759EFF5FDC646B15B0 /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + 8014C3A207A91B62A1E10B9D /* [CP] Embed Pods Frameworks */, + 75D25B4FC2E9E508876CE243 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 607FACE71AFB9204008FA782 /* PBXTargetDependency */, + ); + name = ANREye_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* ANREye_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24FA171E800235001AD0D7 /* ANREye */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24FA1F1E800235001AD0D7 /* Build configuration list for PBXNativeTarget "ANREye" */; + buildPhases = ( + 9E24FA131E800235001AD0D7 /* Sources */, + 9E24FA141E800235001AD0D7 /* Frameworks */, + 9E24FA151E800235001AD0D7 /* Headers */, + 9E24FA161E800235001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ANREye; + productName = ANREye; + productReference = 9E24FA181E800235001AD0D7 /* ANREye.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + }; + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24FA171E800235001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "ANREye" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* ANREye_Example */, + 607FACE41AFB9204008FA782 /* ANREye_Tests */, + 9E24FA171E800235001AD0D7 /* ANREye */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA161E800235001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 318E782D9D4D2506721DCC6B /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ANREye_Example/Pods-ANREye_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 615430759EFF5FDC646B15B0 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 75D25B4FC2E9E508876CE243 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ANREye_Tests/Pods-ANREye_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 8014C3A207A91B62A1E10B9D /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ANREye_Tests/Pods-ANREye_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A96451F5DA7D704B7664BC42 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ANREye_Example/Pods-ANREye_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F16460948FCD9B5B25284597 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA131E800235001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA2F1E800248001AD0D7 /* BSBacktraceLogger.m in Sources */, + 9E24FA2D1E800248001AD0D7 /* AppBacktrace.swift in Sources */, + 9E24FA2C1E800248001AD0D7 /* ANREye.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* ANREye_Example */; + targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 607FACD91AFB9204008FA782 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 607FACDA1AFB9204008FA782 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 59386A9F151384074DAC6FE1 /* Pods-ANREye_Example.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = ANREye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A97E529EF46C0E73BCF0936E /* Pods-ANREye_Example.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = ANREye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 35ED069C36A11AD2F07466B2 /* Pods-ANREye_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4DA125C2EC1048CAF2DA4F0C /* Pods-ANREye_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24FA1D1E800235001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = ANREye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.ANREye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24FA1E1E800235001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = ANREye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.ANREye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "ANREye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ANREye_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ANREye_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24FA1F1E800235001AD0D7 /* Build configuration list for PBXNativeTarget "ANREye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24FA1D1E800235001AD0D7 /* Debug */, + 9E24FA1E1E800235001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..7deb771 --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/project.xcworkspace/xcshareddata/ANREye.xcscmblueprint b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/project.xcworkspace/xcshareddata/ANREye.xcscmblueprint new file mode 100644 index 0000000..714b99a --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/project.xcworkspace/xcshareddata/ANREye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "0BF1E0159082E1DF1B0FEABA529982FE9AE6AF2B", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "0BF1E0159082E1DF1B0FEABA529982FE9AE6AF2B" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "63AE1624-B395-4D6D-B69C-44BAD6C6D1FF", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "0BF1E0159082E1DF1B0FEABA529982FE9AE6AF2B" : "ANREye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "ANREye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/ANREye.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/ANREye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "0BF1E0159082E1DF1B0FEABA529982FE9AE6AF2B" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/xcshareddata/xcschemes/ANREye-Example.xcscheme b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/xcshareddata/xcschemes/ANREye-Example.xcscheme new file mode 100644 index 0000000..fc28888 --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/xcshareddata/xcschemes/ANREye-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/xcshareddata/xcschemes/ANREye.xcscheme b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/xcshareddata/xcschemes/ANREye.xcscheme new file mode 100644 index 0000000..6748bbc --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye.xcodeproj/xcshareddata/xcschemes/ANREye.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/ANREye/Example/ANREye.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/ANREye/Example/ANREye.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c37d94a --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/ANREye/Example/ANREye.xcworkspace/xcshareddata/ANREye.xcscmblueprint b/Carthage/Checkouts/ANREye/Example/ANREye.xcworkspace/xcshareddata/ANREye.xcscmblueprint new file mode 100644 index 0000000..b040283 --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye.xcworkspace/xcshareddata/ANREye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "0BF1E0159082E1DF1B0FEABA529982FE9AE6AF2B", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "0BF1E0159082E1DF1B0FEABA529982FE9AE6AF2B" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "2845C86F-2D70-4C85-B508-12846456463C", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "0BF1E0159082E1DF1B0FEABA529982FE9AE6AF2B" : "ANREye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "ANREye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/ANREye.xcworkspace", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/ANREye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "0BF1E0159082E1DF1B0FEABA529982FE9AE6AF2B" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/ANREye/Example/ANREye/ANREye.h b/Carthage/Checkouts/ANREye/Example/ANREye/ANREye.h new file mode 100644 index 0000000..05ea594 --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye/ANREye.h @@ -0,0 +1,21 @@ +// +// ANREye.h +// ANREye +// +// Created by zixun on 2017/3/20. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for ANREye. +FOUNDATION_EXPORT double ANREyeVersionNumber; + +//! Project version string for ANREye. +FOUNDATION_EXPORT const unsigned char ANREyeVersionString[]; + +#import "BSBacktraceLogger.h" + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/ANREye/Example/ANREye/AppDelegate.swift b/Carthage/Checkouts/ANREye/Example/ANREye/AppDelegate.swift new file mode 100644 index 0000000..5d8d3fd --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// ANREye +// +// Created by zixun on 12/23/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Carthage/Checkouts/ANREye/Example/ANREye/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/ANREye/Example/ANREye/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..ad0f55e --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye/Base.lproj/LaunchScreen.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/ANREye/Example/ANREye/Base.lproj/Main.storyboard b/Carthage/Checkouts/ANREye/Example/ANREye/Base.lproj/Main.storyboard new file mode 100644 index 0000000..52ea29e --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/ANREye/Example/ANREye/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/ANREye/Example/ANREye/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d3942e9 --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/Carthage/Checkouts/ANREye/Example/ANREye/Info.plist b/Carthage/Checkouts/ANREye/Example/ANREye/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/ANREye/Example/ANREye/ViewController.swift b/Carthage/Checkouts/ANREye/Example/ANREye/ViewController.swift new file mode 100644 index 0000000..ffaf19f --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/ANREye/ViewController.swift @@ -0,0 +1,46 @@ +// +// ViewController.swift +// ANREye +// +// Created by zixun on 12/23/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit + +import ANREye + +class ViewController: UIViewController { + private var anrEye: ANREye! + override func viewDidLoad() { + super.viewDidLoad() + + self.anrEye = ANREye() + self.anrEye.delegate = self + self.anrEye.start(with: 1) + + var s = "" + for _ in 0..<9999 { + for _ in 0..<9999 { + s.append("1") + } + } + + print("invoke") + } + +} + +extension ViewController: ANREyeDelegate { + + func anrEye(anrEye:ANREye, + catchWithThreshold threshold:Double, + mainThreadBacktrace:String?, + allThreadBacktrace:String?) { + print("------------------") + print(mainThreadBacktrace!) + print("------------------") + print(allThreadBacktrace!) + } +} + diff --git a/Carthage/Checkouts/ANREye/Example/Podfile b/Carthage/Checkouts/ANREye/Example/Podfile new file mode 100644 index 0000000..1c4cb25 --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/Podfile @@ -0,0 +1,11 @@ +use_frameworks! + +target 'ANREye_Example' do + pod 'ANREye', :path => '../' + + target 'ANREye_Tests' do + inherit! :search_paths + + + end +end diff --git a/Carthage/Checkouts/ANREye/Example/Podfile.lock b/Carthage/Checkouts/ANREye/Example/Podfile.lock new file mode 100644 index 0000000..a2d8b2b --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - ANREye (0.1.0) + +DEPENDENCIES: + - ANREye (from `../`) + +EXTERNAL SOURCES: + ANREye: + :path: "../" + +SPEC CHECKSUMS: + ANREye: 850bd95d308567fa1b995c03ac794a6d20abea05 + +PODFILE CHECKSUM: 43dc7e3969babdfdafcfc1af13cfdfff612d2d56 + +COCOAPODS: 1.1.1 diff --git a/Carthage/Checkouts/ANREye/Example/Tests/Info.plist b/Carthage/Checkouts/ANREye/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/ANREye/Example/Tests/Tests.swift b/Carthage/Checkouts/ANREye/Example/Tests/Tests.swift new file mode 100644 index 0000000..04f1c0f --- /dev/null +++ b/Carthage/Checkouts/ANREye/Example/Tests/Tests.swift @@ -0,0 +1,29 @@ +import UIKit +import XCTest +import ANREye + +class Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + XCTAssert(true, "Pass") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure() { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Carthage/Checkouts/ANREye/LICENSE b/Carthage/Checkouts/ANREye/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/ANREye/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/ANREye/README.md b/Carthage/Checkouts/ANREye/README.md new file mode 100644 index 0000000..4259c33 --- /dev/null +++ b/Carthage/Checkouts/ANREye/README.md @@ -0,0 +1,89 @@ +# ANREye + +[![Version](https://img.shields.io/cocoapods/v/Log4G.svg?style=flat)](http://cocoapods.org/pods/ANREye) +[![License](https://img.shields.io/cocoapods/l/Log4G.svg?style=flat)](http://cocoapods.org/pods/ANREye) +[![Platform](https://img.shields.io/cocoapods/p/Log4G.svg?style=flat)](http://cocoapods.org/pods/ANREye) + +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) + +Class for monitor excessive blocking on the main thread + +## Family +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Book & Principle + +**I has wrote a book named [《iOS监控编程》](https://www.qingdan.us/product/25),each chapter records the course function of the implementation details and the way to explore.sorry for english friends,this book wrote by chineses.** + + +## Installation + +### CocoaPods +ANREye is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "ANREye" +``` + +### Carthage +Or, if you’re using [Carthage](https://github.com/Carthage/Carthage), add SwViewCapture to your Cartfile: + +``` +github "zixun/ANREye" +``` + + +## Usage +### open and add delegate + +```swift +self.anrEye = ANREye() +self.anrEye.delegate = self +self.anrEye.start(with: 1) +``` + +### implement the delegate + +```swift +extension ViewController: ANREyeDelegate { + + func anrEye(anrEye:ANREye, + catchWithThreshold threshold:Double, + mainThreadBacktrace:String?, + allThreadBacktrace:String?) { + print("------------------") + print(mainThreadBacktrace!) + print("------------------") + print(allThreadBacktrace!) + } +} +``` + +### test code +```swift +var s = "" +for _ in 0..<9999 { + for _ in 0..<9999 { + s.append("1") + } +} + +print("invoke") +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + +## License + +ANREye is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/ANREye/_Pods.xcodeproj b/Carthage/Checkouts/ANREye/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/ANREye/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/ASLEye/.gitignore b/Carthage/Checkouts/ASLEye/.gitignore new file mode 100644 index 0000000..1de2633 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/ASLEye/ASLEye.podspec b/Carthage/Checkouts/ASLEye/ASLEye.podspec new file mode 100644 index 0000000..5f83658 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/ASLEye.podspec @@ -0,0 +1,28 @@ +# +# Be sure to run `pod lib lint ASLEye.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'ASLEye' + s.version = '1.1.0' + s.summary = 'ASLEye is an ASL monitor, automatic catch the log from NSLog by asl module.' + + s.description = <<-DESC +ASLEye is an ASL(Apple System Log) monitor, automatic catch the log from NSLog by asl module. + DESC + + s.homepage = 'https://github.com/zixun/ASLEye' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'zixun' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/ASLEye.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'ASLEye/Classes/**/*' + +end diff --git a/Carthage/Checkouts/ASLEye/ASLEye/Classes/ASLEye.swift b/Carthage/Checkouts/ASLEye/ASLEye/Classes/ASLEye.swift new file mode 100644 index 0000000..882e1e4 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/ASLEye/Classes/ASLEye.swift @@ -0,0 +1,112 @@ +// +// ASLEye.swift +// Pods +// +// Created by zixun on 16/12/25. +// +// + +import Foundation +import Foundation +import asl + +@objc public protocol ASLEyeDelegate: class { + @objc optional func aslEye(_ aslEye:ASLEye,catchLogs logs:[String]) +} + +open class ASLEye: NSObject { + + open weak var delegate: ASLEyeDelegate? + + open var isOpening: Bool { + get { + return self.timer?.isValid ?? false + } + } + + open func open(with interval:TimeInterval) { + self.timer = Timer.scheduledTimer(timeInterval: interval, + target: self, + selector: #selector(ASLEye.pollingLogs), + userInfo: nil, + repeats: true) + } + + open func close() { + self.timer?.invalidate() + self.timer = nil + + } + + + @objc fileprivate func pollingLogs() { + self.queue.async { + let logs = self.retrieveLogs() + if logs.count > 0 { + DispatchQueue.main.async { + self.delegate?.aslEye?(self, catchLogs: logs) + } + } + } + } + + fileprivate func retrieveLogs() -> [String] { + var logs = [String]() + + let query: aslmsg = self.initQuery() + + let response: aslresponse? = asl_search(nil, query) + guard response != nil else { + return logs + } + + var message = asl_next(response) + while (message != nil) { + let log = self.parserLog(from: message!) + logs.append(log) + + message = asl_next(response) + } + asl_free(response) + asl_free(query) + + return logs + } + + fileprivate func parserLog(from message:aslmsg) ->String { + let content = asl_get(message, ASL_KEY_MSG)!; + let msg_id = asl_get(message, ASL_KEY_MSG_ID); + + let m = atoi(msg_id); + if (m != 0) { + self.lastMessageID = m; + } + + return String(cString: content, encoding: String.Encoding.utf8)! + } + + fileprivate func initQuery() -> aslmsg { + let query: aslmsg = asl_new(UInt32(ASL_TYPE_QUERY)) + //set BundleIdentifier to ASL_KEY_FACILITY + let bundleIdentifier = (Bundle.main.bundleIdentifier! as NSString).utf8String + asl_set_query(query, ASL_KEY_FACILITY, bundleIdentifier, UInt32(ASL_QUERY_OP_EQUAL)) + + //set pid to ASL_KEY_PID + let pid = NSString(format: "%d", getpid()).cString(using: String.Encoding.utf8.rawValue) + asl_set_query(query, ASL_KEY_PID, pid, UInt32(ASL_QUERY_OP_NUMERIC)) + + if self.lastMessageID != 0 { + let m = NSString(format: "%d", self.lastMessageID).utf8String + asl_set_query(query, ASL_KEY_MSG_ID, m, UInt32(ASL_QUERY_OP_GREATER | ASL_QUERY_OP_NUMERIC)); + } + + return query + } + + fileprivate var timer: Timer? + + fileprivate var lastMessageID: Int32 = 0 + + fileprivate var queue = DispatchQueue(label: "ASLEyeQueue") + +} diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/project.pbxproj b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/project.pbxproj new file mode 100644 index 0000000..2e404c9 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/project.pbxproj @@ -0,0 +1,757 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 3FB830E4D90993DE8BC4287B /* Pods_ASLEye_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CAD08C94955EDD1A51ABE64 /* Pods_ASLEye_Tests.framework */; }; + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 9E24FA3D1E8022E0001AD0D7 /* ASLEye.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24FA3B1E8022E0001AD0D7 /* ASLEye.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FA4B1E802300001AD0D7 /* ASLEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA481E802300001AD0D7 /* ASLEye.swift */; }; + B184FA401C56BC007E744BCF /* Pods_ASLEye_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BA43B4C0F6B1506E5386679 /* Pods_ASLEye_Example.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = ASLEye; + }; + 9E24FA411E8022F4001AD0D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9E24FA381E8022E0001AD0D7; + remoteInfo = ASLEye; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0E77C8170DC530930B874E51 /* Pods-ASLEye_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASLEye_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-ASLEye_Example/Pods-ASLEye_Example.release.xcconfig"; sourceTree = ""; }; + 1CAD08C94955EDD1A51ABE64 /* Pods_ASLEye_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ASLEye_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4013146AFCF41C7249A65F32 /* Pods-ASLEye_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASLEye_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ASLEye_Tests/Pods-ASLEye_Tests.debug.xcconfig"; sourceTree = ""; }; + 525E04F5A47F3135FE6E1268 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 606D13E95387C2D54850C845 /* ASLEye.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = ASLEye.podspec; path = ../ASLEye.podspec; sourceTree = ""; }; + 607FACD01AFB9204008FA782 /* ASLEye_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ASLEye_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 607FACE51AFB9204008FA782 /* ASLEye_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ASLEye_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + 734BDBD92DBDA233B02BC329 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + 7BA43B4C0F6B1506E5386679 /* Pods_ASLEye_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ASLEye_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24FA391E8022E0001AD0D7 /* ASLEye.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ASLEye.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24FA3B1E8022E0001AD0D7 /* ASLEye.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ASLEye.h; sourceTree = ""; }; + 9E24FA3C1E8022E0001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24FA481E802300001AD0D7 /* ASLEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASLEye.swift; sourceTree = ""; }; + A0198BC7365481C42415293D /* Pods-ASLEye_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASLEye_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ASLEye_Tests/Pods-ASLEye_Tests.release.xcconfig"; sourceTree = ""; }; + E2393EF10E0BF4309CC3E292 /* Pods-ASLEye_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ASLEye_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ASLEye_Example/Pods-ASLEye_Example.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B184FA401C56BC007E744BCF /* Pods_ASLEye_Example.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3FB830E4D90993DE8BC4287B /* Pods_ASLEye_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA351E8022E0001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 21F889D69CFB03FD8DFEF4F6 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7BA43B4C0F6B1506E5386679 /* Pods_ASLEye_Example.framework */, + 1CAD08C94955EDD1A51ABE64 /* Pods_ASLEye_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 4645BCB22EDD97F87A78A8C6 /* Pods */ = { + isa = PBXGroup; + children = ( + E2393EF10E0BF4309CC3E292 /* Pods-ASLEye_Example.debug.xcconfig */, + 0E77C8170DC530930B874E51 /* Pods-ASLEye_Example.release.xcconfig */, + 4013146AFCF41C7249A65F32 /* Pods-ASLEye_Tests.debug.xcconfig */, + A0198BC7365481C42415293D /* Pods-ASLEye_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for ASLEye */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24FA3A1E8022E0001AD0D7 /* ASLEye */, + 607FACD11AFB9204008FA782 /* Products */, + 4645BCB22EDD97F87A78A8C6 /* Pods */, + 21F889D69CFB03FD8DFEF4F6 /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* ASLEye_Example.app */, + 607FACE51AFB9204008FA782 /* ASLEye_Tests.xctest */, + 9E24FA391E8022E0001AD0D7 /* ASLEye.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for ASLEye */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 607FACD91AFB9204008FA782 /* Main.storyboard */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for ASLEye"; + path = ASLEye; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* Tests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + 606D13E95387C2D54850C845 /* ASLEye.podspec */, + 525E04F5A47F3135FE6E1268 /* README.md */, + 734BDBD92DBDA233B02BC329 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 9E24FA3A1E8022E0001AD0D7 /* ASLEye */ = { + isa = PBXGroup; + children = ( + 9E24FA431E802300001AD0D7 /* ASLEye */, + 9E24FA3B1E8022E0001AD0D7 /* ASLEye.h */, + 9E24FA3C1E8022E0001AD0D7 /* Info.plist */, + ); + path = ASLEye; + sourceTree = ""; + }; + 9E24FA431E802300001AD0D7 /* ASLEye */ = { + isa = PBXGroup; + children = ( + 9E24FA461E802300001AD0D7 /* Classes */, + ); + name = ASLEye; + path = ../../ASLEye; + sourceTree = ""; + }; + 9E24FA461E802300001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24FA481E802300001AD0D7 /* ASLEye.swift */, + ); + path = Classes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24FA361E8022E0001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA3D1E8022E0001AD0D7 /* ASLEye.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* ASLEye_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ASLEye_Example" */; + buildPhases = ( + 4EDEC8D83C8DF0DB6E05ABCB /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + 3611E782D79D1E8D7EE5835F /* [CP] Embed Pods Frameworks */, + 28C29C82D50D541D3373DE0C /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9E24FA421E8022F4001AD0D7 /* PBXTargetDependency */, + ); + name = ASLEye_Example; + productName = ASLEye; + productReference = 607FACD01AFB9204008FA782 /* ASLEye_Example.app */; + productType = "com.apple.product-type.application"; + }; + 607FACE41AFB9204008FA782 /* ASLEye_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ASLEye_Tests" */; + buildPhases = ( + E87C5764BADA8C741ECBE3DB /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + D83602ACF7991C6D6F2E8B49 /* [CP] Embed Pods Frameworks */, + 62EDEB7B5CF7DA06A21C0D43 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 607FACE71AFB9204008FA782 /* PBXTargetDependency */, + ); + name = ASLEye_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* ASLEye_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24FA381E8022E0001AD0D7 /* ASLEye */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24FA401E8022E0001AD0D7 /* Build configuration list for PBXNativeTarget "ASLEye" */; + buildPhases = ( + 9E24FA341E8022E0001AD0D7 /* Sources */, + 9E24FA351E8022E0001AD0D7 /* Frameworks */, + 9E24FA361E8022E0001AD0D7 /* Headers */, + 9E24FA371E8022E0001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ASLEye; + productName = ASLEye; + productReference = 9E24FA391E8022E0001AD0D7 /* ASLEye.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + }; + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24FA381E8022E0001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + LastSwiftMigration = 0820; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "ASLEye" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* ASLEye_Example */, + 607FACE41AFB9204008FA782 /* ASLEye_Tests */, + 9E24FA381E8022E0001AD0D7 /* ASLEye */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA371E8022E0001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 28C29C82D50D541D3373DE0C /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ASLEye_Example/Pods-ASLEye_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 3611E782D79D1E8D7EE5835F /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ASLEye_Example/Pods-ASLEye_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 4EDEC8D83C8DF0DB6E05ABCB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 62EDEB7B5CF7DA06A21C0D43 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ASLEye_Tests/Pods-ASLEye_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + D83602ACF7991C6D6F2E8B49 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ASLEye_Tests/Pods-ASLEye_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + E87C5764BADA8C741ECBE3DB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA341E8022E0001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA4B1E802300001AD0D7 /* ASLEye.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* ASLEye_Example */; + targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; + }; + 9E24FA421E8022F4001AD0D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9E24FA381E8022E0001AD0D7 /* ASLEye */; + targetProxy = 9E24FA411E8022F4001AD0D7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 607FACD91AFB9204008FA782 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 607FACDA1AFB9204008FA782 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E2393EF10E0BF4309CC3E292 /* Pods-ASLEye_Example.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = ASLEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0E77C8170DC530930B874E51 /* Pods-ASLEye_Example.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = ASLEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4013146AFCF41C7249A65F32 /* Pods-ASLEye_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A0198BC7365481C42415293D /* Pods-ASLEye_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24FA3E1E8022E0001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = ASLEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.ASLEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24FA3F1E8022E0001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = ASLEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.ASLEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "ASLEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ASLEye_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ASLEye_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24FA401E8022E0001AD0D7 /* Build configuration list for PBXNativeTarget "ASLEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24FA3E1E8022E0001AD0D7 /* Debug */, + 9E24FA3F1E8022E0001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..fec5205 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/project.xcworkspace/xcshareddata/ASLEye.xcscmblueprint b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/project.xcworkspace/xcshareddata/ASLEye.xcscmblueprint new file mode 100644 index 0000000..b3d12cd --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/project.xcworkspace/xcshareddata/ASLEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "04F333FDAC6B3FF5A3153B1765B5F99DB10B55A0", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "04F333FDAC6B3FF5A3153B1765B5F99DB10B55A0" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "034F5A1F-7825-4C9C-BE35-00DA024E365D", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "04F333FDAC6B3FF5A3153B1765B5F99DB10B55A0" : "ASLEye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "ASLEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/ASLEye.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/ASLEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "04F333FDAC6B3FF5A3153B1765B5F99DB10B55A0" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/xcshareddata/xcschemes/ASLEye-Example.xcscheme b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/xcshareddata/xcschemes/ASLEye-Example.xcscheme new file mode 100644 index 0000000..57d9b2b --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/xcshareddata/xcschemes/ASLEye-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/xcshareddata/xcschemes/ASLEye.xcscheme b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/xcshareddata/xcschemes/ASLEye.xcscheme new file mode 100644 index 0000000..159f950 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcodeproj/xcshareddata/xcschemes/ASLEye.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..7b10cf4 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye.xcworkspace/xcshareddata/ASLEye.xcscmblueprint b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcworkspace/xcshareddata/ASLEye.xcscmblueprint new file mode 100644 index 0000000..3dd242b --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye.xcworkspace/xcshareddata/ASLEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "04F333FDAC6B3FF5A3153B1765B5F99DB10B55A0", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "04F333FDAC6B3FF5A3153B1765B5F99DB10B55A0" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "E128103C-34B2-4D55-BA0B-23DE117BF993", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "04F333FDAC6B3FF5A3153B1765B5F99DB10B55A0" : "ASLEye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "ASLEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/ASLEye.xcworkspace", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:GodEyeSwift\/ASLEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "04F333FDAC6B3FF5A3153B1765B5F99DB10B55A0" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye/ASLEye.h b/Carthage/Checkouts/ASLEye/Example/ASLEye/ASLEye.h new file mode 100644 index 0000000..c56b3c8 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye/ASLEye.h @@ -0,0 +1,19 @@ +// +// ASLEye.h +// ASLEye +// +// Created by zixun on 2017/3/20. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for ASLEye. +FOUNDATION_EXPORT double ASLEyeVersionNumber; + +//! Project version string for ASLEye. +FOUNDATION_EXPORT const unsigned char ASLEyeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye/AppDelegate.swift b/Carthage/Checkouts/ASLEye/Example/ASLEye/AppDelegate.swift new file mode 100644 index 0000000..825b00c --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// ASLEye +// +// Created by zixun on 12/25/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/ASLEye/Example/ASLEye/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..332f4e0 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye/Base.lproj/LaunchScreen.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye/Base.lproj/Main.storyboard b/Carthage/Checkouts/ASLEye/Example/ASLEye/Base.lproj/Main.storyboard new file mode 100644 index 0000000..52ea29e --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/ASLEye/Example/ASLEye/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d3942e9 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye/Info.plist b/Carthage/Checkouts/ASLEye/Example/ASLEye/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/ASLEye/Example/ASLEye/ViewController.swift b/Carthage/Checkouts/ASLEye/Example/ASLEye/ViewController.swift new file mode 100644 index 0000000..a891a8d --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/ASLEye/ViewController.swift @@ -0,0 +1,35 @@ +// +// ViewController.swift +// ASLEye +// +// Created by zixun on 12/25/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit +import ASLEye + +class ViewController: UIViewController { + + var aslEye: ASLEye! + + override func viewDidLoad() { + super.viewDidLoad() + + NSLog("abb") + self.aslEye = ASLEye() + self.aslEye.delegate = self + self.aslEye.open(with: 2) + + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 4) { + NSLog("2") + } + } + +} + +extension ViewController: ASLEyeDelegate { + func aslEye(aslEye:ASLEye,catchLogs logs:[String]) { + print(logs) + } +} diff --git a/Carthage/Checkouts/ASLEye/Example/Podfile b/Carthage/Checkouts/ASLEye/Example/Podfile new file mode 100644 index 0000000..b9718c6 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/Podfile @@ -0,0 +1,11 @@ +use_frameworks! + +target 'ASLEye_Example' do + pod 'ASLEye', :path => '../' + + target 'ASLEye_Tests' do + inherit! :search_paths + + + end +end diff --git a/Carthage/Checkouts/ASLEye/Example/Podfile.lock b/Carthage/Checkouts/ASLEye/Example/Podfile.lock new file mode 100644 index 0000000..fa33dcc --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - ASLEye (1.0.0) + +DEPENDENCIES: + - ASLEye (from `../`) + +EXTERNAL SOURCES: + ASLEye: + :path: "../" + +SPEC CHECKSUMS: + ASLEye: 3e59870bff471f1110854a2b28016e29eb573d51 + +PODFILE CHECKSUM: bbb483b01a60f5f0dbfdbb76800e9548ef73ae86 + +COCOAPODS: 1.2.0 diff --git a/Carthage/Checkouts/ASLEye/Example/Tests/Info.plist b/Carthage/Checkouts/ASLEye/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/ASLEye/Example/Tests/Tests.swift b/Carthage/Checkouts/ASLEye/Example/Tests/Tests.swift new file mode 100644 index 0000000..1ddc316 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/Example/Tests/Tests.swift @@ -0,0 +1,29 @@ +import UIKit +import XCTest +import ASLEye + +class Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + XCTAssert(true, "Pass") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure() { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Carthage/Checkouts/ASLEye/LICENSE b/Carthage/Checkouts/ASLEye/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/ASLEye/README.md b/Carthage/Checkouts/ASLEye/README.md new file mode 100644 index 0000000..68e8f58 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/README.md @@ -0,0 +1,62 @@ +# ASLEye + +[![Version](https://img.shields.io/cocoapods/v/Log4G.svg?style=flat)](http://cocoapods.org/pods/ASLEye) +[![License](https://img.shields.io/cocoapods/l/Log4G.svg?style=flat)](http://cocoapods.org/pods/ASLEye) +[![Platform](https://img.shields.io/cocoapods/p/Log4G.svg?style=flat)](http://cocoapods.org/pods/ASLEye) + + +ASLEye is an ASL(Apple System Log) monitor, automatic catch the log from NSLog by asl module + +## Family +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Book & Principle + +**I has wrote a book named [《iOS监控编程》](https://www.qingdan.us/product/25),each chapter records the course function of the implementation details and the way to explore.sorry for english friends,this book wrote by chineses.** + +## Example + +To run the example project, clone the repo, and run `pod install` from the Example directory first. + +## Usage + +1.init the asl eye: + +```swift +self.aslEye = ASLEye() +self.aslEye.delegate = self +self.aslEye.open(with: 2) +``` + +2.implement the `ASLEyeDelegate` delegate: + +```swift +func aslEye(aslEye:ASLEye,catchLogs logs:[String]) { + print(logs) +} +``` + +## Installation + +ASLEye is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "ASLEye" +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + +## License + +ASLEye is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/ASLEye/_Pods.xcodeproj b/Carthage/Checkouts/ASLEye/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/ASLEye/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/AppBaseKit/.gitignore b/Carthage/Checkouts/AppBaseKit/.gitignore new file mode 100644 index 0000000..a119ed5 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/.gitignore @@ -0,0 +1,33 @@ +# OS X +.DS_Store + +# Xcode +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ +*.xccheckout +profile +*.moved-aside +DerivedData +*.hmap +*.ipa + +# Bundler +.bundle + +Carthage +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control +# +# Note: if you ignore the Pods directory, make sure to uncomment +# `pod install` in .travis.yml +# +Pods/ diff --git a/Carthage/Checkouts/AppBaseKit/.travis.yml b/Carthage/Checkouts/AppBaseKit/.travis.yml new file mode 100644 index 0000000..b1fa751 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/.travis.yml @@ -0,0 +1,14 @@ +# references: +# * http://www.objc.io/issue-6/travis-ci.html +# * https://github.com/supermarin/xcpretty#usage + +osx_image: xcode7.3 +language: objective-c +# cache: cocoapods +# podfile: Example/Podfile +# before_install: +# - gem install cocoapods # Since Travis is not always on latest version +# - pod install --project-directory=Example +script: +- set -o pipefail && xcodebuild test -workspace Example/AppBaseKit.xcworkspace -scheme AppBaseKit-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty +- pod lib lint diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit.podspec b/Carthage/Checkouts/AppBaseKit/AppBaseKit.podspec new file mode 100644 index 0000000..d4aea54 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit.podspec @@ -0,0 +1,41 @@ +# +# Be sure to run `pod lib lint AppBaseKit.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'AppBaseKit' + s.version = '0.2.0' + s.summary = 'A handy kit of Swift extensions and wrapped class to boost your productivity.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +A handy kit of Swift extensions and wrapped class to boost your productivity. + DESC + + s.homepage = 'https://github.com/zixun/AppBaseKit' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { '陈奕龙' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/AppBaseKit.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'AppBaseKit/Classes/**/*' + + # s.resource_bundles = { + # 'AppBaseKit' => ['AppBaseKit/Assets/*.png'] + # } + + # s.public_header_files = 'Pod/Classes/**/*.h' + # s.frameworks = 'UIKit', 'MapKit' + # s.dependency 'AFNetworking', '~> 2.3' +end diff --git a/GodEye/Assets/.gitkeep b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Assets/.gitkeep similarity index 100% rename from GodEye/Assets/.gitkeep rename to Carthage/Checkouts/AppBaseKit/AppBaseKit/Assets/.gitkeep diff --git a/GodEye/Classes/.gitkeep b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/.gitkeep similarity index 100% rename from GodEye/Classes/.gitkeep rename to Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/.gitkeep diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/Foundation/NSFileManager+AppBaseKit.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/Foundation/NSFileManager+AppBaseKit.swift new file mode 100644 index 0000000..f54f9f6 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/Foundation/NSFileManager+AppBaseKit.swift @@ -0,0 +1,41 @@ +// +// NSFileManager+AppBaseKit.swift +// Pods +// +// Created by zixun on 16/9/25. +// +// + +import Foundation + +extension FileManager { + + public class func createDirectoryIfNotExists(path:String) -> Bool { + + let fileManager = self.default + var isDir: ObjCBool = false + let exists = fileManager.fileExists(atPath: path, isDirectory: &isDir) + if exists == false || isDir.boolValue == false { + do { + try fileManager.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil) + }catch { + return false + } + } + return true + } + + public class func removeItemIfExists(path:String) ->Bool { + let fileManager = self.default + var isDir: ObjCBool = false + let exists = fileManager.fileExists(atPath: path, isDirectory: &isDir) + if exists == true { + do { + try fileManager.removeItem(atPath: path) + }catch { + return false + } + } + return true + } +} diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/Foundation/NSObject+Closure.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/Foundation/NSObject+Closure.swift new file mode 100644 index 0000000..db9b490 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/Foundation/NSObject+Closure.swift @@ -0,0 +1,34 @@ +// +// NSObject+Closure.swift +// Pods +// +// Created by zixun on 2016/10/22. +// +// + +import Foundation + +public extension NSObject { + + func perform(closure:@escaping ()->(), afterDelay:TimeInterval) -> Void { + + var canceled = false + + func wrappingClosure(cancel:Bool)->Void { + if cancel { + canceled = true + return + } + + if canceled == false { + closure() + } + } + + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + afterDelay) { + wrappingClosure(cancel: false) + } + + } + +} diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/Foundation/String+AppBaseKit.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/Foundation/String+AppBaseKit.swift new file mode 100644 index 0000000..3cfeb2d --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/Foundation/String+AppBaseKit.swift @@ -0,0 +1,13 @@ +// +// String+AppBaseKit.swift +// Pods +// +// Created by zixun on 16/9/25. +// +// + +import Foundation +// MARK: - 方便转NSString +extension String { + public var NS: NSString { return (self as NSString) } +} diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIAlertController+AppBaseKit.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIAlertController+AppBaseKit.swift new file mode 100644 index 0000000..be16a46 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIAlertController+AppBaseKit.swift @@ -0,0 +1,42 @@ +// +// UIAlertController+AppExtension.swift +// Pods +// +// Created by zixun on 16/9/25. +// +// + +import Foundation +import UIKit + +extension UIAlertController { + + public class func quickTip(message:String, navigation:UINavigationController?,title:String = "Tip",cancelButtonTitle:String = "OK") { + let alertView = UIAlertController(title: title, message: message, preferredStyle: .alert) + alertView.addAction(UIAlertAction(title: cancelButtonTitle, style: .cancel) { _ in + + }) + + navigation?.present(alertView, animated: true, completion: nil) + } + + public class func quickConfirm(message:String, + title:String, + destructive:Bool = false, + navigation:UINavigationController?, + cancelButtonTitle:String = "No", + confirmButtonTitle:String = "Yes", + clickedButtonAtIndex:@escaping ( _ buttonIndex: Int)->()) { + let alertView = UIAlertController(title: title, message: message, preferredStyle: .alert) + alertView.addAction(UIAlertAction(title: cancelButtonTitle, style: .cancel) { _ in + clickedButtonAtIndex(0) + }) + + let style = destructive == false ? UIAlertActionStyle.default : .destructive + alertView.addAction(UIAlertAction(title: confirmButtonTitle, style: style) { _ in + clickedButtonAtIndex(1) + }) + + navigation?.present(alertView, animated: true, completion: nil) + } +} diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIAlertView+AppBaseKit.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIAlertView+AppBaseKit.swift new file mode 100644 index 0000000..b486143 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIAlertView+AppBaseKit.swift @@ -0,0 +1,67 @@ +// +// UIAlertView+AppBaseKit.swift +// Pods +// +// Created by zixun on 16/9/25. +// +// + +import Foundation +import UIKit + +private var key = "kUIAlertViewHandler" +extension UIAlertView { + + + private var handler:UIAlertViewHandler?{ + set{ + objc_setAssociatedObject(self, &key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + get{ + return objc_getAssociatedObject(self, &key) as! UIAlertViewHandler? + } + } + + + + public class func quickTip(message: String, + title: String = "Tip", + cancelButtonTitle: String = "OK") { + UIAlertView(title: title, message: message, delegate: nil, cancelButtonTitle: cancelButtonTitle).show() + } + + public class func quickConfirm(message: String, + title: String, + cancelButtonTitle:String = "No", + confirmButtonTitle:String = "Yes", + clickedButtonAtIndex:@escaping ( _ buttonIndex: Int)->()) { + + let alert = UIAlertView(title: title, + message: message, + delegate: nil, + cancelButtonTitle: cancelButtonTitle, + otherButtonTitles: confirmButtonTitle) + + alert.handler = UIAlertViewHandler { (handler, index) in + clickedButtonAtIndex(index) + } + alert.delegate = alert.handler + alert.show() + } +} + + +private class UIAlertViewHandler: NSObject,UIAlertViewDelegate { + typealias ClickBlock = (_ handler:UIAlertViewHandler,_ index:Int)->() + + private var clickBlock: ClickBlock! + + init(clickBlock:@escaping ClickBlock) { + super.init() + self.clickBlock = clickBlock + } + + @objc func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) { + self.clickBlock(self,buttonIndex) + } +} diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIApplication+AppBaseKit.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIApplication+AppBaseKit.swift new file mode 100644 index 0000000..15ec415 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIApplication+AppBaseKit.swift @@ -0,0 +1,28 @@ +// +// UIApplication+AppBaseKit.swift +// Pods +// +// Created by zixun on 16/9/25. +// +// + +import Foundation +import UIKit + + +// MARK: - MainWindow +extension UIApplication { + + public func mainWindow() -> UIWindow? { + guard let delegate = self.delegate else { + return self.keyWindow + } + + guard delegate.responds(to: Selector("window")) else { + return self.keyWindow + } + + return delegate.window! + } +} + diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIColor+AppBaseKit.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIColor+AppBaseKit.swift new file mode 100644 index 0000000..cacfb8f --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIColor+AppBaseKit.swift @@ -0,0 +1,105 @@ +// +// UIColor+AppBaseKit.swift +// Pods +// +// Created by zixun on 16/9/25. +// +// + +import Foundation +import UIKit + +extension UIColor { + + public class func niceBlack() -> UIColor { + return UIColor(red: 30.0/255.0, green: 32.0/255.0, blue: 40.0/255.0, alpha: 1) + } + + public class func niceDuckBlack() -> UIColor { + return UIColor(red: 20.0/255.0, green: 21.0/255.0, blue: 27.0/255.0, alpha: 1) + } + + public class func niceRed() -> UIColor { + return UIColor(red: 237.0/255.0, green: 66.0/255.0, blue: 82.0/255.0, alpha: 1) + } + + public class func niceJHSRed() -> UIColor { + return UIColor(red: 235.0/255.0, green: 0.0/255.0, blue: 18.0/255.0, alpha: 1) + } +} + +// MARK: - RGB +extension UIColor { + public convenience init(hex:Int, alpha:CGFloat = 1.0) { + let red: CGFloat = CGFloat((hex & 0xFF0000) >> 16) / 255.0 + let green: CGFloat = CGFloat((hex & 0x00FF00) >> 8) / 255.0 + let blue: CGFloat = CGFloat((hex & 0x0000FF)) / 255.0 + self.init(red: red, green: green, blue: blue, alpha: alpha) + } + + public convenience init?(hexString:String,alpha:CGFloat = 1.0) { + let formatted = hexString.replacingOccurrences(of: "0x", with: "") + .replacingOccurrences(of:"#", with: "") + if let hex = Int(formatted, radix: 16) { + self.init(hex: hex, alpha: alpha) + } + return nil + } + + public func hexString(prefix:String = "") -> String { + let rgbFloat = self.rgba() + + let result = self.string(of: rgbFloat.r) + self.string(of: rgbFloat.g) + self.string(of: rgbFloat.b) + return prefix + result.uppercased() + } + + private func string(of component:Int) -> String { + var result = String(format: "%x", component) + let count = result.characters.count + if count == 0 { + return "00" + }else if count == 1 { + return "0" + result + }else { + return result + } + } + + + public func hex() -> Int? { + return Int(self.hexString(), radix: 16) + } + + public func rgba() -> (r:Int,g:Int,b:Int,a:CGFloat) { + var r: CGFloat = 0 + var g: CGFloat = 0 + var b: CGFloat = 0 + var a: CGFloat = 0 + self.getRed(&r, green: &g, blue: &b, alpha: &a) + r = r * 255 + g = g * 255 + b = b * 255 + + return (Int(r),Int(g),Int(b),a) + } +} + +// MARK: - Gradient +extension UIColor { + + public class func gradient(startColor:UIColor,endColor:UIColor,fraction:CGFloat) -> UIColor { + var startR: CGFloat = 0, startG: CGFloat = 0, startB: CGFloat = 0, startA: CGFloat = 0 + startColor.getRed(&startR, green: &startG, blue: &startB, alpha: &startA) + + var endR: CGFloat = 0, endG: CGFloat = 0, endB: CGFloat = 0, endA: CGFloat = 0 + endColor.getRed(&endR, green: &endG, blue: &endB, alpha: &endA) + + let resultA = startA + (endA - startA) * fraction + let resultR = startR + (endR - startR) * fraction + let resultG = startG + (endG - startG) * fraction + let resultB = startB + (endB - startB) * fraction + + return UIColor(red: resultR, green: resultG, blue: resultB, alpha: resultA) + } +} + diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIFont+AppBaseKit.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIFont+AppBaseKit.swift new file mode 100644 index 0000000..12381cd --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIFont+AppBaseKit.swift @@ -0,0 +1,25 @@ +// +// UIFont+AppBaseKit.swift +// Pods +// +// Created by zixun on 2016/10/29. +// +// + +import Foundation +import UIKit + +extension UIFont { + + class func printAllNames() { + let familyNames = UIFont.familyNames + + for familyName in familyNames { + print("-------\(familyName)-------") + let fontNames = UIFont.fontNames(forFamilyName: familyName) + for fontName in fontNames { + print(fontName) + } + } + } +} diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIImage+AppBaseKit.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIImage+AppBaseKit.swift new file mode 100644 index 0000000..322574c --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIImage+AppBaseKit.swift @@ -0,0 +1,122 @@ +// +// UIImage+AppBaseKit.swift +// Pods +// +// Created by zixun on 16/9/25. +// +// + +import Foundation +import UIKit + +// MARK: - Resize +extension UIImage { + + public func resizeImage(newSize:CGSize) -> UIImage? { + let size = self.size + + let widthRatio = newSize.width / self.size.width + let heightRatio = newSize.height / self.size.height + + // Figure out what our orientation is, and use that to form the rectangle + var newSize: CGSize + if(widthRatio > heightRatio) { + newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) + } else { + newSize = CGSize(width:size.width * widthRatio, height:size.height * widthRatio) + } + + // This is the rect that we've calculated out and this is what is actually used below + let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) + + // Actually do the resizing to the rect using the ImageContext stuff + UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) + self.draw(in: rect) + let newImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return newImage + } + + public func realSize() -> CGSize { + return CGSize(width:self.size.width * self.scale, height:self.size.height * self.scale) + } + + public func isSquaresSize() -> Bool { + let size = self.realSize() + return size.width == size.height + } +} + + +// MARK: - draw image +public extension UIImage { + + /// 用CGContext绘制一张图形到原来的图片中 + /// + /// - parameter block: 绘制block + /// + /// - returns: 生成的新图 + public func drawGraphics(with block:(CGContext,CGRect) -> Void) -> UIImage? { + + let size = self.size + let rect = CGRect(x:0, y:0, width:size.width, height:size.height) + UIGraphicsBeginImageContextWithOptions(size, false, 0.0) + self.draw(at: CGPoint.zero) + let context: CGContext = UIGraphicsGetCurrentContext()! + block(context,rect) + + let image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; + } + + /** + 用CGContextRef代码生成一个UIImage图片对象 + + - parameter size: 图片大小 + - parameter drawingBlock: 绘画block + + - returns: 生成的图片 + */ + public class func image(size: CGSize, drawingBlock:(CGContext,CGRect) -> Void) -> UIImage? { + + guard size.equalTo(CGSize()) == false else { + return nil + } + + let rect = CGRect(x:0, y:0, width:size.width, height:size.height) + UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0) + let context: CGContext = UIGraphicsGetCurrentContext()! + context.clear(rect) + + drawingBlock(context,rect) + + let image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return image; + } + + /** + 生成一个单一颜色的UIImage图片对象 + + - parameter color: 颜色 + - parameter size: 大小 + + - returns: 生成的图片对象 + */ + public class func image(color:UIColor, size:CGSize) ->UIImage? { + + guard size.equalTo(CGSize()) == false else { + return nil + } + + return UIImage.image(size: size) { (context:CGContext, rect:CGRect) in + context.setFillColor(color.cgColor) + context.fill(rect) + } + } +} + diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIView+AppBaseKit.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIView+AppBaseKit.swift new file mode 100644 index 0000000..9501751 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Extension/UIKit/UIView+AppBaseKit.swift @@ -0,0 +1,33 @@ +// +// UIView+AppBaseKit.swift +// Pods +// +// Created by zixun on 16/9/25. +// +// + +import Foundation +import UIKit + +extension UIView { + + /** + if view or subviews is first responder, find and resign it + + - returns: retun true if find and resign first responder, otherwise return false + */ + public func findAndResignFirstResponder() -> Bool { + if self.isFirstResponder { + self.resignFirstResponder() + return true + } + + for subview in self.subviews { + if subview.findAndResignFirstResponder() { + return true + } + } + + return false + } +} diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Util/AppNavigationController.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Util/AppNavigationController.swift new file mode 100644 index 0000000..0472ddc --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Util/AppNavigationController.swift @@ -0,0 +1,62 @@ +// +// AppNavigationController.swift +// Pods +// +// Created by zixun on 2016/10/24. +// +// + +import UIKit + +public class AppNavigationController: UINavigationController { + + public var enable = true + + override public func viewDidLoad() { + super.viewDidLoad() + + // 获取系统自带滑动手势的target对象 + let target = self.interactivePopGestureRecognizer!.delegate; + + // 创建全屏滑动手势,调用系统自带滑动手势的target的action方法 + let pan = UIPanGestureRecognizer(target: target, action: Selector("handleNavigationTransition:")) + + // 设置手势代理,拦截手势触发 + pan.delegate = self; + + // 给导航控制器的view添加全屏滑动手势 + self.view.addGestureRecognizer(pan); + + // 禁止使用系统自带的滑动手势 + self.interactivePopGestureRecognizer!.isEnabled = false; + } + + override public func pushViewController(_ viewController: UIViewController, animated: Bool) { + + if self.viewControllers.count > 0 { + viewController.hidesBottomBarWhenPushed = true + } + super.pushViewController(viewController, animated: animated) + } +} + +// MARK: UIGestureRecognizerDelegate +extension AppNavigationController: UIGestureRecognizerDelegate { + + public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + let translation: CGPoint = (gestureRecognizer as! UIPanGestureRecognizer).translation(in: self.view.superview) + + guard self.enable == true else { + return false + } + + if (translation.x < 0) { + return false //往右滑返回,往左滑不做操作 + } + + if (self.viewControllers.count <= 1) { + return false + } + return true + } +} diff --git a/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Util/AppPaths.swift b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Util/AppPaths.swift new file mode 100644 index 0000000..5b420be --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/AppBaseKit/Classes/Util/AppPaths.swift @@ -0,0 +1,86 @@ +// +// AppPaths.swift +// Pods +// +// Created by zixun on 16/9/24. +// +// + +import Foundation + +//AppPaths用来简化对app目录的检索, +//改写自Facebook大神jverkoey的Objective-C项目Nimbus 中的NIPaths +//(https://github.com/jverkoey/nimbus/blob/master/src/core/src/NIPaths.m) +//因语法关系有略微不同 并且增加了ApplicationSupportDirectory的检索 + +/** + * Create a path with the given bundle and the relative path appended. + * + * @param bundle The bundle to append relativePath to. If nil, [NSBundle mainBundle] + * will be used. + * @param relativePath The relative path to append to the bundle's path. + * + * @returns The bundle path concatenated with the given relative path. + */ +public func AppPathForBundleResource(bundle: Bundle?, relativePath: String) -> String { + let resourcePath = (bundle == nil ? Bundle.main : bundle)!.resourcePath! + + return (resourcePath as NSString).appendingPathComponent(relativePath) +} + +/** + * Create a path with the documents directory and the relative path appended. + * + * @returns The documents path concatenated with the given relative path. + */ +public func AppPathForDocumentsResource(relativePath: String) -> String { + return documentsPath.appendingPathComponent(relativePath) +} + +/** + * Create a path with the Library directory and the relative path appended. + * + * @returns The Library path concatenated with the given relative path. + */ +public func AppPathForLibraryResource(relativePath: String) -> String { + return libraryPath.appendingPathComponent(relativePath) +} + +/** + * Create a path with the caches directory and the relative path appended. + * + * @returns The caches path concatenated with the given relative path. + */ +public func AppPathForCachesResource(relativePath: String) -> String { + return cachesPath.appendingPathComponent(relativePath) +} + + +/** + * Create a path with the ApplicationSupport directory and the relative path appended. + * + * @returns The caches path concatenated with the given relative path. + */ +public func AppPathForApplicationSupportResource(relativePath: String) -> String { + return applicationSupportPath.appendingPathComponent(relativePath) +} + +/// 将document目录作为常量保存起来,提高访问性能 +private let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, + .userDomainMask, + true).first! as NSString + +/// 将library目录作为常量保存起来,提高访问性能 +private let libraryPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, + .userDomainMask, + true).first! as NSString + +/// 将caches目录作为常量保存起来,提高访问性能 +private let cachesPath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, + .userDomainMask, + true).first! as NSString + +/// 将applicationSupport目录作为常量保存起来,提高访问性能 +private let applicationSupportPath = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, + .userDomainMask, + true).first! as NSString diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/project.pbxproj b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/project.pbxproj new file mode 100644 index 0000000..61038d4 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/project.pbxproj @@ -0,0 +1,815 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 5C38CC72AF78AE043A8D3563 /* Pods_AppBaseKit_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ADF42F6221573B041F34DBBA /* Pods_AppBaseKit_Example.framework */; }; + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 8E374C58DEE1F5954DD39592 /* Pods_AppBaseKit_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25E6BC4B5222A1C69B7A4F2A /* Pods_AppBaseKit_Tests.framework */; }; + 9E24F9891E7FAED9001AD0D7 /* AppBaseKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24F9871E7FAED9001AD0D7 /* AppBaseKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24F9A41E7FAEF1001AD0D7 /* NSFileManager+AppBaseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9941E7FAEF1001AD0D7 /* NSFileManager+AppBaseKit.swift */; }; + 9E24F9A51E7FAEF1001AD0D7 /* NSObject+Closure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9951E7FAEF1001AD0D7 /* NSObject+Closure.swift */; }; + 9E24F9A61E7FAEF1001AD0D7 /* String+AppBaseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9961E7FAEF1001AD0D7 /* String+AppBaseKit.swift */; }; + 9E24F9A71E7FAEF1001AD0D7 /* UIAlertController+AppBaseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9981E7FAEF1001AD0D7 /* UIAlertController+AppBaseKit.swift */; }; + 9E24F9A81E7FAEF1001AD0D7 /* UIAlertView+AppBaseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9991E7FAEF1001AD0D7 /* UIAlertView+AppBaseKit.swift */; }; + 9E24F9A91E7FAEF1001AD0D7 /* UIApplication+AppBaseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F99A1E7FAEF1001AD0D7 /* UIApplication+AppBaseKit.swift */; }; + 9E24F9AA1E7FAEF1001AD0D7 /* UIColor+AppBaseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F99B1E7FAEF1001AD0D7 /* UIColor+AppBaseKit.swift */; }; + 9E24F9AB1E7FAEF1001AD0D7 /* UIFont+AppBaseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F99C1E7FAEF1001AD0D7 /* UIFont+AppBaseKit.swift */; }; + 9E24F9AC1E7FAEF1001AD0D7 /* UIImage+AppBaseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F99D1E7FAEF1001AD0D7 /* UIImage+AppBaseKit.swift */; }; + 9E24F9AD1E7FAEF1001AD0D7 /* UIView+AppBaseKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F99E1E7FAEF1001AD0D7 /* UIView+AppBaseKit.swift */; }; + 9E24F9AE1E7FAEF1001AD0D7 /* AppNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9A01E7FAEF1001AD0D7 /* AppNavigationController.swift */; }; + 9E24F9AF1E7FAEF1001AD0D7 /* AppPaths.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9A11E7FAEF1001AD0D7 /* AppPaths.swift */; }; + 9ECCC76E1DBD299F005B4705 /* ViewController2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ECCC76D1DBD299F005B4705 /* ViewController2.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = AppBaseKit; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0E5969C692F16822DD8DEBE5 /* Pods-AppBaseKit_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppBaseKit_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-AppBaseKit_Example/Pods-AppBaseKit_Example.release.xcconfig"; sourceTree = ""; }; + 11B50876088F077D4478E390 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + 25E6BC4B5222A1C69B7A4F2A /* Pods_AppBaseKit_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AppBaseKit_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 26506621862CE38119D8EE97 /* Pods-AppBaseKit_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppBaseKit_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AppBaseKit_Tests/Pods-AppBaseKit_Tests.debug.xcconfig"; sourceTree = ""; }; + 3E4D767F320243702251E875 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 4DD76BA36EC95BF996D1DECB /* AppBaseKit.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = AppBaseKit.podspec; path = ../AppBaseKit.podspec; sourceTree = ""; }; + 607FACD01AFB9204008FA782 /* AppBaseKit_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppBaseKit_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 607FACE51AFB9204008FA782 /* AppBaseKit_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AppBaseKit_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + 85786E234EA99C27803F8D59 /* Pods-AppBaseKit_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppBaseKit_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AppBaseKit_Example/Pods-AppBaseKit_Example.debug.xcconfig"; sourceTree = ""; }; + 9E24F9851E7FAED9001AD0D7 /* AppBaseKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AppBaseKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24F9871E7FAED9001AD0D7 /* AppBaseKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppBaseKit.h; sourceTree = ""; }; + 9E24F9881E7FAED9001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24F9941E7FAEF1001AD0D7 /* NSFileManager+AppBaseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFileManager+AppBaseKit.swift"; sourceTree = ""; }; + 9E24F9951E7FAEF1001AD0D7 /* NSObject+Closure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+Closure.swift"; sourceTree = ""; }; + 9E24F9961E7FAEF1001AD0D7 /* String+AppBaseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+AppBaseKit.swift"; sourceTree = ""; }; + 9E24F9981E7FAEF1001AD0D7 /* UIAlertController+AppBaseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertController+AppBaseKit.swift"; sourceTree = ""; }; + 9E24F9991E7FAEF1001AD0D7 /* UIAlertView+AppBaseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertView+AppBaseKit.swift"; sourceTree = ""; }; + 9E24F99A1E7FAEF1001AD0D7 /* UIApplication+AppBaseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+AppBaseKit.swift"; sourceTree = ""; }; + 9E24F99B1E7FAEF1001AD0D7 /* UIColor+AppBaseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+AppBaseKit.swift"; sourceTree = ""; }; + 9E24F99C1E7FAEF1001AD0D7 /* UIFont+AppBaseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIFont+AppBaseKit.swift"; sourceTree = ""; }; + 9E24F99D1E7FAEF1001AD0D7 /* UIImage+AppBaseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+AppBaseKit.swift"; sourceTree = ""; }; + 9E24F99E1E7FAEF1001AD0D7 /* UIView+AppBaseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+AppBaseKit.swift"; sourceTree = ""; }; + 9E24F9A01E7FAEF1001AD0D7 /* AppNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppNavigationController.swift; sourceTree = ""; }; + 9E24F9A11E7FAEF1001AD0D7 /* AppPaths.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppPaths.swift; sourceTree = ""; }; + 9ECCC76D1DBD299F005B4705 /* ViewController2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController2.swift; sourceTree = ""; }; + ADF42F6221573B041F34DBBA /* Pods_AppBaseKit_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AppBaseKit_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BA2F8DCFF2CFF3328DF50735 /* Pods-AppBaseKit_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppBaseKit_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AppBaseKit_Tests/Pods-AppBaseKit_Tests.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5C38CC72AF78AE043A8D3563 /* Pods_AppBaseKit_Example.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8E374C58DEE1F5954DD39592 /* Pods_AppBaseKit_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9811E7FAED9001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for AppBaseKit */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24F9861E7FAED9001AD0D7 /* AppBaseKit */, + 607FACD11AFB9204008FA782 /* Products */, + AC40615017F79EF175EBCF69 /* Pods */, + 745282724A18705E4388B062 /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* AppBaseKit_Example.app */, + 607FACE51AFB9204008FA782 /* AppBaseKit_Tests.xctest */, + 9E24F9851E7FAED9001AD0D7 /* AppBaseKit.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for AppBaseKit */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 9ECCC76D1DBD299F005B4705 /* ViewController2.swift */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for AppBaseKit"; + path = AppBaseKit; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* Tests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + 4DD76BA36EC95BF996D1DECB /* AppBaseKit.podspec */, + 3E4D767F320243702251E875 /* README.md */, + 11B50876088F077D4478E390 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 745282724A18705E4388B062 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ADF42F6221573B041F34DBBA /* Pods_AppBaseKit_Example.framework */, + 25E6BC4B5222A1C69B7A4F2A /* Pods_AppBaseKit_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9E24F9861E7FAED9001AD0D7 /* AppBaseKit */ = { + isa = PBXGroup; + children = ( + 9E24F98D1E7FAEF1001AD0D7 /* AppBaseKit */, + 9E24F9871E7FAED9001AD0D7 /* AppBaseKit.h */, + 9E24F9881E7FAED9001AD0D7 /* Info.plist */, + ); + path = AppBaseKit; + sourceTree = ""; + }; + 9E24F98D1E7FAEF1001AD0D7 /* AppBaseKit */ = { + isa = PBXGroup; + children = ( + 9E24F9901E7FAEF1001AD0D7 /* Classes */, + ); + name = AppBaseKit; + path = ../../AppBaseKit; + sourceTree = ""; + }; + 9E24F9901E7FAEF1001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24F9921E7FAEF1001AD0D7 /* Extension */, + 9E24F99F1E7FAEF1001AD0D7 /* Util */, + ); + path = Classes; + sourceTree = ""; + }; + 9E24F9921E7FAEF1001AD0D7 /* Extension */ = { + isa = PBXGroup; + children = ( + 9E24F9931E7FAEF1001AD0D7 /* Foundation */, + 9E24F9971E7FAEF1001AD0D7 /* UIKit */, + ); + path = Extension; + sourceTree = ""; + }; + 9E24F9931E7FAEF1001AD0D7 /* Foundation */ = { + isa = PBXGroup; + children = ( + 9E24F9941E7FAEF1001AD0D7 /* NSFileManager+AppBaseKit.swift */, + 9E24F9951E7FAEF1001AD0D7 /* NSObject+Closure.swift */, + 9E24F9961E7FAEF1001AD0D7 /* String+AppBaseKit.swift */, + ); + path = Foundation; + sourceTree = ""; + }; + 9E24F9971E7FAEF1001AD0D7 /* UIKit */ = { + isa = PBXGroup; + children = ( + 9E24F9981E7FAEF1001AD0D7 /* UIAlertController+AppBaseKit.swift */, + 9E24F9991E7FAEF1001AD0D7 /* UIAlertView+AppBaseKit.swift */, + 9E24F99A1E7FAEF1001AD0D7 /* UIApplication+AppBaseKit.swift */, + 9E24F99B1E7FAEF1001AD0D7 /* UIColor+AppBaseKit.swift */, + 9E24F99C1E7FAEF1001AD0D7 /* UIFont+AppBaseKit.swift */, + 9E24F99D1E7FAEF1001AD0D7 /* UIImage+AppBaseKit.swift */, + 9E24F99E1E7FAEF1001AD0D7 /* UIView+AppBaseKit.swift */, + ); + path = UIKit; + sourceTree = ""; + }; + 9E24F99F1E7FAEF1001AD0D7 /* Util */ = { + isa = PBXGroup; + children = ( + 9E24F9A01E7FAEF1001AD0D7 /* AppNavigationController.swift */, + 9E24F9A11E7FAEF1001AD0D7 /* AppPaths.swift */, + ); + path = Util; + sourceTree = ""; + }; + AC40615017F79EF175EBCF69 /* Pods */ = { + isa = PBXGroup; + children = ( + 85786E234EA99C27803F8D59 /* Pods-AppBaseKit_Example.debug.xcconfig */, + 0E5969C692F16822DD8DEBE5 /* Pods-AppBaseKit_Example.release.xcconfig */, + 26506621862CE38119D8EE97 /* Pods-AppBaseKit_Tests.debug.xcconfig */, + BA2F8DCFF2CFF3328DF50735 /* Pods-AppBaseKit_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24F9821E7FAED9001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9891E7FAED9001AD0D7 /* AppBaseKit.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* AppBaseKit_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppBaseKit_Example" */; + buildPhases = ( + 60151BFF5B0BB14ED5BC4101 /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + CA3C5A4CAA457B255D30F709 /* [CP] Embed Pods Frameworks */, + 72C3F126D90FD9D2F1DFD28D /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppBaseKit_Example; + productName = AppBaseKit; + productReference = 607FACD01AFB9204008FA782 /* AppBaseKit_Example.app */; + productType = "com.apple.product-type.application"; + }; + 607FACE41AFB9204008FA782 /* AppBaseKit_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppBaseKit_Tests" */; + buildPhases = ( + 3B5CE0171ACAD89C49B59A3F /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + C08A9096B12B86D6BB4D67A9 /* [CP] Embed Pods Frameworks */, + 509764B3066C32FB57B7E18F /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 607FACE71AFB9204008FA782 /* PBXTargetDependency */, + ); + name = AppBaseKit_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* AppBaseKit_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24F9841E7FAED9001AD0D7 /* AppBaseKit */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24F98C1E7FAED9001AD0D7 /* Build configuration list for PBXNativeTarget "AppBaseKit" */; + buildPhases = ( + 9E24F9801E7FAED9001AD0D7 /* Sources */, + 9E24F9811E7FAED9001AD0D7 /* Frameworks */, + 9E24F9821E7FAED9001AD0D7 /* Headers */, + 9E24F9831E7FAED9001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppBaseKit; + productName = AppBaseKit; + productReference = 9E24F9851E7FAED9001AD0D7 /* AppBaseKit.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0800; + }; + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0800; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24F9841E7FAED9001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AppBaseKit" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* AppBaseKit_Example */, + 607FACE41AFB9204008FA782 /* AppBaseKit_Tests */, + 9E24F9841E7FAED9001AD0D7 /* AppBaseKit */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9831E7FAED9001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B5CE0171ACAD89C49B59A3F /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 509764B3066C32FB57B7E18F /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppBaseKit_Tests/Pods-AppBaseKit_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 60151BFF5B0BB14ED5BC4101 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 72C3F126D90FD9D2F1DFD28D /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppBaseKit_Example/Pods-AppBaseKit_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + C08A9096B12B86D6BB4D67A9 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppBaseKit_Tests/Pods-AppBaseKit_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + CA3C5A4CAA457B255D30F709 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppBaseKit_Example/Pods-AppBaseKit_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + 9ECCC76E1DBD299F005B4705 /* ViewController2.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9801E7FAED9001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9A91E7FAEF1001AD0D7 /* UIApplication+AppBaseKit.swift in Sources */, + 9E24F9A41E7FAEF1001AD0D7 /* NSFileManager+AppBaseKit.swift in Sources */, + 9E24F9A61E7FAEF1001AD0D7 /* String+AppBaseKit.swift in Sources */, + 9E24F9AC1E7FAEF1001AD0D7 /* UIImage+AppBaseKit.swift in Sources */, + 9E24F9A81E7FAEF1001AD0D7 /* UIAlertView+AppBaseKit.swift in Sources */, + 9E24F9A71E7FAEF1001AD0D7 /* UIAlertController+AppBaseKit.swift in Sources */, + 9E24F9AF1E7FAEF1001AD0D7 /* AppPaths.swift in Sources */, + 9E24F9AD1E7FAEF1001AD0D7 /* UIView+AppBaseKit.swift in Sources */, + 9E24F9AE1E7FAEF1001AD0D7 /* AppNavigationController.swift in Sources */, + 9E24F9AA1E7FAEF1001AD0D7 /* UIColor+AppBaseKit.swift in Sources */, + 9E24F9AB1E7FAEF1001AD0D7 /* UIFont+AppBaseKit.swift in Sources */, + 9E24F9A51E7FAEF1001AD0D7 /* NSObject+Closure.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* AppBaseKit_Example */; + targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 85786E234EA99C27803F8D59 /* Pods-AppBaseKit_Example.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = AppBaseKit/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0E5969C692F16822DD8DEBE5 /* Pods-AppBaseKit_Example.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = AppBaseKit/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 26506621862CE38119D8EE97 /* Pods-AppBaseKit_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BA2F8DCFF2CFF3328DF50735 /* Pods-AppBaseKit_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24F98A1E7FAED9001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AppBaseKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AppBaseKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24F98B1E7FAED9001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AppBaseKit/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AppBaseKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AppBaseKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppBaseKit_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppBaseKit_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24F98C1E7FAED9001AD0D7 /* Build configuration list for PBXNativeTarget "AppBaseKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24F98A1E7FAED9001AD0D7 /* Debug */, + 9E24F98B1E7FAED9001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..13f0c80 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/project.xcworkspace/xcshareddata/AppBaseKit.xcscmblueprint b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/project.xcworkspace/xcshareddata/AppBaseKit.xcscmblueprint new file mode 100644 index 0000000..3bf9e9f --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/project.xcworkspace/xcshareddata/AppBaseKit.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "EE27F8B5D43F2D143EFE26F45B368D6A64BE2F86", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "EE27F8B5D43F2D143EFE26F45B368D6A64BE2F86" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "10867CCB-B2FD-4B2F-829D-1C19087C2D7A", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "EE27F8B5D43F2D143EFE26F45B368D6A64BE2F86" : "AppBaseKit\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "AppBaseKit", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/AppBaseKit.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/AppBaseKit.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "EE27F8B5D43F2D143EFE26F45B368D6A64BE2F86" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/xcshareddata/xcschemes/AppBaseKit-Example.xcscheme b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/xcshareddata/xcschemes/AppBaseKit-Example.xcscheme new file mode 100644 index 0000000..3016afe --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/xcshareddata/xcschemes/AppBaseKit-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/xcshareddata/xcschemes/AppBaseKit.xcscheme b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/xcshareddata/xcschemes/AppBaseKit.xcscheme new file mode 100644 index 0000000..733095a --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcodeproj/xcshareddata/xcschemes/AppBaseKit.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..d8966f2 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcworkspace/xcshareddata/AppBaseKit.xcscmblueprint b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcworkspace/xcshareddata/AppBaseKit.xcscmblueprint new file mode 100644 index 0000000..44d1c3e --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit.xcworkspace/xcshareddata/AppBaseKit.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "EE27F8B5D43F2D143EFE26F45B368D6A64BE2F86", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "EE27F8B5D43F2D143EFE26F45B368D6A64BE2F86" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "308CF14E-6D12-495F-869E-D602B0B24D1C", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "EE27F8B5D43F2D143EFE26F45B368D6A64BE2F86" : "AppBaseKit\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "AppBaseKit", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/AppBaseKit.xcworkspace", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/AppBaseKit.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "EE27F8B5D43F2D143EFE26F45B368D6A64BE2F86" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/AppBaseKit.h b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/AppBaseKit.h new file mode 100644 index 0000000..4efeb84 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/AppBaseKit.h @@ -0,0 +1,19 @@ +// +// AppBaseKit.h +// AppBaseKit +// +// Created by zixun on 2017/3/20. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for AppBaseKit. +FOUNDATION_EXPORT double AppBaseKitVersionNumber; + +//! Project version string for AppBaseKit. +FOUNDATION_EXPORT const unsigned char AppBaseKitVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/AppDelegate.swift b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/AppDelegate.swift new file mode 100644 index 0000000..7374192 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/AppDelegate.swift @@ -0,0 +1,57 @@ +// +// AppDelegate.swift +// AppBaseKit +// +// Created by 陈奕龙 on 09/24/2016. +// Copyright (c) 2016 陈奕龙. All rights reserved. +// + +import UIKit +import AppBaseKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + + self.window = UIWindow(frame: UIScreen.main.bounds); + if let window = self.window { + + let rootViewController = AppNavigationController(rootViewController: ViewController()); + + window.rootViewController = rootViewController; + window.makeKeyAndVisible() + + } + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..0477fb1 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/Base.lproj/LaunchScreen.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d3942e9 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/Info.plist b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/ViewController.swift b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/ViewController.swift new file mode 100644 index 0000000..d22e4e0 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/ViewController.swift @@ -0,0 +1,28 @@ +// +// ViewController.swift +// AppBaseKit +// +// Created by 陈奕龙 on 09/24/2016. +// Copyright (c) 2016 陈奕龙. All rights reserved. +// + +import UIKit +import AppBaseKit + + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + self.view.backgroundColor = UIColor.blue + + self.navigationController?.pushViewController(ViewController2(), animated: true) + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + + } +} + diff --git a/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/ViewController2.swift b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/ViewController2.swift new file mode 100644 index 0000000..4237726 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/AppBaseKit/ViewController2.swift @@ -0,0 +1,18 @@ +// +// ViewController2.swift +// AppBaseKit +// +// Created by zixun on 2016/10/24. +// Copyright © 2016年 CocoaPods. All rights reserved. +// + +import Foundation +import UIKit + +class ViewController2: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + self.view.backgroundColor = UIColor.red + } +} diff --git a/Carthage/Checkouts/AppBaseKit/Example/Podfile b/Carthage/Checkouts/AppBaseKit/Example/Podfile new file mode 100644 index 0000000..5a0ee72 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/Podfile @@ -0,0 +1,11 @@ +use_frameworks! + +target 'AppBaseKit_Example' do + pod 'AppBaseKit', :path => '../' + + target 'AppBaseKit_Tests' do + inherit! :search_paths + + + end +end diff --git a/Carthage/Checkouts/AppBaseKit/Example/Podfile.lock b/Carthage/Checkouts/AppBaseKit/Example/Podfile.lock new file mode 100644 index 0000000..81e4a34 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - AppBaseKit (0.1.0) + +DEPENDENCIES: + - AppBaseKit (from `../`) + +EXTERNAL SOURCES: + AppBaseKit: + :path: "../" + +SPEC CHECKSUMS: + AppBaseKit: 1d1544fc5cd112e513c8ce5931d2500acb470e81 + +PODFILE CHECKSUM: 2a83357147041de47a0ca39bfaddcfa7a454da81 + +COCOAPODS: 1.2.0 diff --git a/Carthage/Checkouts/AppBaseKit/Example/Tests/Info.plist b/Carthage/Checkouts/AppBaseKit/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/AppBaseKit/Example/Tests/Tests.swift b/Carthage/Checkouts/AppBaseKit/Example/Tests/Tests.swift new file mode 100644 index 0000000..bc46d0a --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/Example/Tests/Tests.swift @@ -0,0 +1,29 @@ +import UIKit +import XCTest +import AppBaseKit + +class Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + XCTAssert(true, "Pass") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure() { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Carthage/Checkouts/AppBaseKit/LICENSE b/Carthage/Checkouts/AppBaseKit/LICENSE new file mode 100644 index 0000000..be8a1fd --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2017 Yilong Chen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Carthage/Checkouts/AppBaseKit/README.md b/Carthage/Checkouts/AppBaseKit/README.md new file mode 100644 index 0000000..7b7daab --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/README.md @@ -0,0 +1,36 @@ +# AppBaseKit + + + +[![Swift 3.0+](https://img.shields.io/badge/Swift-3.0%2B-orange.svg)](https://github.com/zixun/AppBaseKit) +[![Platform](https://img.shields.io/badge/Platform-iOS-lightgrey.svg)](https://github.com/zixun/AppBaseKit) +[![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) + +## Context +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly disply Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Example + +To run the example project, clone the repo, and run `pod install` from the Example directory first. + + +## Installation + +AppBaseKit is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "AppBaseKit" +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +## License + +AppBaseKit is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/AppBaseKit/_Pods.xcodeproj b/Carthage/Checkouts/AppBaseKit/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/AppBaseKit/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/AppSwizzle/.gitignore b/Carthage/Checkouts/AppSwizzle/.gitignore new file mode 100644 index 0000000..1de2633 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/AppSwizzle/AppSwizzle.podspec b/Carthage/Checkouts/AppSwizzle/AppSwizzle.podspec new file mode 100644 index 0000000..3c9cd6e --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/AppSwizzle.podspec @@ -0,0 +1,33 @@ +# +# Be sure to run `pod lib lint AppSwizzle.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'AppSwizzle' + s.version = '1.1.1' + s.summary = 'lightweight and flexible method swizzling wrapped by swift.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +Lightweight and flexible method swizzling wrapped by swift. enjoy it! + DESC + + s.homepage = 'https://github.com/zixun/AppSwizzle' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { '陈奕龙' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/AppSwizzle.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'AppSwizzle/Classes/**/*' +end diff --git a/Carthage/Checkouts/AppSwizzle/AppSwizzle/Assets/.gitkeep b/Carthage/Checkouts/AppSwizzle/AppSwizzle/Assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/.gitkeep b/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/AppSwizzle.swift b/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/AppSwizzle.swift new file mode 100644 index 0000000..5312665 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/AppSwizzle.swift @@ -0,0 +1,99 @@ +// +// AppSwizzle.swift +// Pods +// +// Created by zixun on 2016/11/27. +// +// + +import Foundation + +import ObjectiveC + +public enum SwizzleResult { + case Succeed + case OriginMethodNotFound + case AlternateMethodNotFound +} + +public extension NSObject { + + public class func swizzleInstanceMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: self.classForCoder(), + isClassMethod: false) + } + + public class func swizzleClassMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: self.classForCoder(), + isClassMethod: true) + } + + + public class func swizzleInstanceMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector, + inAlterClass alterClass: AnyClass) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: alterClass, + isClassMethod: false) + } + + public class func swizzleClassMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector, + inAlterClass alterClass: AnyClass) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: alterClass, + isClassMethod: true) + } + + + private class func swizzleMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector!, + inAlterClass alterClass: AnyClass!, + isClassMethod:Bool) -> SwizzleResult { + + var alterClass = alterClass + var origClass: AnyClass = self.classForCoder() + if isClassMethod { + alterClass = object_getClass(alterClass) + origClass = object_getClass(self.classForCoder()) + } + + return SwizzleMethod(origClass: origClass, origSelector: origSelector, toAlterSelector: alterSelector, inAlterClass: alterClass) + } +} + + +private func SwizzleMethod(origClass:AnyClass!,origSelector: Selector,toAlterSelector alterSelector: Selector!,inAlterClass alterClass: AnyClass!) -> SwizzleResult{ + + guard let origMethod: Method = class_getInstanceMethod(origClass, origSelector) else { + return SwizzleResult.OriginMethodNotFound + } + + guard let altMethod: Method = class_getInstanceMethod(alterClass, alterSelector) else { + return SwizzleResult.AlternateMethodNotFound + } + + + + let didadd = class_addMethod(origClass, + origSelector,method_getImplementation(origMethod), + method_getTypeEncoding(origMethod)) + + + let didadd2 = class_addMethod(alterClass, + alterSelector,method_getImplementation(altMethod), + method_getTypeEncoding(altMethod)) + + method_exchangeImplementations(origMethod, altMethod) + + return SwizzleResult.Succeed + +} diff --git a/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.pbxproj b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.pbxproj new file mode 100644 index 0000000..976270e --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.pbxproj @@ -0,0 +1,527 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 607FACEC1AFB9204008FA782 /* AppSwizzleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* AppSwizzleTests.swift */; }; + 9E24F9D91E7FB91A001AD0D7 /* AppSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24F9D71E7FB91A001AD0D7 /* AppSwizzle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24F9E01E7FB92D001AD0D7 /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = 9E24F9DE1E7FB92D001AD0D7 /* .gitkeep */; }; + 9E24F9E11E7FB92D001AD0D7 /* AppSwizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9DF1E7FB92D001AD0D7 /* AppSwizzle.swift */; }; + 9EFFB71B24C66DC6A7F031F7 /* Pods_AppSwizzle_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 491CD07646A3DE1A3E69F9D1 /* Pods_AppSwizzle_Tests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2E3BA46813095DB970DC7076 /* Pods-AppSwizzle_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppSwizzle_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests.release.xcconfig"; sourceTree = ""; }; + 491CD07646A3DE1A3E69F9D1 /* Pods_AppSwizzle_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AppSwizzle_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACE51AFB9204008FA782 /* AppSwizzle_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AppSwizzle_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* AppSwizzleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSwizzleTests.swift; sourceTree = ""; }; + 89AFF071BC9E704AA1C37D55 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 9E24F9D51E7FB91A001AD0D7 /* AppSwizzle.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AppSwizzle.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24F9D71E7FB91A001AD0D7 /* AppSwizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppSwizzle.h; sourceTree = ""; }; + 9E24F9D81E7FB91A001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24F9DE1E7FB92D001AD0D7 /* .gitkeep */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + 9E24F9DF1E7FB92D001AD0D7 /* AppSwizzle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppSwizzle.swift; sourceTree = ""; }; + E26F9D2C0E0879A1F36DBA49 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + E2A536F5AEFAB64066837735 /* AppSwizzle.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = AppSwizzle.podspec; path = ../AppSwizzle.podspec; sourceTree = ""; }; + EF9F0C8A4C454C95207FD5A2 /* Pods-AppSwizzle_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppSwizzle_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EFFB71B24C66DC6A7F031F7 /* Pods_AppSwizzle_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9D11E7FB91A001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 148CFF5A86E94370A2FFA6EB /* Frameworks */ = { + isa = PBXGroup; + children = ( + 491CD07646A3DE1A3E69F9D1 /* Pods_AppSwizzle_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24F9D61E7FB91A001AD0D7 /* AppSwizzle */, + 607FACD11AFB9204008FA782 /* Products */, + 95CAC9C1BE74BBFAF93AD32F /* Pods */, + 148CFF5A86E94370A2FFA6EB /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACE51AFB9204008FA782 /* AppSwizzle_Tests.xctest */, + 9E24F9D51E7FB91A001AD0D7 /* AppSwizzle.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* AppSwizzleTests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + E2A536F5AEFAB64066837735 /* AppSwizzle.podspec */, + 89AFF071BC9E704AA1C37D55 /* README.md */, + E26F9D2C0E0879A1F36DBA49 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 95CAC9C1BE74BBFAF93AD32F /* Pods */ = { + isa = PBXGroup; + children = ( + EF9F0C8A4C454C95207FD5A2 /* Pods-AppSwizzle_Tests.debug.xcconfig */, + 2E3BA46813095DB970DC7076 /* Pods-AppSwizzle_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9E24F9D61E7FB91A001AD0D7 /* AppSwizzle */ = { + isa = PBXGroup; + children = ( + 9E24F9DD1E7FB92D001AD0D7 /* Classes */, + 9E24F9D71E7FB91A001AD0D7 /* AppSwizzle.h */, + 9E24F9D81E7FB91A001AD0D7 /* Info.plist */, + ); + path = AppSwizzle; + sourceTree = ""; + }; + 9E24F9DD1E7FB92D001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24F9DE1E7FB92D001AD0D7 /* .gitkeep */, + 9E24F9DF1E7FB92D001AD0D7 /* AppSwizzle.swift */, + ); + name = Classes; + path = ../../AppSwizzle/Classes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24F9D21E7FB91A001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9D91E7FB91A001AD0D7 /* AppSwizzle.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACE41AFB9204008FA782 /* AppSwizzle_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppSwizzle_Tests" */; + buildPhases = ( + 7A1970CC11A178F2524BAA27 /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + C1AA5E9370E2274451F9FA64 /* [CP] Embed Pods Frameworks */, + F92510766834405DBE333382 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppSwizzle_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* AppSwizzle_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24F9D41E7FB91A001AD0D7 /* AppSwizzle */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24F9DC1E7FB91A001AD0D7 /* Build configuration list for PBXNativeTarget "AppSwizzle" */; + buildPhases = ( + 9E24F9D01E7FB91A001AD0D7 /* Sources */, + 9E24F9D11E7FB91A001AD0D7 /* Frameworks */, + 9E24F9D21E7FB91A001AD0D7 /* Headers */, + 9E24F9D31E7FB91A001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppSwizzle; + productName = AppSwizzle; + productReference = 9E24F9D51E7FB91A001AD0D7 /* AppSwizzle.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0800; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24F9D41E7FB91A001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AppSwizzle" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACE41AFB9204008FA782 /* AppSwizzle_Tests */, + 9E24F9D41E7FB91A001AD0D7 /* AppSwizzle */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9D31E7FB91A001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9E01E7FB92D001AD0D7 /* .gitkeep in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 7A1970CC11A178F2524BAA27 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + C1AA5E9370E2274451F9FA64 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F92510766834405DBE333382 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* AppSwizzleTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9D01E7FB91A001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9E11E7FB92D001AD0D7 /* AppSwizzle.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EF9F0C8A4C454C95207FD5A2 /* Pods-AppSwizzle_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2E3BA46813095DB970DC7076 /* Pods-AppSwizzle_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24F9DA1E7FB91A001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AppSwizzle/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AppSwizzle; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24F9DB1E7FB91A001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AppSwizzle/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AppSwizzle; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AppSwizzle" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppSwizzle_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24F9DC1E7FB91A001AD0D7 /* Build configuration list for PBXNativeTarget "AppSwizzle" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24F9DA1E7FB91A001AD0D7 /* Debug */, + 9E24F9DB1E7FB91A001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..79e358c --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/xcshareddata/AppSwizzle.xcscmblueprint b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/xcshareddata/AppSwizzle.xcscmblueprint new file mode 100644 index 0000000..e32fd4c --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/xcshareddata/AppSwizzle.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "0CB12C37-D96F-4E37-99A6-EA1B9BB695B0", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0" : "AppSwizzle\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "AppSwizzle", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/AppSwizzle.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/AppSwizzle.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle-Example.xcscheme b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle-Example.xcscheme new file mode 100644 index 0000000..aae5e32 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle.xcscheme b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle.xcscheme new file mode 100644 index 0000000..233c1b3 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..bbcb77a --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/AppSwizzle.h b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/AppSwizzle.h new file mode 100644 index 0000000..12be6cf --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/AppSwizzle.h @@ -0,0 +1,19 @@ +// +// AppSwizzle.h +// AppSwizzle +// +// Created by zixun on 2017/3/20. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for AppSwizzle. +FOUNDATION_EXPORT double AppSwizzleVersionNumber; + +//! Project version string for AppSwizzle. +FOUNDATION_EXPORT const unsigned char AppSwizzleVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/Info.plist b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/AppSwizzle/Example/Podfile b/Carthage/Checkouts/AppSwizzle/Example/Podfile new file mode 100644 index 0000000..ce647a9 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/Podfile @@ -0,0 +1,6 @@ +use_frameworks! +target 'AppSwizzle_Tests' do + pod 'AppSwizzle', :path => '../' + + +end diff --git a/Carthage/Checkouts/AppSwizzle/Example/Podfile.lock b/Carthage/Checkouts/AppSwizzle/Example/Podfile.lock new file mode 100644 index 0000000..709afd2 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - AppSwizzle (0.1.0) + +DEPENDENCIES: + - AppSwizzle (from `../`) + +EXTERNAL SOURCES: + AppSwizzle: + :path: "../" + +SPEC CHECKSUMS: + AppSwizzle: eddd38c6429de033e115f66862622723274926a0 + +PODFILE CHECKSUM: 939ed1355ec6a0adef5ae3f3b1e627821b2fc52a + +COCOAPODS: 1.1.1 diff --git a/Carthage/Checkouts/AppSwizzle/Example/Tests/AppSwizzleTests.swift b/Carthage/Checkouts/AppSwizzle/Example/Tests/AppSwizzleTests.swift new file mode 100644 index 0000000..d5aabc7 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/Tests/AppSwizzleTests.swift @@ -0,0 +1,96 @@ +import UIKit +import XCTest +import AppSwizzle + +class AppSwizzleTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testSwizzleInstanceMethod() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethod) + let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleInstanceMethod) + AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) + + self.origSelector_testSwizzleInstanceMethod() + } + + func testSwizzleClassMethod() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethod) + let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleClassMethod) + AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter) + + AppSwizzleTests.origSelector_testSwizzleClassMethod() + } + + func testSwizzleInstanceMethodToAlterClass() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethodToAlterClass) + let alter = #selector(OtherClass.alterSelector_testSwizzleInstanceMethodToAlterClass) + AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) + self.origSelector_testSwizzleInstanceMethodToAlterClass() + } + + func testSwizzleClassMethodToAlterClass() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethodToAlterClass) + let alter = #selector(OtherClass.alterSelector_testSwizzleClassMethodToAlterClass) + + AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) + + AppSwizzleTests.origSelector_testSwizzleClassMethodToAlterClass() + } + +} + +//MARK: testSwizzleInstanceMethod extension +extension AppSwizzleTests { + + func origSelector_testSwizzleInstanceMethod() { + XCTFail("Failed") + } + + func alterSelector_testSwizzleInstanceMethod() { + XCTAssert(true, "Pass") + } +} + +//MARK: testSwizzleClassMethod extension +extension AppSwizzleTests { + + class func origSelector_testSwizzleClassMethod() { + XCTFail("Failed") + } + + class func alterSelector_testSwizzleClassMethod() { + XCTAssert(true, "Pass") + } +} + +//MARK: testSwizzleInstanceMethodToAlterClass extension +extension AppSwizzleTests { + func origSelector_testSwizzleInstanceMethodToAlterClass() { + XCTFail("Failed") + } +} + +extension AppSwizzleTests { + class func origSelector_testSwizzleClassMethodToAlterClass() { + XCTFail("Failed") + } +} + + +class OtherClass: NSObject { + + func alterSelector_testSwizzleInstanceMethodToAlterClass() { + XCTAssert(true, "Pass") + } + + class func alterSelector_testSwizzleClassMethodToAlterClass() { + XCTAssert(true, "Pass") + } +} diff --git a/Carthage/Checkouts/AppSwizzle/Example/Tests/Info.plist b/Carthage/Checkouts/AppSwizzle/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/AppSwizzle/LICENSE b/Carthage/Checkouts/AppSwizzle/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/AppSwizzle/README.md b/Carthage/Checkouts/AppSwizzle/README.md new file mode 100644 index 0000000..9933d6d --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/README.md @@ -0,0 +1,72 @@ +# AppSwizzle + +[![Swift 3.0+](https://img.shields.io/badge/Swift-3.0%2B-orange.svg)](https://github.com/zixun/AppBaseKit) +[![Platform](https://img.shields.io/badge/Platform-iOS-lightgrey.svg)](https://github.com/zixun/AppBaseKit) +[![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) + +## Context +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly disply Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Example + +To run the example project, clone the repo, and run `pod install` from the Example directory first. + +## Requirements + +## Installation + +AppSwizzle is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "AppSwizzle" +``` +## Usage + +### Swizzle Instance Method + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethod) +let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleInstanceMethod) +AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) +``` + +### Swizzle Class Method + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethod) +let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleClassMethod) +AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter) +``` + +### Swizzle Instance Method To Alter Class + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethodToAlterClass) +let alter = #selector(OtherClass.alterSelector_testSwizzleInstanceMethodToAlterClass) +AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) +``` + +### Swizzle Class Method To Alter Class + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethodToAlterClass) +let alter = #selector(OtherClass.alterSelector_testSwizzleClassMethodToAlterClass) +AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + +## License + +AppSwizzle is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/AppSwizzle/_Pods.xcodeproj b/Carthage/Checkouts/AppSwizzle/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/AppSwizzle/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/AssistiveButton/.gitignore b/Carthage/Checkouts/AssistiveButton/.gitignore new file mode 100644 index 0000000..2c22487 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/AssistiveButton/AssistiveButton.podspec b/Carthage/Checkouts/AssistiveButton/AssistiveButton.podspec new file mode 100644 index 0000000..f3f7b1e --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/AssistiveButton.podspec @@ -0,0 +1,33 @@ +# +# Be sure to run `pod lib lint AssistiveButton.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'AssistiveButton' + s.version = '1.1.0' + s.summary = 'Simple Assistive Button.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +Simple Assistive Button imitate the iOS system AssistiveTouch. + DESC + + s.homepage = 'https://github.com/zixun/AssistiveButton' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'zixun' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/AssistiveButton.git', :tag => s.version.to_s } + # s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'AssistiveButton/Classes/**/*' +end diff --git a/Carthage/Checkouts/AssistiveButton/AssistiveButton/Classes/AssistiveButton.swift b/Carthage/Checkouts/AssistiveButton/AssistiveButton/Classes/AssistiveButton.swift new file mode 100644 index 0000000..857c6e2 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/AssistiveButton/Classes/AssistiveButton.swift @@ -0,0 +1,141 @@ +// +// AssistiveButton.swift +// Pods +// +// Created by zixun on 16/12/25. +// +// + +import Foundation + +//MARK: AssistiveButton +open class AssistiveButton: UIButton { + + //MARK: Public Var + open var moveEnable = true + + open var didTap: (()->())? + + //MARK: Init + public init(frame: CGRect,normalImage:UIImage,highlightedImage:UIImage? = nil) { + super.init(frame: frame) + + self.setBackgroundImage(normalImage, for: .normal) + self.setBackgroundImage(highlightedImage, for: .highlighted) + self.adjustsImageWhenHighlighted = true + + self.addTarget(self, action: #selector(AssistiveButton.tap), for: .touchUpInside) + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //MARK: Action + @objc fileprivate func tap() { + if self.didMoved { + return + } + + self.didTap?() + } + + + //MARK: Override + override open func touchesBegan(_ touches: Set, with event: UIEvent?) { + self.didMoved = false + + super.touchesBegan(touches, with: event) + + guard self.moveEnable == true, + let touch = touches.first else { + return + } + + self.beginPoint = touch.location(in: self) + } + + override open func touchesMoved(_ touches: Set, with event: UIEvent?) { + self.didMoved = false + + guard self.moveEnable == true else { + return + } + + guard let superview = self.superview else { + return + } + + guard let touch = touches.first else { + return + } + + let currentPosition = touch.location(in: self) + let offsetX = currentPosition.x - self.beginPoint.x + let offsetY = currentPosition.y - self.beginPoint.y + + if fabsf(Float(offsetX)) > 0 || fabsf(Float(offsetY)) > 0 { + self.didMoved = true + } + + //center position after move + self.center = CGPoint(x: self.center.x + offsetX, y: self.center.y + offsetY) + + //left and right limit coordinates of X axis + if (self.center.x > (superview.frame.size.width-self.frame.size.width / 2)) { + let x = superview.frame.size.width-self.frame.size.width / 2; + self.center = CGPoint(x:x, y:self.center.y + offsetY); + }else if (self.center.x < self.frame.size.width / 2){ + let x = self.frame.size.width / 2; + self.center = CGPoint(x:x, y:self.center.y + offsetY); + } + + //Upper and lower limit coordinates of Y axis + if (self.center.y > (superview.frame.size.height-self.frame.size.height/2)) { + let x = self.center.x; + let y = superview.frame.size.height-self.frame.size.height/2; + self.center = CGPoint(x:x, y:y); + }else if (self.center.y <= self.frame.size.height/2){ + let x = self.center.x; + let y = self.frame.size.height/2; + self.center = CGPoint(x:x, y:y); + } + } + + override open func touchesEnded(_ touches: Set, with event: UIEvent?) { + + guard self.moveEnable == true else { + return + } + + guard let superview = self.superview else { + return + } + + if (self.center.x >= superview.frame.size.width/2) {//Move to the right + //move animation + UIView.beginAnimations("move", context: nil) + UIView.setAnimationDuration(0.2) + UIView.setAnimationDelegate(self) + self.frame = CGRect(x: superview.frame.size.width - self.frame.size.width, y: self.center.y - self.frame.size.height / 2.0, width: self.frame.size.width, height: self.frame.size.height) + UIView.commitAnimations() + }else{//move to the left + UIView.beginAnimations("move", context: nil) + UIView.setAnimationDuration(0.2) + UIView.setAnimationDelegate(self) + self.frame = CGRect(x: 0, y: self.center.y - self.frame.size.height / 2.0, width: self.frame.size.width, height: self.frame.size.height) + UIView.commitAnimations() + } + + super.touchesEnded(touches, with: event) + } + + override open func touchesCancelled(_ touches: Set, with event: UIEvent?) { + super.touchesCancelled(touches, with: event) + } + + //MARK: Private Var + fileprivate var beginPoint = CGPoint.zero + + fileprivate var didMoved = false +} diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/project.pbxproj b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/project.pbxproj new file mode 100644 index 0000000..52f8ba7 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/project.pbxproj @@ -0,0 +1,744 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 9E24FA551E810439001AD0D7 /* AssistiveButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24FA531E810439001AD0D7 /* AssistiveButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FA611E810474001AD0D7 /* AssistiveButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA5E1E810474001AD0D7 /* AssistiveButton.swift */; }; + E6B6F3426CABC1316F4EDC1B /* Pods_AssistiveButton_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD90FC6B6DBB8116538C5370 /* Pods_AssistiveButton_Tests.framework */; }; + EDA80A8013811CF3E507FDB2 /* Pods_AssistiveButton_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 69C54E006496A5345C5A1F4E /* Pods_AssistiveButton_Example.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = AssistiveButton; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 20F5D8E3644B1D50CEBCC72C /* Pods-AssistiveButton_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AssistiveButton_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-AssistiveButton_Example/Pods-AssistiveButton_Example.release.xcconfig"; sourceTree = ""; }; + 2DD76D0735B8681F3D0BD89C /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 363F985B6DED4340864C7280 /* Pods-AssistiveButton_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AssistiveButton_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AssistiveButton_Tests/Pods-AssistiveButton_Tests.debug.xcconfig"; sourceTree = ""; }; + 5E63CEBD7A687B41B68C8342 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + 607FACD01AFB9204008FA782 /* AssistiveButton_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AssistiveButton_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 607FACE51AFB9204008FA782 /* AssistiveButton_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AssistiveButton_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + 69C54E006496A5345C5A1F4E /* Pods_AssistiveButton_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AssistiveButton_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7ED7531AB5F9EF4F82C3502E /* AssistiveButton.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = AssistiveButton.podspec; path = ../AssistiveButton.podspec; sourceTree = ""; }; + 9E24FA511E810439001AD0D7 /* AssistiveButton.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AssistiveButton.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24FA531E810439001AD0D7 /* AssistiveButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AssistiveButton.h; sourceTree = ""; }; + 9E24FA541E810439001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24FA5E1E810474001AD0D7 /* AssistiveButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssistiveButton.swift; sourceTree = ""; }; + C1ED1D870119B36B6380140F /* Pods-AssistiveButton_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AssistiveButton_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AssistiveButton_Tests/Pods-AssistiveButton_Tests.release.xcconfig"; sourceTree = ""; }; + D5C9CB2CDF362BFD815847A7 /* Pods-AssistiveButton_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AssistiveButton_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AssistiveButton_Example/Pods-AssistiveButton_Example.debug.xcconfig"; sourceTree = ""; }; + FD90FC6B6DBB8116538C5370 /* Pods_AssistiveButton_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AssistiveButton_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EDA80A8013811CF3E507FDB2 /* Pods_AssistiveButton_Example.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E6B6F3426CABC1316F4EDC1B /* Pods_AssistiveButton_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA4D1E810439001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for AssistiveButton */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24FA521E810439001AD0D7 /* AssistiveButton */, + 607FACD11AFB9204008FA782 /* Products */, + 884454A53C197584D07F6446 /* Pods */, + C27107BD070EC04303ED8B2C /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* AssistiveButton_Example.app */, + 607FACE51AFB9204008FA782 /* AssistiveButton_Tests.xctest */, + 9E24FA511E810439001AD0D7 /* AssistiveButton.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for AssistiveButton */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 607FACD91AFB9204008FA782 /* Main.storyboard */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for AssistiveButton"; + path = AssistiveButton; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* Tests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + 7ED7531AB5F9EF4F82C3502E /* AssistiveButton.podspec */, + 2DD76D0735B8681F3D0BD89C /* README.md */, + 5E63CEBD7A687B41B68C8342 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 884454A53C197584D07F6446 /* Pods */ = { + isa = PBXGroup; + children = ( + D5C9CB2CDF362BFD815847A7 /* Pods-AssistiveButton_Example.debug.xcconfig */, + 20F5D8E3644B1D50CEBCC72C /* Pods-AssistiveButton_Example.release.xcconfig */, + 363F985B6DED4340864C7280 /* Pods-AssistiveButton_Tests.debug.xcconfig */, + C1ED1D870119B36B6380140F /* Pods-AssistiveButton_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9E24FA521E810439001AD0D7 /* AssistiveButton */ = { + isa = PBXGroup; + children = ( + 9E24FA591E810474001AD0D7 /* AssistiveButton */, + 9E24FA531E810439001AD0D7 /* AssistiveButton.h */, + 9E24FA541E810439001AD0D7 /* Info.plist */, + ); + path = AssistiveButton; + sourceTree = ""; + }; + 9E24FA591E810474001AD0D7 /* AssistiveButton */ = { + isa = PBXGroup; + children = ( + 9E24FA5C1E810474001AD0D7 /* Classes */, + ); + name = AssistiveButton; + path = ../../AssistiveButton; + sourceTree = ""; + }; + 9E24FA5C1E810474001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24FA5E1E810474001AD0D7 /* AssistiveButton.swift */, + ); + path = Classes; + sourceTree = ""; + }; + C27107BD070EC04303ED8B2C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 69C54E006496A5345C5A1F4E /* Pods_AssistiveButton_Example.framework */, + FD90FC6B6DBB8116538C5370 /* Pods_AssistiveButton_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24FA4E1E810439001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA551E810439001AD0D7 /* AssistiveButton.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* AssistiveButton_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AssistiveButton_Example" */; + buildPhases = ( + 7961A9C02B9CF45A2D323F17 /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + BAA6BFFFDCC37D64DF613083 /* [CP] Embed Pods Frameworks */, + 557F07A61C6AD9B7D70D9C48 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AssistiveButton_Example; + productName = AssistiveButton; + productReference = 607FACD01AFB9204008FA782 /* AssistiveButton_Example.app */; + productType = "com.apple.product-type.application"; + }; + 607FACE41AFB9204008FA782 /* AssistiveButton_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AssistiveButton_Tests" */; + buildPhases = ( + D951416B7A3BA5D36A3A682B /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + 722A8556187D3ADEC86C1A86 /* [CP] Embed Pods Frameworks */, + 4A1F7D01A4075E9C0B2D35C3 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 607FACE71AFB9204008FA782 /* PBXTargetDependency */, + ); + name = AssistiveButton_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* AssistiveButton_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24FA501E810439001AD0D7 /* AssistiveButton */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24FA581E810439001AD0D7 /* Build configuration list for PBXNativeTarget "AssistiveButton" */; + buildPhases = ( + 9E24FA4C1E810439001AD0D7 /* Sources */, + 9E24FA4D1E810439001AD0D7 /* Frameworks */, + 9E24FA4E1E810439001AD0D7 /* Headers */, + 9E24FA4F1E810439001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AssistiveButton; + productName = AssistiveButton; + productReference = 9E24FA511E810439001AD0D7 /* AssistiveButton.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + }; + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24FA501E810439001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + LastSwiftMigration = 0820; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AssistiveButton" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* AssistiveButton_Example */, + 607FACE41AFB9204008FA782 /* AssistiveButton_Tests */, + 9E24FA501E810439001AD0D7 /* AssistiveButton */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA4F1E810439001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 4A1F7D01A4075E9C0B2D35C3 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AssistiveButton_Tests/Pods-AssistiveButton_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 557F07A61C6AD9B7D70D9C48 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AssistiveButton_Example/Pods-AssistiveButton_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 722A8556187D3ADEC86C1A86 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AssistiveButton_Tests/Pods-AssistiveButton_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 7961A9C02B9CF45A2D323F17 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + BAA6BFFFDCC37D64DF613083 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AssistiveButton_Example/Pods-AssistiveButton_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + D951416B7A3BA5D36A3A682B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA4C1E810439001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA611E810474001AD0D7 /* AssistiveButton.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* AssistiveButton_Example */; + targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 607FACD91AFB9204008FA782 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 607FACDA1AFB9204008FA782 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D5C9CB2CDF362BFD815847A7 /* Pods-AssistiveButton_Example.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = AssistiveButton/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 20F5D8E3644B1D50CEBCC72C /* Pods-AssistiveButton_Example.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = AssistiveButton/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 363F985B6DED4340864C7280 /* Pods-AssistiveButton_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C1ED1D870119B36B6380140F /* Pods-AssistiveButton_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24FA561E810439001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AssistiveButton/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AssistiveButton; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24FA571E810439001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AssistiveButton/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AssistiveButton; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AssistiveButton" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AssistiveButton_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AssistiveButton_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24FA581E810439001AD0D7 /* Build configuration list for PBXNativeTarget "AssistiveButton" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24FA561E810439001AD0D7 /* Debug */, + 9E24FA571E810439001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..3b06221 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/project.xcworkspace/xcshareddata/AssistiveButton.xcscmblueprint b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/project.xcworkspace/xcshareddata/AssistiveButton.xcscmblueprint new file mode 100644 index 0000000..5296565 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/project.xcworkspace/xcshareddata/AssistiveButton.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "60DE1C3A34E0DCD228D2ECF36F878D99014133B1", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "60DE1C3A34E0DCD228D2ECF36F878D99014133B1" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "73CE7CD0-A104-4A21-BD2F-503F6DFAE2F8", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "60DE1C3A34E0DCD228D2ECF36F878D99014133B1" : "AssistiveButton\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "AssistiveButton", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/AssistiveButton.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/AssistiveButton.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "60DE1C3A34E0DCD228D2ECF36F878D99014133B1" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/xcshareddata/xcschemes/AssistiveButton-Example.xcscheme b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/xcshareddata/xcschemes/AssistiveButton-Example.xcscheme new file mode 100644 index 0000000..e0fc61d --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/xcshareddata/xcschemes/AssistiveButton-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/xcshareddata/xcschemes/AssistiveButton.xcscheme b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/xcshareddata/xcschemes/AssistiveButton.xcscheme new file mode 100644 index 0000000..0365d72 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcodeproj/xcshareddata/xcschemes/AssistiveButton.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..7c1a1e7 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/AppDelegate.swift b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/AppDelegate.swift new file mode 100644 index 0000000..2c0159b --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// AssistiveButton +// +// Created by zixun on 12/25/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/AssistiveButton.h b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/AssistiveButton.h new file mode 100644 index 0000000..bf3e11d --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/AssistiveButton.h @@ -0,0 +1,19 @@ +// +// AssistiveButton.h +// AssistiveButton +// +// Created by zixun on 2017/3/21. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for AssistiveButton. +FOUNDATION_EXPORT double AssistiveButtonVersionNumber; + +//! Project version string for AssistiveButton. +FOUNDATION_EXPORT const unsigned char AssistiveButtonVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..221ad8f --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Base.lproj/LaunchScreen.xib @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Base.lproj/Main.storyboard b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Base.lproj/Main.storyboard new file mode 100644 index 0000000..6c8a2e7 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Base.lproj/Main.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b8236c6 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,48 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/Contents.json b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/Contents.json b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/Contents.json new file mode 100644 index 0000000..0e623a1 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "eye@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "eye@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "eye@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/eye@1x.png b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/eye@1x.png new file mode 100644 index 0000000..3094380 Binary files /dev/null and b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/eye@1x.png differ diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/eye@2x.png b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/eye@2x.png new file mode 100644 index 0000000..ad6c7e6 Binary files /dev/null and b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/eye@2x.png differ diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/eye@3x.png b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/eye@3x.png new file mode 100644 index 0000000..d13b499 Binary files /dev/null and b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Images.xcassets/test.imageset/eye@3x.png differ diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Info.plist b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/ViewController.swift b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/ViewController.swift new file mode 100644 index 0000000..7148a14 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/AssistiveButton/ViewController.swift @@ -0,0 +1,34 @@ +// +// ViewController.swift +// AssistiveButton +// +// Created by zixun on 12/25/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit +import AssistiveButton + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + self.view.backgroundColor = UIColor.red + + let frame = CGRect(x: 0, y: 100, width: 48, height: 48) + let btn = AssistiveButton(frame: frame, normalImage: UIImage(named: "test")!) + + btn.didTap = { () -> () in + print("abc") + } + self.view.addSubview(btn) + + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + +} + diff --git a/Carthage/Checkouts/AssistiveButton/Example/Podfile b/Carthage/Checkouts/AssistiveButton/Example/Podfile new file mode 100644 index 0000000..ecce28d --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/Podfile @@ -0,0 +1,11 @@ +use_frameworks! + +target 'AssistiveButton_Example' do + pod 'AssistiveButton', :path => '../' + + target 'AssistiveButton_Tests' do + inherit! :search_paths + + + end +end diff --git a/Carthage/Checkouts/AssistiveButton/Example/Podfile.lock b/Carthage/Checkouts/AssistiveButton/Example/Podfile.lock new file mode 100644 index 0000000..66cbed7 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - AssistiveButton (0.1.0) + +DEPENDENCIES: + - AssistiveButton (from `../`) + +EXTERNAL SOURCES: + AssistiveButton: + :path: "../" + +SPEC CHECKSUMS: + AssistiveButton: b3ed89fdfea31218a90a6a617cdbd0931c8abdf2 + +PODFILE CHECKSUM: f196779507dcad2139b98a6fdc7ae652a0dec240 + +COCOAPODS: 1.1.1 diff --git a/Carthage/Checkouts/AssistiveButton/Example/Tests/Info.plist b/Carthage/Checkouts/AssistiveButton/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/AssistiveButton/Example/Tests/Tests.swift b/Carthage/Checkouts/AssistiveButton/Example/Tests/Tests.swift new file mode 100644 index 0000000..97b2ecc --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/Example/Tests/Tests.swift @@ -0,0 +1,29 @@ +import UIKit +import XCTest +import AssistiveButton + +class Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + XCTAssert(true, "Pass") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure() { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Carthage/Checkouts/AssistiveButton/LICENSE b/Carthage/Checkouts/AssistiveButton/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/AssistiveButton/README.md b/Carthage/Checkouts/AssistiveButton/README.md new file mode 100644 index 0000000..28e9de7 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/README.md @@ -0,0 +1,57 @@ +# AssistiveButton + +[![Swift 3.0+](https://img.shields.io/badge/Swift-3.0%2B-orange.svg)](https://github.com/zixun/AssistiveButton) +[![Platform](https://img.shields.io/badge/Platform-iOS-lightgrey.svg)](https://github.com/zixun/AssistiveButton) +[![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) + +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) +## Context +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly disply Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Example + +To run the example project, clone the repo, and run `pod install` from the Example directory first. + +## Installation + +### CocoaPods +AssistiveButton is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "AssistiveButton" +``` + +### Carthage +Or, if you’re using [Carthage](https://github.com/Carthage/Carthage), add SwViewCapture to your Cartfile: + +``` +github "zixun/AssistiveButton" + +## Usage + +```swift +let frame = CGRect(x: 0, y: 100, width: 48, height: 48) +let btn = AssistiveButton(frame: frame, normalImage: UIImage(named: "test")!) + +btn.didTap = { () -> () in + print("abc") +} +self.view.addSubview(btn) +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + +## License + +AssistiveButton is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/AssistiveButton/_Pods.xcodeproj b/Carthage/Checkouts/AssistiveButton/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/AssistiveButton/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/CrashEye/.gitignore b/Carthage/Checkouts/CrashEye/.gitignore new file mode 100644 index 0000000..1de2633 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/CrashEye/CrashEye.podspec b/Carthage/Checkouts/CrashEye/CrashEye.podspec new file mode 100644 index 0000000..2c33bcb --- /dev/null +++ b/Carthage/Checkouts/CrashEye/CrashEye.podspec @@ -0,0 +1,33 @@ +# +# Be sure to run `pod lib lint CrashEye.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'CrashEye' + s.version = '1.1.0' + s.summary = 'CrashEye is an ios crash monitor,automatic catch exception crash & signal crash and return the stacktrace.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +CrashEye is an ios crash monitor,automatic catch exception crash & signal crash and return the crash stacktrace. + DESC + + s.homepage = 'https://github.com/zixun/CrashEye' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'zixun' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/CrashEye.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'CrashEye/Classes/**/*' +end diff --git a/Carthage/Checkouts/CrashEye/CrashEye/Classes/CrashEye.swift b/Carthage/Checkouts/CrashEye/CrashEye/Classes/CrashEye.swift new file mode 100644 index 0000000..e6de029 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/CrashEye/Classes/CrashEye.swift @@ -0,0 +1,249 @@ +// +// CrashEye.swift +// Pods +// +// Created by zixun on 16/12/23. +// +// + +import Foundation + +//-------------------------------------------------------------------------- +// MARK: - CrashEyeDelegate +//-------------------------------------------------------------------------- +public protocol CrashEyeDelegate: NSObjectProtocol { + func crashEyeDidCatchCrash(with model:CrashModel) +} + +//-------------------------------------------------------------------------- +// MARK: - WeakCrashEyeDelegate +//-------------------------------------------------------------------------- +class WeakCrashEyeDelegate: NSObject { + weak var delegate: CrashEyeDelegate? + + init(delegate: CrashEyeDelegate) { + super.init() + self.delegate = delegate + } +} + +//-------------------------------------------------------------------------- +// MARK: - CrashModelType +//-------------------------------------------------------------------------- +public enum CrashModelType:Int { + case signal = 1 + case exception = 2 +} + +//-------------------------------------------------------------------------- +// MARK: - CrashModel +//-------------------------------------------------------------------------- +open class CrashModel: NSObject { + + open var type: CrashModelType! + open var name: String! + open var reason: String! + open var appinfo: String! + open var callStack: String! + + init(type:CrashModelType, + name:String, + reason:String, + appinfo:String, + callStack:String) { + super.init() + self.type = type + self.name = name + self.reason = reason + self.appinfo = appinfo + self.callStack = callStack + } +} + +//-------------------------------------------------------------------------- +// MARK: - GLOBAL VARIABLE +//-------------------------------------------------------------------------- +private var app_old_exceptionHandler:(@convention(c) (NSException) -> Swift.Void)? = nil + +//-------------------------------------------------------------------------- +// MARK: - CrashEye +//-------------------------------------------------------------------------- +public class CrashEye: NSObject { + + //-------------------------------------------------------------------------- + // MARK: OPEN PROPERTY + //-------------------------------------------------------------------------- + public private(set) static var isOpen: Bool = false + + //-------------------------------------------------------------------------- + // MARK: OPEN FUNCTION + //-------------------------------------------------------------------------- + open class func add(delegate:CrashEyeDelegate) { + // delete null week delegate + self.delegates = self.delegates.filter { + return $0.delegate != nil + } + + // judge if contains the delegate from parameter + let contains = self.delegates.contains { + return $0.delegate?.hash == delegate.hash + } + // if not contains, append it with weak wrapped + if contains == false { + let week = WeakCrashEyeDelegate(delegate: delegate) + self.delegates.append(week) + } + + if self.delegates.count > 0 { + self.open() + } + } + + open class func remove(delegate:CrashEyeDelegate) { + self.delegates = self.delegates.filter { + // filter null weak delegate + return $0.delegate != nil + }.filter { + // filter the delegate from parameter + return $0.delegate?.hash != delegate.hash + } + + if self.delegates.count == 0 { + self.close() + } + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE FUNCTION + //-------------------------------------------------------------------------- + private class func open() { + guard self.isOpen == false else { + return + } + CrashEye.isOpen = true + + app_old_exceptionHandler = NSGetUncaughtExceptionHandler() + NSSetUncaughtExceptionHandler(CrashEye.RecieveException) + self.setCrashSignalHandler() + } + + private class func close() { + guard self.isOpen == true else { + return + } + CrashEye.isOpen = false + NSSetUncaughtExceptionHandler(app_old_exceptionHandler) + } + + private class func setCrashSignalHandler(){ + signal(SIGABRT, CrashEye.RecieveSignal) + signal(SIGILL, CrashEye.RecieveSignal) + signal(SIGSEGV, CrashEye.RecieveSignal) + signal(SIGFPE, CrashEye.RecieveSignal) + signal(SIGBUS, CrashEye.RecieveSignal) + signal(SIGPIPE, CrashEye.RecieveSignal) + //http://stackoverflow.com/questions/36325140/how-to-catch-a-swift-crash-and-do-some-logging + signal(SIGTRAP, CrashEye.RecieveSignal) + } + + private static let RecieveException: @convention(c) (NSException) -> Swift.Void = { + (exteption) -> Void in + if (app_old_exceptionHandler != nil) { + app_old_exceptionHandler!(exteption); + } + + guard CrashEye.isOpen == true else { + return + } + + let callStack = exteption.callStackSymbols.joined(separator: "\r") + let reason = exteption.reason ?? "" + let name = exteption.name + let appinfo = CrashEye.appInfo() + + + let model = CrashModel(type:CrashModelType.exception, + name:name.rawValue, + reason:reason, + appinfo:appinfo, + callStack:callStack) + for delegate in CrashEye.delegates { + delegate.delegate?.crashEyeDidCatchCrash(with: model) + } + } + + private static let RecieveSignal : @convention(c) (Int32) -> Void = { + (signal) -> Void in + + guard CrashEye.isOpen == true else { + return + } + + var stack = Thread.callStackSymbols + stack.removeFirst(2) + let callStack = stack.joined(separator: "\r") + let reason = "Signal \(CrashEye.name(of: signal))(\(signal)) was raised.\n" + let appinfo = CrashEye.appInfo() + + let model = CrashModel(type:CrashModelType.signal, + name:CrashEye.name(of: signal), + reason:reason, + appinfo:appinfo, + callStack:callStack) + + for delegate in CrashEye.delegates { + delegate.delegate?.crashEyeDidCatchCrash(with: model) + } + + CrashEye.killApp() + } + + private class func appInfo() -> String { + let displayName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") ?? "" + let shortVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "" + let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "" + let deviceModel = UIDevice.current.model + let systemName = UIDevice.current.systemName + let systemVersion = UIDevice.current.systemVersion + return "App: \(displayName) \(shortVersion)(\(version))\n" + + "Device:\(deviceModel)\n" + "OS Version:\(systemName) \(systemVersion)" + } + + + private class func name(of signal:Int32) -> String { + switch (signal) { + case SIGABRT: + return "SIGABRT" + case SIGILL: + return "SIGILL" + case SIGSEGV: + return "SIGSEGV" + case SIGFPE: + return "SIGFPE" + case SIGBUS: + return "SIGBUS" + case SIGPIPE: + return "SIGPIPE" + default: + return "OTHER" + } + } + + private class func killApp(){ + NSSetUncaughtExceptionHandler(nil) + + signal(SIGABRT, SIG_DFL) + signal(SIGILL, SIG_DFL) + signal(SIGSEGV, SIG_DFL) + signal(SIGFPE, SIG_DFL) + signal(SIGBUS, SIG_DFL) + signal(SIGPIPE, SIG_DFL) + + kill(getpid(), SIGKILL) + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE PROPERTY + //-------------------------------------------------------------------------- + fileprivate static var delegates = [WeakCrashEyeDelegate]() +} diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/project.pbxproj b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/project.pbxproj new file mode 100644 index 0000000..153c57a --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/project.pbxproj @@ -0,0 +1,744 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 30D65D6E9BCAFB2037A8F719 /* Pods_CrashEye_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBFBA31818B946FCA08DB0E7 /* Pods_CrashEye_Tests.framework */; }; + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 9E24FA6B1E810ADC001AD0D7 /* CrashEye.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24FA691E810ADC001AD0D7 /* CrashEye.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FA771E810AE7001AD0D7 /* CrashEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA741E810AE7001AD0D7 /* CrashEye.swift */; }; + AAB8106104EFCA27495FABB1 /* Pods_CrashEye_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B123EE73DD3EAEAE0F3956BD /* Pods_CrashEye_Example.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = CrashEye; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 607FACD01AFB9204008FA782 /* CrashEye_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CrashEye_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 607FACE51AFB9204008FA782 /* CrashEye_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CrashEye_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + 6414DE440A0BED3968574E13 /* Pods-CrashEye_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CrashEye_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-CrashEye_Example/Pods-CrashEye_Example.release.xcconfig"; sourceTree = ""; }; + 89DA72A5867BF7F7001C5EF1 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + 932D8ED2DBB67EC0A8ACF584 /* Pods-CrashEye_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CrashEye_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CrashEye_Example/Pods-CrashEye_Example.debug.xcconfig"; sourceTree = ""; }; + 9E24FA671E810ADC001AD0D7 /* CrashEye.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CrashEye.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24FA691E810ADC001AD0D7 /* CrashEye.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CrashEye.h; sourceTree = ""; }; + 9E24FA6A1E810ADC001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24FA741E810AE7001AD0D7 /* CrashEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CrashEye.swift; sourceTree = ""; }; + AF8DE7FCF29A7A3996051AC2 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + B123EE73DD3EAEAE0F3956BD /* Pods_CrashEye_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CrashEye_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C77933209E64DDD3E21C4ABF /* Pods-CrashEye_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CrashEye_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CrashEye_Tests/Pods-CrashEye_Tests.debug.xcconfig"; sourceTree = ""; }; + E7B22179B657D22D63E85667 /* CrashEye.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CrashEye.podspec; path = ../CrashEye.podspec; sourceTree = ""; }; + F3045FEAA1FFC0A078DBF094 /* Pods-CrashEye_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CrashEye_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CrashEye_Tests/Pods-CrashEye_Tests.release.xcconfig"; sourceTree = ""; }; + FBFBA31818B946FCA08DB0E7 /* Pods_CrashEye_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CrashEye_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AAB8106104EFCA27495FABB1 /* Pods_CrashEye_Example.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 30D65D6E9BCAFB2037A8F719 /* Pods_CrashEye_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA631E810ADC001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 45119F8C63A827E252799401 /* Frameworks */ = { + isa = PBXGroup; + children = ( + B123EE73DD3EAEAE0F3956BD /* Pods_CrashEye_Example.framework */, + FBFBA31818B946FCA08DB0E7 /* Pods_CrashEye_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for CrashEye */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24FA681E810ADC001AD0D7 /* CrashEye */, + 607FACD11AFB9204008FA782 /* Products */, + A7BF527AF68A689201F113C6 /* Pods */, + 45119F8C63A827E252799401 /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* CrashEye_Example.app */, + 607FACE51AFB9204008FA782 /* CrashEye_Tests.xctest */, + 9E24FA671E810ADC001AD0D7 /* CrashEye.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for CrashEye */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 607FACD91AFB9204008FA782 /* Main.storyboard */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for CrashEye"; + path = CrashEye; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* Tests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + E7B22179B657D22D63E85667 /* CrashEye.podspec */, + AF8DE7FCF29A7A3996051AC2 /* README.md */, + 89DA72A5867BF7F7001C5EF1 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 9E24FA681E810ADC001AD0D7 /* CrashEye */ = { + isa = PBXGroup; + children = ( + 9E24FA6F1E810AE7001AD0D7 /* CrashEye */, + 9E24FA691E810ADC001AD0D7 /* CrashEye.h */, + 9E24FA6A1E810ADC001AD0D7 /* Info.plist */, + ); + path = CrashEye; + sourceTree = ""; + }; + 9E24FA6F1E810AE7001AD0D7 /* CrashEye */ = { + isa = PBXGroup; + children = ( + 9E24FA721E810AE7001AD0D7 /* Classes */, + ); + name = CrashEye; + path = ../../CrashEye; + sourceTree = ""; + }; + 9E24FA721E810AE7001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24FA741E810AE7001AD0D7 /* CrashEye.swift */, + ); + path = Classes; + sourceTree = ""; + }; + A7BF527AF68A689201F113C6 /* Pods */ = { + isa = PBXGroup; + children = ( + 932D8ED2DBB67EC0A8ACF584 /* Pods-CrashEye_Example.debug.xcconfig */, + 6414DE440A0BED3968574E13 /* Pods-CrashEye_Example.release.xcconfig */, + C77933209E64DDD3E21C4ABF /* Pods-CrashEye_Tests.debug.xcconfig */, + F3045FEAA1FFC0A078DBF094 /* Pods-CrashEye_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24FA641E810ADC001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA6B1E810ADC001AD0D7 /* CrashEye.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* CrashEye_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "CrashEye_Example" */; + buildPhases = ( + F054FD555903E2293623FE81 /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + D8C6B6E74A50EE0CA59984C4 /* [CP] Embed Pods Frameworks */, + 23F43BE133993B38C6096BF1 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CrashEye_Example; + productName = CrashEye; + productReference = 607FACD01AFB9204008FA782 /* CrashEye_Example.app */; + productType = "com.apple.product-type.application"; + }; + 607FACE41AFB9204008FA782 /* CrashEye_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "CrashEye_Tests" */; + buildPhases = ( + CB12523A6EDDC1A1AFEFCBBF /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + 29219E941909AB4B6F98E44D /* [CP] Embed Pods Frameworks */, + 89A3255AA14B15EF8534A9E6 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 607FACE71AFB9204008FA782 /* PBXTargetDependency */, + ); + name = CrashEye_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* CrashEye_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24FA661E810ADC001AD0D7 /* CrashEye */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24FA6E1E810ADC001AD0D7 /* Build configuration list for PBXNativeTarget "CrashEye" */; + buildPhases = ( + 9E24FA621E810ADC001AD0D7 /* Sources */, + 9E24FA631E810ADC001AD0D7 /* Frameworks */, + 9E24FA641E810ADC001AD0D7 /* Headers */, + 9E24FA651E810ADC001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CrashEye; + productName = CrashEye; + productReference = 9E24FA671E810ADC001AD0D7 /* CrashEye.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + }; + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24FA661E810ADC001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + LastSwiftMigration = 0820; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "CrashEye" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* CrashEye_Example */, + 607FACE41AFB9204008FA782 /* CrashEye_Tests */, + 9E24FA661E810ADC001AD0D7 /* CrashEye */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA651E810ADC001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 23F43BE133993B38C6096BF1 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CrashEye_Example/Pods-CrashEye_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 29219E941909AB4B6F98E44D /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CrashEye_Tests/Pods-CrashEye_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 89A3255AA14B15EF8534A9E6 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CrashEye_Tests/Pods-CrashEye_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + CB12523A6EDDC1A1AFEFCBBF /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + D8C6B6E74A50EE0CA59984C4 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CrashEye_Example/Pods-CrashEye_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F054FD555903E2293623FE81 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA621E810ADC001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA771E810AE7001AD0D7 /* CrashEye.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* CrashEye_Example */; + targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 607FACD91AFB9204008FA782 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 607FACDA1AFB9204008FA782 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 932D8ED2DBB67EC0A8ACF584 /* Pods-CrashEye_Example.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = CrashEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6414DE440A0BED3968574E13 /* Pods-CrashEye_Example.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = CrashEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C77933209E64DDD3E21C4ABF /* Pods-CrashEye_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F3045FEAA1FFC0A078DBF094 /* Pods-CrashEye_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24FA6C1E810ADC001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = CrashEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.CrashEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24FA6D1E810ADC001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = CrashEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.CrashEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "CrashEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "CrashEye_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "CrashEye_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24FA6E1E810ADC001AD0D7 /* Build configuration list for PBXNativeTarget "CrashEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24FA6C1E810ADC001AD0D7 /* Debug */, + 9E24FA6D1E810ADC001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..a052bbd --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/project.xcworkspace/xcshareddata/CrashEye.xcscmblueprint b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/project.xcworkspace/xcshareddata/CrashEye.xcscmblueprint new file mode 100644 index 0000000..618f7c7 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/project.xcworkspace/xcshareddata/CrashEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "176CADFAA9739C57FD277A2658D64742B30CB35F", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "176CADFAA9739C57FD277A2658D64742B30CB35F" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "F43A6501-4107-4D16-8686-45CDAFC42EAA", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "176CADFAA9739C57FD277A2658D64742B30CB35F" : "CrashEye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "CrashEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/CrashEye.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/CrashEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "176CADFAA9739C57FD277A2658D64742B30CB35F" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/xcshareddata/xcschemes/CrashEye-Example.xcscheme b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/xcshareddata/xcschemes/CrashEye-Example.xcscheme new file mode 100644 index 0000000..df895ee --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/xcshareddata/xcschemes/CrashEye-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/xcshareddata/xcschemes/CrashEye.xcscheme b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/xcshareddata/xcschemes/CrashEye.xcscheme new file mode 100644 index 0000000..ea4898b --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcodeproj/xcshareddata/xcschemes/CrashEye.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..7af6787 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye.xcworkspace/xcshareddata/CrashEye.xcscmblueprint b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcworkspace/xcshareddata/CrashEye.xcscmblueprint new file mode 100644 index 0000000..164277e --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye.xcworkspace/xcshareddata/CrashEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "176CADFAA9739C57FD277A2658D64742B30CB35F", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "176CADFAA9739C57FD277A2658D64742B30CB35F" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "46A1C854-1ED4-478B-BCA5-627F7125A0A8", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "176CADFAA9739C57FD277A2658D64742B30CB35F" : "CrashEye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "CrashEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/CrashEye.xcworkspace", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:GodEyeSwift\/CrashEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "176CADFAA9739C57FD277A2658D64742B30CB35F" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye/AppDelegate.swift b/Carthage/Checkouts/CrashEye/Example/CrashEye/AppDelegate.swift new file mode 100644 index 0000000..3855bfc --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// CrashEye +// +// Created by zixun on 12/23/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/CrashEye/Example/CrashEye/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..b809f4d --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye/Base.lproj/LaunchScreen.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye/Base.lproj/Main.storyboard b/Carthage/Checkouts/CrashEye/Example/CrashEye/Base.lproj/Main.storyboard new file mode 100644 index 0000000..52ea29e --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye/CrashEye.h b/Carthage/Checkouts/CrashEye/Example/CrashEye/CrashEye.h new file mode 100644 index 0000000..0f5908f --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye/CrashEye.h @@ -0,0 +1,19 @@ +// +// CrashEye.h +// CrashEye +// +// Created by zixun on 2017/3/21. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for CrashEye. +FOUNDATION_EXPORT double CrashEyeVersionNumber; + +//! Project version string for CrashEye. +FOUNDATION_EXPORT const unsigned char CrashEyeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/CrashEye/Example/CrashEye/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d3942e9 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye/Info.plist b/Carthage/Checkouts/CrashEye/Example/CrashEye/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/CrashEye/Example/CrashEye/ViewController.swift b/Carthage/Checkouts/CrashEye/Example/CrashEye/ViewController.swift new file mode 100644 index 0000000..ada6eb0 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/CrashEye/ViewController.swift @@ -0,0 +1,33 @@ +// +// ViewController.swift +// CrashEye +// +// Created by zixun on 12/23/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit +import CrashEye + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + CrashEye.add(delegate: self) + CrashEye.open() + CrashEye.close() + CrashEye.open() + let arr = NSArray() + arr[10] + } + +} + +extension ViewController: CrashEyeDelegate { + + func crashEyeDidCatchCrash(with model:CrashModel) { + print(model) + } +} + diff --git a/Carthage/Checkouts/CrashEye/Example/Podfile b/Carthage/Checkouts/CrashEye/Example/Podfile new file mode 100644 index 0000000..9f95317 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/Podfile @@ -0,0 +1,11 @@ +use_frameworks! + +target 'CrashEye_Example' do + pod 'CrashEye', :path => '../' + + target 'CrashEye_Tests' do + inherit! :search_paths + + + end +end diff --git a/Carthage/Checkouts/CrashEye/Example/Podfile.lock b/Carthage/Checkouts/CrashEye/Example/Podfile.lock new file mode 100644 index 0000000..4756cce --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - CrashEye (1.0.0) + +DEPENDENCIES: + - CrashEye (from `../`) + +EXTERNAL SOURCES: + CrashEye: + :path: "../" + +SPEC CHECKSUMS: + CrashEye: eb7fb132dd1612f163d456142c451151df1f8e99 + +PODFILE CHECKSUM: 9e0da17e46e41bc2d6df8c392ec74790b310654f + +COCOAPODS: 1.2.0 diff --git a/Carthage/Checkouts/CrashEye/Example/Tests/Info.plist b/Carthage/Checkouts/CrashEye/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/CrashEye/Example/Tests/Tests.swift b/Carthage/Checkouts/CrashEye/Example/Tests/Tests.swift new file mode 100644 index 0000000..1ef3954 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/Example/Tests/Tests.swift @@ -0,0 +1,29 @@ +import UIKit +import XCTest +import CrashEye + +class Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + XCTAssert(true, "Pass") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure() { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Carthage/Checkouts/CrashEye/LICENSE b/Carthage/Checkouts/CrashEye/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/CrashEye/README.md b/Carthage/Checkouts/CrashEye/README.md new file mode 100644 index 0000000..353e090 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/README.md @@ -0,0 +1,73 @@ +#CrashEye + +[![Version](https://img.shields.io/cocoapods/v/CrashEye.svg?style=flat)](http://cocoapods.org/pods/CrashEye) +[![License](https://img.shields.io/cocoapods/l/CrashEye.svg?style=flat)](http://cocoapods.org/pods/CrashEye) +[![Platform](https://img.shields.io/cocoapods/p/CrashEye.svg?style=flat)](http://cocoapods.org/pods/CrashEye) +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) + +CrashEye is an ios crash monitor,automatic catch exception crash & signal crash and return the stacktrace + +## Family +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Book & Principle + +**I has wrote a book named [《iOS监控编程》](https://www.qingdan.us/product/25),each chapter records the course function of the implementation details and the way to explore.sorry for english friends,this book wrote by chineses.** + +## Features + +- [x] monitor uncatched exception crash. +- [x] monitor signal crash. + + +## Installation + +### CocoaPods +CrashEye is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "CrashEye" +``` + +### Carthage +Or, if you’re using [Carthage](https://github.com/Carthage/Carthage), add SwViewCapture to your Cartfile: + +``` +github "zixun/CrashEye" + +## Usage +### open and add delegate + +```swift +CrashEye.add(delegate: self) +CrashEye.open() +``` + +### implement the delegate + +```swift +extension ViewController: CrashEyeDelegate { + func crashEyeDidCatchCrash(with model:CrashModel) { + print(model) + } +} +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + + + +## License + +CrashEye is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/CrashEye/_Pods.xcodeproj b/Carthage/Checkouts/CrashEye/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/CrashEye/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/FileBrowser/.gitignore b/Carthage/Checkouts/FileBrowser/.gitignore new file mode 100644 index 0000000..5e5d5ce --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/.gitignore @@ -0,0 +1,63 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md + +fastlane/report.xml +fastlane/screenshots diff --git a/Carthage/Checkouts/FileBrowser/.swift-version b/Carthage/Checkouts/FileBrowser/.swift-version new file mode 100644 index 0000000..9f55b2c --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/.swift-version @@ -0,0 +1 @@ +3.0 diff --git a/Carthage/Checkouts/FileBrowser/.travis.yml b/Carthage/Checkouts/FileBrowser/.travis.yml new file mode 100644 index 0000000..e1e0f7f --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/.travis.yml @@ -0,0 +1,19 @@ +osx_image: xcode8 +language: objective-c +env: + global: + - LC_CTYPE=en_US.UTF-8 + - LANG=en_US.UTF-8 +before_install: + - gem install cocoapods --pre + - xcrun simctl list +install: echo "<3" +env: + - MODE=framework + - MODE=examples +script: ./build.sh $MODE + +# whitelist +branches: + only: + - master diff --git a/Carthage/Checkouts/FileBrowser/CHANGELOG.md b/Carthage/Checkouts/FileBrowser/CHANGELOG.md new file mode 100644 index 0000000..2ffa626 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log + +## [0.1.0](https://github.com/marmelroy/FileBrowser/tree/0.1.0) (2016-02-16) +**Closed issues:** + +- Images for README [\#1](https://github.com/marmelroy/Zip/issues/1) + + + +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser.podspec b/Carthage/Checkouts/FileBrowser/FileBrowser.podspec new file mode 100644 index 0000000..2da9b4c --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser.podspec @@ -0,0 +1,40 @@ +# +# Be sure to run `pod lib lint FileBrowser.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = "FileBrowser" + s.version = "0.2.0" + s.summary = "Powerful iOS file browser in Swift." + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + s.description = <<-DESC + A Swift file browser for iOS. Supports QuickLook, search and 3D touch. + DESC + + s.homepage = "https://github.com/marmelroy/FileBrowser" + # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" + s.license = 'MIT' + s.author = { "Roy Marmelstein" => "marmelroy@gmail.com" } + s.source = { :git => "https://github.com/marmelroy/FileBrowser.git", :tag => s.version.to_s, :submodules => true} + s.social_media_url = "http://twitter.com/marmelroy" + + s.ios.deployment_target = '8.0' + s.requires_arc = true + + s.source_files = "FileBrowser" + s.resources = "FileBrowser/Resources/*.*" + + # s.public_header_files = 'Pod/Classes/**/*.h' + s.frameworks = 'QuickLook', 'WebKit' + # s.dependency 'AFNetworking', '~> 2.3' + +end diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser.xcodeproj/project.pbxproj b/Carthage/Checkouts/FileBrowser/FileBrowser.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d6fb649 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser.xcodeproj/project.pbxproj @@ -0,0 +1,543 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 3437405B1C6E7DA50090FD6A /* FileListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3437405A1C6E7DA50090FD6A /* FileListViewController.swift */; }; + 3439AB681C6F203A0058AF04 /* FileParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3439AB671C6F203A0058AF04 /* FileParser.swift */; }; + 3439AB6A1C6FC6D90058AF04 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3439AB691C6FC6D90058AF04 /* QuickLook.framework */; settings = {ATTRIBUTES = (Required, ); }; }; + 3439AB6C1C6FD6650058AF04 /* FileListPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3439AB6B1C6FD6650058AF04 /* FileListPreview.swift */; }; + 3439AB701C6FF68C0058AF04 /* FileBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3439AB6F1C6FF68C0058AF04 /* FileBrowser.swift */; }; + 343C44631C73CC8100D874FB /* PreviewTransitionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 343C44611C73CC8100D874FB /* PreviewTransitionViewController.swift */; }; + 343C44661C73CD3200D874FB /* PreviewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 343C44651C73CD3200D874FB /* PreviewManager.swift */; }; + 343C44681C73CD8700D874FB /* PreviewTransitionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 343C44671C73CD8700D874FB /* PreviewTransitionViewController.xib */; }; + 343C447A1C73CFC400D874FB /* WebviewPreviewViewContoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 343C44781C73CFC400D874FB /* WebviewPreviewViewContoller.swift */; }; + 343C447D1C73CFD900D874FB /* WebviewPreviewViewContoller.xib in Resources */ = {isa = PBXBuildFile; fileRef = 343C447C1C73CFD900D874FB /* WebviewPreviewViewContoller.xib */; }; + 343C447F1C73D06200D874FB /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 343C447E1C73D06200D874FB /* WebKit.framework */; }; + 344169581C67812400B93D28 /* FileBrowser.h in Headers */ = {isa = PBXBuildFile; fileRef = 344169571C67812400B93D28 /* FileBrowser.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3441695F1C67812400B93D28 /* FileBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 344169541C67812400B93D28 /* FileBrowser.framework */; }; + 344169641C67812400B93D28 /* FileBrowserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 344169631C67812400B93D28 /* FileBrowserTests.swift */; }; + 3441DC611C71235C005CC2FA /* 3crBXeO.gif in Resources */ = {isa = PBXBuildFile; fileRef = 3441DC601C71235C005CC2FA /* 3crBXeO.gif */; }; + 3441DC631C712370005CC2FA /* Stitch.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 3441DC621C712370005CC2FA /* Stitch.jpg */; }; + 349A12241C70725D005435C0 /* FileListSearch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349A12231C70725D005435C0 /* FileListSearch.swift */; }; + 349A12261C707317005435C0 /* FileListTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349A12251C707317005435C0 /* FileListTableView.swift */; }; + 349A12281C707B1A005435C0 /* FBFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349A12271C707B1A005435C0 /* FBFile.swift */; }; + 349A12321C707E86005435C0 /* documents@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 349A122B1C707E86005435C0 /* documents@2x.png */; }; + 349A12331C707E86005435C0 /* file@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 349A122C1C707E86005435C0 /* file@2x.png */; }; + 349A12341C707E86005435C0 /* FileBrowser.xib in Resources */ = {isa = PBXBuildFile; fileRef = 349A122D1C707E86005435C0 /* FileBrowser.xib */; }; + 349A12351C707E86005435C0 /* folder@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 349A122E1C707E86005435C0 /* folder@2x.png */; }; + 349A12361C707E86005435C0 /* image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 349A122F1C707E86005435C0 /* image@2x.png */; }; + 349A12371C707E86005435C0 /* pdf@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 349A12301C707E86005435C0 /* pdf@2x.png */; }; + 349A12381C707E86005435C0 /* zip@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 349A12311C707E86005435C0 /* zip@2x.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 344169601C67812400B93D28 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3441694B1C67812400B93D28 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 344169531C67812400B93D28; + remoteInfo = FileBrowser; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3437405A1C6E7DA50090FD6A /* FileListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileListViewController.swift; sourceTree = ""; }; + 3439AB671C6F203A0058AF04 /* FileParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileParser.swift; sourceTree = ""; }; + 3439AB691C6FC6D90058AF04 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = System/Library/Frameworks/QuickLook.framework; sourceTree = SDKROOT; }; + 3439AB6B1C6FD6650058AF04 /* FileListPreview.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileListPreview.swift; sourceTree = ""; }; + 3439AB6F1C6FF68C0058AF04 /* FileBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileBrowser.swift; sourceTree = ""; }; + 343C44611C73CC8100D874FB /* PreviewTransitionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewTransitionViewController.swift; sourceTree = ""; }; + 343C44651C73CD3200D874FB /* PreviewManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewManager.swift; sourceTree = ""; }; + 343C44671C73CD8700D874FB /* PreviewTransitionViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PreviewTransitionViewController.xib; sourceTree = ""; }; + 343C44781C73CFC400D874FB /* WebviewPreviewViewContoller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebviewPreviewViewContoller.swift; sourceTree = ""; }; + 343C447C1C73CFD900D874FB /* WebviewPreviewViewContoller.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WebviewPreviewViewContoller.xib; sourceTree = ""; }; + 343C447E1C73D06200D874FB /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + 344169541C67812400B93D28 /* FileBrowser.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FileBrowser.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 344169571C67812400B93D28 /* FileBrowser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FileBrowser.h; sourceTree = ""; }; + 344169591C67812400B93D28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3441695E1C67812400B93D28 /* FileBrowserTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FileBrowserTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 344169631C67812400B93D28 /* FileBrowserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileBrowserTests.swift; sourceTree = ""; }; + 344169651C67812400B93D28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3441DC601C71235C005CC2FA /* 3crBXeO.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = 3crBXeO.gif; sourceTree = ""; }; + 3441DC621C712370005CC2FA /* Stitch.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = Stitch.jpg; sourceTree = ""; }; + 349A12231C70725D005435C0 /* FileListSearch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileListSearch.swift; sourceTree = ""; }; + 349A12251C707317005435C0 /* FileListTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileListTableView.swift; sourceTree = ""; }; + 349A12271C707B1A005435C0 /* FBFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBFile.swift; sourceTree = ""; }; + 349A122B1C707E86005435C0 /* documents@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "documents@2x.png"; sourceTree = ""; }; + 349A122C1C707E86005435C0 /* file@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "file@2x.png"; sourceTree = ""; }; + 349A122D1C707E86005435C0 /* FileBrowser.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FileBrowser.xib; sourceTree = ""; }; + 349A122E1C707E86005435C0 /* folder@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "folder@2x.png"; sourceTree = ""; }; + 349A122F1C707E86005435C0 /* image@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image@2x.png"; sourceTree = ""; }; + 349A12301C707E86005435C0 /* pdf@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pdf@2x.png"; sourceTree = ""; }; + 349A12311C707E86005435C0 /* zip@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "zip@2x.png"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 344169501C67812400B93D28 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 343C447F1C73D06200D874FB /* WebKit.framework in Frameworks */, + 3439AB6A1C6FC6D90058AF04 /* QuickLook.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3441695B1C67812400B93D28 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3441695F1C67812400B93D28 /* FileBrowser.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 343C445E1C73CB9600D874FB /* Data */ = { + isa = PBXGroup; + children = ( + 3439AB671C6F203A0058AF04 /* FileParser.swift */, + 349A12271C707B1A005435C0 /* FBFile.swift */, + ); + name = Data; + sourceTree = ""; + }; + 343C445F1C73CBA900D874FB /* FileList */ = { + isa = PBXGroup; + children = ( + 3437405A1C6E7DA50090FD6A /* FileListViewController.swift */, + 3439AB6B1C6FD6650058AF04 /* FileListPreview.swift */, + 349A12231C70725D005435C0 /* FileListSearch.swift */, + 349A12251C707317005435C0 /* FileListTableView.swift */, + ); + name = FileList; + sourceTree = ""; + }; + 343C44601C73CC3C00D874FB /* Preview */ = { + isa = PBXGroup; + children = ( + 343C44611C73CC8100D874FB /* PreviewTransitionViewController.swift */, + 343C44651C73CD3200D874FB /* PreviewManager.swift */, + 343C44781C73CFC400D874FB /* WebviewPreviewViewContoller.swift */, + ); + name = Preview; + sourceTree = ""; + }; + 3441694A1C67812400B93D28 = { + isa = PBXGroup; + children = ( + 344169561C67812400B93D28 /* FileBrowser */, + 344169621C67812400B93D28 /* FileBrowserTests */, + 344169551C67812400B93D28 /* Products */, + ); + sourceTree = ""; + }; + 344169551C67812400B93D28 /* Products */ = { + isa = PBXGroup; + children = ( + 344169541C67812400B93D28 /* FileBrowser.framework */, + 3441695E1C67812400B93D28 /* FileBrowserTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 344169561C67812400B93D28 /* FileBrowser */ = { + isa = PBXGroup; + children = ( + 344169571C67812400B93D28 /* FileBrowser.h */, + 3439AB6F1C6FF68C0058AF04 /* FileBrowser.swift */, + 343C445E1C73CB9600D874FB /* Data */, + 349A121D1C706601005435C0 /* Frameworks */, + 343C445F1C73CBA900D874FB /* FileList */, + 343C44601C73CC3C00D874FB /* Preview */, + 349A122A1C707E86005435C0 /* Resources */, + 344169591C67812400B93D28 /* Info.plist */, + ); + path = FileBrowser; + sourceTree = ""; + }; + 344169621C67812400B93D28 /* FileBrowserTests */ = { + isa = PBXGroup; + children = ( + 3441DC601C71235C005CC2FA /* 3crBXeO.gif */, + 3441DC621C712370005CC2FA /* Stitch.jpg */, + 344169631C67812400B93D28 /* FileBrowserTests.swift */, + 344169651C67812400B93D28 /* Info.plist */, + ); + path = FileBrowserTests; + sourceTree = ""; + }; + 349A121D1C706601005435C0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3439AB691C6FC6D90058AF04 /* QuickLook.framework */, + 343C447E1C73D06200D874FB /* WebKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 349A122A1C707E86005435C0 /* Resources */ = { + isa = PBXGroup; + children = ( + 349A122B1C707E86005435C0 /* documents@2x.png */, + 349A122C1C707E86005435C0 /* file@2x.png */, + 349A122D1C707E86005435C0 /* FileBrowser.xib */, + 349A122E1C707E86005435C0 /* folder@2x.png */, + 349A122F1C707E86005435C0 /* image@2x.png */, + 349A12301C707E86005435C0 /* pdf@2x.png */, + 343C44671C73CD8700D874FB /* PreviewTransitionViewController.xib */, + 343C447C1C73CFD900D874FB /* WebviewPreviewViewContoller.xib */, + 349A12311C707E86005435C0 /* zip@2x.png */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 344169511C67812400B93D28 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 344169581C67812400B93D28 /* FileBrowser.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 344169531C67812400B93D28 /* FileBrowser */ = { + isa = PBXNativeTarget; + buildConfigurationList = 344169681C67812400B93D28 /* Build configuration list for PBXNativeTarget "FileBrowser" */; + buildPhases = ( + 3441694F1C67812400B93D28 /* Sources */, + 344169501C67812400B93D28 /* Frameworks */, + 344169511C67812400B93D28 /* Headers */, + 344169521C67812400B93D28 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FileBrowser; + productName = FileBrowser; + productReference = 344169541C67812400B93D28 /* FileBrowser.framework */; + productType = "com.apple.product-type.framework"; + }; + 3441695D1C67812400B93D28 /* FileBrowserTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3441696B1C67812400B93D28 /* Build configuration list for PBXNativeTarget "FileBrowserTests" */; + buildPhases = ( + 3441695A1C67812400B93D28 /* Sources */, + 3441695B1C67812400B93D28 /* Frameworks */, + 3441695C1C67812400B93D28 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 344169611C67812400B93D28 /* PBXTargetDependency */, + ); + name = FileBrowserTests; + productName = FileBrowserTests; + productReference = 3441695E1C67812400B93D28 /* FileBrowserTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3441694B1C67812400B93D28 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0800; + ORGANIZATIONNAME = "Roy Marmelstein"; + TargetAttributes = { + 344169531C67812400B93D28 = { + CreatedOnToolsVersion = 7.2.1; + LastSwiftMigration = 0800; + }; + 3441695D1C67812400B93D28 = { + CreatedOnToolsVersion = 7.2.1; + LastSwiftMigration = 0800; + }; + }; + }; + buildConfigurationList = 3441694E1C67812400B93D28 /* Build configuration list for PBXProject "FileBrowser" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 3441694A1C67812400B93D28; + productRefGroup = 344169551C67812400B93D28 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 344169531C67812400B93D28 /* FileBrowser */, + 3441695D1C67812400B93D28 /* FileBrowserTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 344169521C67812400B93D28 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 343C44681C73CD8700D874FB /* PreviewTransitionViewController.xib in Resources */, + 349A12331C707E86005435C0 /* file@2x.png in Resources */, + 349A12341C707E86005435C0 /* FileBrowser.xib in Resources */, + 343C447D1C73CFD900D874FB /* WebviewPreviewViewContoller.xib in Resources */, + 349A12361C707E86005435C0 /* image@2x.png in Resources */, + 349A12371C707E86005435C0 /* pdf@2x.png in Resources */, + 349A12351C707E86005435C0 /* folder@2x.png in Resources */, + 349A12321C707E86005435C0 /* documents@2x.png in Resources */, + 349A12381C707E86005435C0 /* zip@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3441695C1C67812400B93D28 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3441DC631C712370005CC2FA /* Stitch.jpg in Resources */, + 3441DC611C71235C005CC2FA /* 3crBXeO.gif in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3441694F1C67812400B93D28 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 343C447A1C73CFC400D874FB /* WebviewPreviewViewContoller.swift in Sources */, + 3439AB701C6FF68C0058AF04 /* FileBrowser.swift in Sources */, + 349A12261C707317005435C0 /* FileListTableView.swift in Sources */, + 343C44661C73CD3200D874FB /* PreviewManager.swift in Sources */, + 3439AB681C6F203A0058AF04 /* FileParser.swift in Sources */, + 349A12281C707B1A005435C0 /* FBFile.swift in Sources */, + 343C44631C73CC8100D874FB /* PreviewTransitionViewController.swift in Sources */, + 3437405B1C6E7DA50090FD6A /* FileListViewController.swift in Sources */, + 349A12241C70725D005435C0 /* FileListSearch.swift in Sources */, + 3439AB6C1C6FD6650058AF04 /* FileListPreview.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3441695A1C67812400B93D28 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 344169641C67812400B93D28 /* FileBrowserTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 344169611C67812400B93D28 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 344169531C67812400B93D28 /* FileBrowser */; + targetProxy = 344169601C67812400B93D28 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 344169661C67812400B93D28 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 6; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 344169671C67812400B93D28 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 6; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 344169691C67812400B93D28 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 6; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = FileBrowser/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.roymarmelstein.FileBrowser; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 3441696A1C67812400B93D28 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 6; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = FileBrowser/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.roymarmelstein.FileBrowser; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 3441696C1C67812400B93D28 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = FileBrowserTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.roymarmelstein.FileBrowserTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 3441696D1C67812400B93D28 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = FileBrowserTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.roymarmelstein.FileBrowserTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3441694E1C67812400B93D28 /* Build configuration list for PBXProject "FileBrowser" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 344169661C67812400B93D28 /* Debug */, + 344169671C67812400B93D28 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 344169681C67812400B93D28 /* Build configuration list for PBXNativeTarget "FileBrowser" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 344169691C67812400B93D28 /* Debug */, + 3441696A1C67812400B93D28 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3441696B1C67812400B93D28 /* Build configuration list for PBXNativeTarget "FileBrowserTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3441696C1C67812400B93D28 /* Debug */, + 3441696D1C67812400B93D28 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3441694B1C67812400B93D28 /* Project object */; +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/FileBrowser/FileBrowser.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..0334f03 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser.xcodeproj/xcshareddata/xcschemes/FileBrowser.xcscheme b/Carthage/Checkouts/FileBrowser/FileBrowser.xcodeproj/xcshareddata/xcschemes/FileBrowser.xcscheme new file mode 100644 index 0000000..88866a2 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser.xcodeproj/xcshareddata/xcschemes/FileBrowser.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/FBFile.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/FBFile.swift new file mode 100644 index 0000000..6e8c700 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/FBFile.swift @@ -0,0 +1,127 @@ +// +// FBFile.swift +// FileBrowser +// +// Created by Roy Marmelstein on 14/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import Foundation + +/// FBFile is a class representing a file in FileBrowser +open class FBFile: NSObject { + /// Display name. String. + open let displayName: String + // is Directory. Bool. + open let isDirectory: Bool + /// File extension. + open let fileExtension: String? + /// File attributes (including size, creation date etc). + open let fileAttributes: NSDictionary? + /// NSURL file path. + open let filePath: URL + // FBFileType + open let type: FBFileType + + /** + Initialize an FBFile object with a filePath + + - parameter filePath: NSURL filePath + + - returns: FBFile object. + */ + init(filePath: URL) { + self.filePath = filePath + let isDirectory = checkDirectory(filePath) + self.isDirectory = isDirectory + if self.isDirectory { + self.fileAttributes = nil + self.fileExtension = nil + self.type = .Directory + } + else { + self.fileAttributes = getFileAttributes(self.filePath) + self.fileExtension = filePath.pathExtension + if let fileExtension = fileExtension { + self.type = FBFileType(rawValue: fileExtension) ?? .Default + } + else { + self.type = .Default + } + } + self.displayName = filePath.lastPathComponent + } +} + +/** + FBFile type + */ +public enum FBFileType: String { + /// Directory + case Directory = "directory" + /// GIF file + case GIF = "gif" + /// JPG file + case JPG = "jpg" + /// PLIST file + case JSON = "json" + /// PDF file + case PDF = "pdf" + /// PLIST file + case PLIST = "plist" + /// PNG file + case PNG = "png" + /// ZIP file + case ZIP = "zip" + /// Any file + case Default = "file" + + /** + Get representative image for file type + + - returns: UIImage for file type + */ + public func image() -> UIImage? { + let bundle = Bundle(for: FileParser.self) + var fileName = String() + switch self { + case .Directory: fileName = "folder@2x.png" + case .JPG, .PNG, .GIF: fileName = "image@2x.png" + case .PDF: fileName = "pdf@2x.png" + case .ZIP: fileName = "zip@2x.png" + default: fileName = "file@2x.png" + } + let file = UIImage(named: fileName, in: bundle, compatibleWith: nil) + return file + } +} + +/** + Check if file path NSURL is directory or file. + + - parameter filePath: NSURL file path. + + - returns: isDirectory Bool. + */ +func checkDirectory(_ filePath: URL) -> Bool { + var isDirectory = false + do { + var resourceValue: AnyObject? + try (filePath as NSURL).getResourceValue(&resourceValue, forKey: URLResourceKey.isDirectoryKey) + if let number = resourceValue as? NSNumber , number == true { + isDirectory = true + } + } + catch { } + return isDirectory +} + +func getFileAttributes(_ filePath: URL) -> NSDictionary? { + let path = filePath.path + let fileManager = FileParser.sharedInstance.fileManager + do { + let attributes = try fileManager.attributesOfItem(atPath: path) as NSDictionary + return attributes + } catch {} + return nil +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/FileBrowser.h b/Carthage/Checkouts/FileBrowser/FileBrowser/FileBrowser.h new file mode 100644 index 0000000..9831390 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/FileBrowser.h @@ -0,0 +1,19 @@ +// +// FileBrowser.h +// FileBrowser +// +// Created by Roy Marmelstein on 07/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +#import + +//! Project version number for FileBrowser. +FOUNDATION_EXPORT double FileBrowserVersionNumber; + +//! Project version string for FileBrowser. +FOUNDATION_EXPORT const unsigned char FileBrowserVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/FileBrowser.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/FileBrowser.swift new file mode 100644 index 0000000..340183f --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/FileBrowser.swift @@ -0,0 +1,64 @@ +// +// FileBrowser.swift +// FileBrowser +// +// Created by Roy Marmelstein on 14/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import Foundation + +/// File browser containing navigation controller. +open class FileBrowser: UINavigationController { + + let parser = FileParser.sharedInstance + + var fileList: FileListViewController? + + /// File types to exclude from the file browser. + open var excludesFileExtensions: [String]? { + didSet { + parser.excludesFileExtensions = excludesFileExtensions + } + } + + /// File paths to exclude from the file browser. + open var excludesFilepaths: [URL]? { + didSet { + parser.excludesFilepaths = excludesFilepaths + } + } + + /// Override default preview and actionsheet behaviour in favour of custom file handling. + open var didSelectFile: ((FBFile) -> ())? { + didSet { + fileList?.didSelectFile = didSelectFile + } + } + + /** + Init to documents folder. + + - returns: File browser view controller. + */ + public convenience init() { + let parser = FileParser.sharedInstance + let path = parser.documentsURL() + self.init(initialPath: path as URL) + } + + /** + Init to a custom directory path. + + - parameter initialPath: NSURL filepath to containing directory. + + - returns: File browser view controller. + */ + public convenience init(initialPath: URL) { + let fileListViewController = FileListViewController(initialPath: initialPath) + self.init(rootViewController: fileListViewController) + self.view.backgroundColor = UIColor.white + self.fileList = fileListViewController + } + +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/FileListPreview.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/FileListPreview.swift new file mode 100644 index 0000000..240413d --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/FileListPreview.swift @@ -0,0 +1,48 @@ +// +// FileListPreview.swift +// FileBrowser +// +// Created by Roy Marmelstein on 13/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import Foundation +import QuickLook + +extension FileListViewController: UIViewControllerPreviewingDelegate { + + //MARK: UIViewControllerPreviewingDelegate + + func registerFor3DTouch() { + if #available(iOS 9.0, *) { + if self.traitCollection.forceTouchCapability == UIForceTouchCapability.available { + registerForPreviewing(with: self, sourceView: tableView) + } + } + } + + func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { + if #available(iOS 9.0, *) { + if let indexPath = tableView.indexPathForRow(at: location) { + let selectedFile = fileForIndexPath(indexPath) + previewingContext.sourceRect = tableView.rectForRow(at: indexPath) + if selectedFile.isDirectory == false { + return previewManager.previewViewControllerForFile(selectedFile, fromNavigation: false) + } + } + } + return nil + } + + func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) { + if let previewTransitionViewController = viewControllerToCommit as? PreviewTransitionViewController { + self.navigationController?.pushViewController(previewTransitionViewController.quickLookPreviewController, animated: true) + } + else { + self.navigationController?.pushViewController(viewControllerToCommit, animated: true) + } + + } + +} + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/FileListSearch.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/FileListSearch.swift new file mode 100644 index 0000000..ede8f3a --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/FileListSearch.swift @@ -0,0 +1,31 @@ +// +// FileListSearch.swift +// FileBrowser +// +// Created by Roy Marmelstein on 14/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import Foundation + +extension FileListViewController: UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating { + + // MARK: UISearchControllerDelegate + func willPresentSearchController(_ searchController: UISearchController) { + self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) + } + + func willDismissSearchController(_ searchController: UISearchController) { + self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0) + } + + // MARK: UISearchBarDelegate + func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { + filterContentForSearchText(searchBar.text!) + } + + // MARK: UISearchResultsUpdating + func updateSearchResults(for searchController: UISearchController) { + filterContentForSearchText(searchController.searchBar.text!) + } +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/FileListTableView.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/FileListTableView.swift new file mode 100644 index 0000000..bb2a290 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/FileListTableView.swift @@ -0,0 +1,90 @@ +// +// FlieListTableView.swift +// FileBrowser +// +// Created by Roy Marmelstein on 14/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import Foundation + +extension FileListViewController: UITableViewDataSource, UITableViewDelegate { + + //MARK: UITableViewDataSource, UITableViewDelegate + + func numberOfSections(in tableView: UITableView) -> Int { + if searchController.isActive { + return 1 + } + return sections.count + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if searchController.isActive { + return filteredFiles.count + } + return sections[section].count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cellIdentifier = "FileCell" + var cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier) + if let reuseCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) { + cell = reuseCell + } + cell.selectionStyle = .blue + let selectedFile = fileForIndexPath(indexPath) + cell.textLabel?.text = selectedFile.displayName + cell.imageView?.image = selectedFile.type.image() + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let selectedFile = fileForIndexPath(indexPath) + searchController.isActive = false + if selectedFile.isDirectory { + let fileListViewController = FileListViewController(initialPath: selectedFile.filePath) + fileListViewController.didSelectFile = didSelectFile + self.navigationController?.pushViewController(fileListViewController, animated: true) + } + else { + if let didSelectFile = didSelectFile { + self.dismiss() + didSelectFile(selectedFile) + } + else { + let filePreview = previewManager.previewViewControllerForFile(selectedFile, fromNavigation: true) + self.navigationController?.pushViewController(filePreview, animated: true) + } + } + tableView.deselectRow(at: indexPath, animated: true) + } + + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + if searchController.isActive { + return nil + } + if sections[section].count > 0 { + return collation.sectionTitles[section] + } + else { + return nil + } + } + + func sectionIndexTitles(for tableView: UITableView) -> [String]? { + if searchController.isActive { + return nil + } + return collation.sectionIndexTitles + } + + func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int { + if searchController.isActive { + return 0 + } + return collation.section(forSectionIndexTitle: index) + } + + +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/FileListViewController.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/FileListViewController.swift new file mode 100644 index 0000000..b898c5e --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/FileListViewController.swift @@ -0,0 +1,128 @@ +// +// FileListViewController.swift +// FileBrowser +// +// Created by Roy Marmelstein on 12/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import Foundation + +class FileListViewController: UIViewController { + + // TableView + @IBOutlet weak var tableView: UITableView! + let collation = UILocalizedIndexedCollation.current() + + /// Data + var didSelectFile: ((FBFile) -> ())? + var files = [FBFile]() + var initialPath: URL? + let parser = FileParser.sharedInstance + let previewManager = PreviewManager() + var sections: [[FBFile]] = [] + + // Search controller + var filteredFiles = [FBFile]() + let searchController: UISearchController = { + let searchController = UISearchController(searchResultsController: nil) + searchController.searchBar.searchBarStyle = .minimal + searchController.searchBar.backgroundColor = UIColor.white + searchController.dimsBackgroundDuringPresentation = false + return searchController + }() + + + //MARK: Lifecycle + + convenience init (initialPath: URL) { + self.init(nibName: "FileBrowser", bundle: Bundle(for: FileListViewController.self)) + self.edgesForExtendedLayout = UIRectEdge() + + // Set initial path + self.initialPath = initialPath + self.title = initialPath.lastPathComponent + + // Set search controller delegates + searchController.searchResultsUpdater = self + searchController.searchBar.delegate = self + searchController.delegate = self + + // Add dismiss button + let dismissButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(FileListViewController.dismiss(button:))) + self.navigationItem.rightBarButtonItem = dismissButton + + } + + deinit{ + if #available(iOS 9.0, *) { + searchController.loadViewIfNeeded() + } else { + searchController.loadView() + } + } + + //MARK: UIViewController + + override func viewDidLoad() { + + // Prepare data + if let initialPath = initialPath { + files = parser.filesForDirectory(initialPath) + indexFiles() + } + + // Set search bar + tableView.tableHeaderView = searchController.searchBar + + // Register for 3D touch + self.registerFor3DTouch() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + // Scroll to hide search bar + self.tableView.contentOffset = CGPoint(x: 0, y: searchController.searchBar.frame.size.height) + + // Make sure navigation bar is visible + self.navigationController?.isNavigationBarHidden = false + } + + @objc func dismiss(button: UIBarButtonItem = UIBarButtonItem()) { + self.dismiss(animated: true, completion: nil) + } + + //MARK: Data + + func indexFiles() { + let selector: Selector = #selector(getter: UIPrinter.displayName) + sections = Array(repeating: [], count: collation.sectionTitles.count) + if let sortedObjects = collation.sortedArray(from: files, collationStringSelector: selector) as? [FBFile]{ + for object in sortedObjects { + let sectionNumber = collation.section(for: object, collationStringSelector: selector) + sections[sectionNumber].append(object) + } + } + } + + func fileForIndexPath(_ indexPath: IndexPath) -> FBFile { + var file: FBFile + if searchController.isActive { + file = filteredFiles[(indexPath as NSIndexPath).row] + } + else { + file = sections[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).row] + } + return file + } + + func filterContentForSearchText(_ searchText: String) { + filteredFiles = files.filter({ (file: FBFile) -> Bool in + return file.displayName.lowercased().contains(searchText.lowercased()) + }) + tableView.reloadData() + } + +} + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/FileParser.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/FileParser.swift new file mode 100644 index 0000000..c0e364f --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/FileParser.swift @@ -0,0 +1,64 @@ +// +// FileParser.swift +// FileBrowser +// +// Created by Roy Marmelstein on 13/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import Foundation + +class FileParser { + + static let sharedInstance = FileParser() + + var _excludesFileExtensions = [String]() + + /// Mapped for case insensitivity + var excludesFileExtensions: [String]? { + get { + return _excludesFileExtensions.map({$0.lowercased()}) + } + set { + if let newValue = newValue { + _excludesFileExtensions = newValue + } + } + } + + var excludesFilepaths: [URL]? + + let fileManager = FileManager.default + + func documentsURL() -> URL { + return fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL + } + + func filesForDirectory(_ directoryPath: URL) -> [FBFile] { + var files = [FBFile]() + var filePaths = [URL]() + // Get contents + do { + filePaths = try self.fileManager.contentsOfDirectory(at: directoryPath, includingPropertiesForKeys: [], options: [.skipsHiddenFiles]) + } catch { + return files + } + // Parse + for filePath in filePaths { + let file = FBFile(filePath: filePath) + if let excludesFileExtensions = excludesFileExtensions, let fileExtensions = file.fileExtension , excludesFileExtensions.contains(fileExtensions) { + continue + } + if let excludesFilepaths = excludesFilepaths , excludesFilepaths.contains(file.filePath) { + continue + } + if file.displayName.isEmpty == false { + files.append(file) + } + } + // Sort + files = files.sorted(){$0.displayName < $1.displayName} + return files + } + +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Info.plist b/Carthage/Checkouts/FileBrowser/FileBrowser/Info.plist new file mode 100644 index 0000000..96c5e0b --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.2.0 + CFBundleSignature + ???? + CFBundleVersion + 6 + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/PreviewManager.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/PreviewManager.swift new file mode 100644 index 0000000..672283b --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/PreviewManager.swift @@ -0,0 +1,65 @@ +// +// PreviewManager.swift +// FileBrowser +// +// Created by Roy Marmelstein on 16/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import Foundation +import QuickLook + +class PreviewManager: NSObject, QLPreviewControllerDataSource { + + var filePath: URL? + + func previewViewControllerForFile(_ file: FBFile, fromNavigation: Bool) -> UIViewController { + + if file.type == .PLIST || file.type == .JSON{ + let webviewPreviewViewContoller = WebviewPreviewViewContoller(nibName: "WebviewPreviewViewContoller", bundle: Bundle(for: WebviewPreviewViewContoller.self)) + webviewPreviewViewContoller.file = file + return webviewPreviewViewContoller + } + else { + let previewTransitionViewController = PreviewTransitionViewController(nibName: "PreviewTransitionViewController", bundle: Bundle(for: PreviewTransitionViewController.self)) + previewTransitionViewController.quickLookPreviewController.dataSource = self + + self.filePath = file.filePath as URL + if fromNavigation == true { + return previewTransitionViewController.quickLookPreviewController + } + return previewTransitionViewController + } + } + + + func numberOfPreviewItems(in controller: QLPreviewController) -> Int { + return 1 + } + + func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem { + let item = PreviewItem() + if let filePath = filePath { + item.filePath = filePath + } + return item + } + +} + +class PreviewItem: NSObject, QLPreviewItem { + + /*! + * @abstract The URL of the item to preview. + * @discussion The URL must be a file URL. + */ + + var filePath: URL? + public var previewItemURL: URL? { + if let filePath = filePath { + return filePath + } + return nil + } + +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/PreviewTransitionViewController.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/PreviewTransitionViewController.swift new file mode 100644 index 0000000..a2c5e28 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/PreviewTransitionViewController.swift @@ -0,0 +1,27 @@ +// +// PreviewTransitionViewController.swift +// FileBrowser +// +// Created by Roy Marmelstein on 16/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import UIKit +import QuickLook + +/// Preview Transition View Controller was created because of a bug in QLPreviewController. It seems that QLPreviewController has issues being presented from a 3D touch peek-pop gesture and is produced an unbalanced presentation warning. By wrapping it in a container, we are solving this issue. +class PreviewTransitionViewController: UIViewController { + + @IBOutlet weak var containerView: UIView! + + let quickLookPreviewController = QLPreviewController() + + override func viewDidLoad() { + super.viewDidLoad() + self.addChildViewController(quickLookPreviewController) + containerView.addSubview(quickLookPreviewController.view) + quickLookPreviewController.view.frame = containerView.bounds + quickLookPreviewController.didMove(toParentViewController: self) + } + +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/FileBrowser.xib b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/FileBrowser.xib new file mode 100644 index 0000000..8a78feb --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/FileBrowser.xib @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/PreviewTransitionViewController.xib b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/PreviewTransitionViewController.xib new file mode 100644 index 0000000..4771e6b --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/PreviewTransitionViewController.xib @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/WebviewPreviewViewContoller.xib b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/WebviewPreviewViewContoller.xib new file mode 100644 index 0000000..24a9969 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/WebviewPreviewViewContoller.xib @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/documents@2x.png b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/documents@2x.png new file mode 100644 index 0000000..26cea39 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/documents@2x.png differ diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/file@2x.png b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/file@2x.png new file mode 100644 index 0000000..7f43e53 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/file@2x.png differ diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/folder@2x.png b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/folder@2x.png new file mode 100644 index 0000000..bd55edf Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/folder@2x.png differ diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/image@2x.png b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/image@2x.png new file mode 100644 index 0000000..bc0bc32 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/image@2x.png differ diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/pdf@2x.png b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/pdf@2x.png new file mode 100644 index 0000000..7cebc92 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/pdf@2x.png differ diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/zip@2x.png b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/zip@2x.png new file mode 100644 index 0000000..27fe4e9 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/FileBrowser/Resources/zip@2x.png differ diff --git a/Carthage/Checkouts/FileBrowser/FileBrowser/WebviewPreviewViewContoller.swift b/Carthage/Checkouts/FileBrowser/FileBrowser/WebviewPreviewViewContoller.swift new file mode 100644 index 0000000..0c89067 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowser/WebviewPreviewViewContoller.swift @@ -0,0 +1,115 @@ +// +// WebviewPreviewViewContoller.swift +// FileBrowser +// +// Created by Roy Marmelstein on 16/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import UIKit +import WebKit + +/// Webview for rendering items QuickLook will struggle with. +class WebviewPreviewViewContoller: UIViewController { + + var webView = WKWebView() + + var file: FBFile? { + didSet { + self.title = file?.displayName + self.processForDisplay() + } + } + + //MARK: Lifecycle + + override func viewDidLoad() { + super.viewDidLoad() + self.view.addSubview(webView) + + // Add share button + let shareButton = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(WebviewPreviewViewContoller.shareFile)) + self.navigationItem.rightBarButtonItem = shareButton + } + + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + webView.frame = self.view.bounds + } + + //MARK: Share + + func shareFile() { + guard let file = file else { + return + } + let activityViewController = UIActivityViewController(activityItems: [file.filePath], applicationActivities: nil) + self.present(activityViewController, animated: true, completion: nil) + + } + + //MARK: Processing + + func processForDisplay() { + guard let file = file, let data = try? Data(contentsOf: file.filePath as URL) else { + return + } + var rawString: String? + + // Prepare plist for display + if file.type == .PLIST { + do { + if let plistDescription = try (PropertyListSerialization.propertyList(from: data, options: [], format: nil) as AnyObject).description { + rawString = plistDescription + } + } catch {} + } + + // Prepare json file for display + else if file.type == .JSON { + do { + let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) + if JSONSerialization.isValidJSONObject(jsonObject) { + let prettyJSON = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) + var jsonString = String(data: prettyJSON, encoding: String.Encoding.utf8) + // Unescape forward slashes + jsonString = jsonString?.replacingOccurrences(of: "\\/", with: "/") + rawString = jsonString + } + } catch {} + } + + // Default prepare for display + if rawString == nil { + rawString = String(data: data, encoding: String.Encoding.utf8) + } + + // Convert and display string + if let convertedString = convertSpecialCharacters(rawString) { + let htmlString = "
\(convertedString)
" + webView.loadHTMLString(htmlString, baseURL: nil) + } + + } + + + // Make sure we convert HTML special characters + // Code from https://gist.github.com/mikesteele/70ae98d04fdc35cb1d5f + func convertSpecialCharacters(_ string: String?) -> String? { + guard let string = string else { + return nil + } + var newString = string + let char_dictionary = [ + "&": "&", + "<": "<", + ">": ">", + """: "\"", + "'": "'" + ]; + for (escaped_char, unescaped_char) in char_dictionary { + newString = newString.replacingOccurrences(of: escaped_char, with: unescaped_char, options: NSString.CompareOptions.regularExpression, range: nil) + } + return newString + } +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowserTests/3crBXeO.gif b/Carthage/Checkouts/FileBrowser/FileBrowserTests/3crBXeO.gif new file mode 100644 index 0000000..0c7d073 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/FileBrowserTests/3crBXeO.gif differ diff --git a/Carthage/Checkouts/FileBrowser/FileBrowserTests/FileBrowserTests.swift b/Carthage/Checkouts/FileBrowser/FileBrowserTests/FileBrowserTests.swift new file mode 100644 index 0000000..286b019 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowserTests/FileBrowserTests.swift @@ -0,0 +1,73 @@ +// +// FileBrowserTests.swift +// FileBrowserTests +// +// Created by Roy Marmelstein on 07/02/2016. +// Copyright © 2016 Roy Marmelstein. All rights reserved. +// + +import XCTest +@testable import FileBrowser + +class FileBrowserTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testGifFBFileParse() { + let filePath = Bundle(for: FileBrowserTests.self).url(forResource: "3crBXeO", withExtension: "gif")! + let file = FBFile(filePath: filePath) + XCTAssertEqual(file.filePath, filePath) + XCTAssertEqual(file.isDirectory, false) + XCTAssertEqual(file.type, FBFileType.GIF) + XCTAssertEqual(file.fileExtension, "gif") + } + + func testJpgFBFileParse() { + let filePath = Bundle(for: FileBrowserTests.self).url(forResource: "Stitch", withExtension: "jpg")! + let file = FBFile(filePath: filePath) + XCTAssertEqual(file.filePath, filePath) + XCTAssertEqual(file.isDirectory, false) + XCTAssertEqual(file.type, FBFileType.JPG) + XCTAssertEqual(file.fileExtension, "jpg") + } + + func testDirectoryFBFileParse() { + let filePath = Bundle(for: FileBrowserTests.self).bundleURL + let file = FBFile(filePath: filePath) + XCTAssertEqual(file.type, FBFileType.Directory) + } + + func testDirectoryContentsParse() { + let parser = FileParser.sharedInstance + let directoryPath = Bundle(for: FileBrowserTests.self).bundleURL + let directoryContents = parser.filesForDirectory(directoryPath) + XCTAssertTrue(directoryContents.count > 0) + let stitchFile = directoryContents.filter({$0.displayName == "Stitch.jpg"}).first + XCTAssertNotNil(stitchFile) + if let stitchFile = stitchFile { + XCTAssertEqual(stitchFile.type, FBFileType.JPG) + } + } + + func testCaseSensitiveExclusion() { + let parser = FileParser.sharedInstance + parser.excludesFileExtensions = ["gIf"] + let directoryPath = Bundle(for: FileBrowserTests.self).bundleURL + let directoryContents = parser.filesForDirectory(directoryPath) + for file in directoryContents { + if let fileExtension = file.fileExtension { + XCTAssertFalse(fileExtension == "gif") + } + } + } + + +} diff --git a/Carthage/Checkouts/FileBrowser/FileBrowserTests/Info.plist b/Carthage/Checkouts/FileBrowser/FileBrowserTests/Info.plist new file mode 100644 index 0000000..a7f3874 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowserTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 0.2.0 + CFBundleSignature + ???? + CFBundleVersion + 6 + + diff --git a/Carthage/Checkouts/FileBrowser/FileBrowserTests/Stitch.jpg b/Carthage/Checkouts/FileBrowser/FileBrowserTests/Stitch.jpg new file mode 100644 index 0000000..08fa643 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/FileBrowserTests/Stitch.jpg differ diff --git a/Carthage/Checkouts/FileBrowser/FileBrowserWorkspace.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/FileBrowser/FileBrowserWorkspace.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..877319b --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/FileBrowserWorkspace.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/FileBrowser/Gemfile b/Carthage/Checkouts/FileBrowser/Gemfile new file mode 100644 index 0000000..d2e8888 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'cocoapods', '1.1.0.rc.1' diff --git a/Carthage/Checkouts/FileBrowser/Gemfile.lock b/Carthage/Checkouts/FileBrowser/Gemfile.lock new file mode 100644 index 0000000..f279a83 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/Gemfile.lock @@ -0,0 +1,69 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (4.2.7.1) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + claide (1.0.0) + cocoapods (1.1.0.rc.1) + activesupport (>= 4.0.2, < 5) + claide (>= 1.0.0, < 2.0) + cocoapods-core (= 1.1.0.rc.1) + cocoapods-deintegrate (>= 1.0.1, < 2.0) + cocoapods-downloader (>= 1.1.1, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-stats (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.0.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored (~> 1.2) + escape (~> 0.0.4) + fourflusher (~> 1.0.1) + gh_inspector (~> 1.0) + molinillo (~> 0.5.0) + nap (~> 1.0) + xcodeproj (>= 1.3.1, < 2.0) + cocoapods-core (1.1.0.rc.1) + activesupport (>= 4.0.2, < 5) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + cocoapods-deintegrate (1.0.1) + cocoapods-downloader (1.1.1) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.0) + cocoapods-stats (1.0.0) + cocoapods-trunk (1.0.0) + nap (>= 0.8, < 2.0) + netrc (= 0.7.8) + cocoapods-try (1.1.0) + colored (1.2) + escape (0.0.4) + fourflusher (1.0.1) + fuzzy_match (2.0.4) + gh_inspector (1.0.2) + i18n (0.7.0) + json (1.8.3) + minitest (5.9.0) + molinillo (0.5.0) + nap (1.1.0) + netrc (0.7.8) + thread_safe (0.3.5) + tzinfo (1.2.2) + thread_safe (~> 0.1) + xcodeproj (1.3.1) + activesupport (>= 3) + claide (>= 1.0.0, < 2.0) + colored (~> 1.2) + +PLATFORMS + ruby + +DEPENDENCIES + cocoapods (= 1.1.0.rc.1) + +BUNDLED WITH + 1.12.5 diff --git a/Carthage/Checkouts/FileBrowser/LICENSE b/Carthage/Checkouts/FileBrowser/LICENSE new file mode 100644 index 0000000..52e2df0 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Roy Marmelstein + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/FileBrowser/README.md b/Carthage/Checkouts/FileBrowser/README.md new file mode 100644 index 0000000..4aa7e7e --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/README.md @@ -0,0 +1,80 @@ +![FileBrowser - iOS Finder-style file browser in Swift](https://cloud.githubusercontent.com/assets/889949/13035402/75e4eb00-d34f-11e5-8b92-c921ecca9300.png) + +[![Build Status](https://travis-ci.org/marmelroy/FileBrowser.svg?branch=master)](https://travis-ci.org/marmelroy/FileBrowser) [![Version](http://img.shields.io/cocoapods/v/FileBrowser.svg)](http://cocoapods.org/?q=FileBrowser) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) + +# FileBrowser +iOS Finder-style file browser in Swift with search, file previews and 3D touch. Simple and quick to use. + +

+ +## Features + + + | Features +--------------------------|------------------------------------------------------------ +:iphone: | Browse and select files and folders with a familiar UI on iOS. +:mag: | Pull down to search. +:eyeglasses: | Preview most file types. Including plist and json. +:point_up_2: | 3D touch support for faster previews with Peek & Pop. +:white_flower: | Fully customizable. + + +## Usage + +Import FileBrowser at the top of the Swift file. + +```swift +import FileBrowser +``` + +To show the file browser, all you need to do is: +```swift +let fileBrowser = FileBrowser() +present(file, animated: true, completion: nil) +``` + +By default, the file browser will open in your app's documents directory. When users select a file, a preview will be displayed - offering an action sheet of options based on the file type. + +## Advanced Usage + +You can open FileBrowser in a different root folder by initialising with an NSURL file path of your choice. +```swift +let fileBrowser = FileBrowser(initialPath: customPath) +``` + +Use the didSelectFile closure to change FileBrowser's behaviour when a file is selected. +```swift +fileBrowser.didSelectFile = { (file: FBFile) -> Void in + print(file.displayName) +} +``` + +To exclude a certain file type or a specific file path: +```swift +fileBrowser.excludesFileExtensions = ["zip"] +fileBrowser.excludesFilepaths = [secretFile] +``` + +### Setting up with [CocoaPods](http://cocoapods.org/?q=FileBrowser) +```ruby +source 'https://github.com/CocoaPods/Specs.git' +pod 'FileBrowser', '~> 0.2' +``` + +### Setting up with Carthage + +[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application. + +You can install Carthage with [Homebrew](http://brew.sh/) using the following command: + +```bash +$ brew update +$ brew install carthage +``` + +To integrate FileBrowser into your Xcode project using Carthage, specify it in your `Cartfile`: + +```ogdl +github "marmelroy/FileBrowser" +``` diff --git a/Carthage/Checkouts/FileBrowser/build.sh b/Carthage/Checkouts/FileBrowser/build.sh new file mode 100755 index 0000000..0a27da6 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/build.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# **** Update me when new Xcode versions are released! **** +PLATFORM="platform=iOS Simulator,OS=10.0,name=iPhone 7" +SDK="iphonesimulator10.0" + + +# It is pitch black. +set -e +function trap_handler() { + echo -e "\n\nOh no! You walked directly into the slavering fangs of a lurking grue!" + echo "**** You have died ****" + exit 255 +} +trap trap_handler INT TERM EXIT + + +MODE="$1" + +if [ "$MODE" = "framework" ]; then + echo "Building and testing FileBrowser." + xcodebuild \ + -project FileBrowser.xcodeproj \ + -scheme FileBrowser \ + -sdk "$SDK" \ + -destination "$PLATFORM" \ + build test + trap - EXIT + exit 0 +fi + +if [ "$MODE" = "examples" ]; then + echo "Building and testing all FileBrowser examples." + + for example in examples/*/; do + echo "Building $example." + pod install --project-directory=$example + xcodebuild \ + -workspace "${example}Sample.xcworkspace" \ + -scheme Sample \ + -sdk "$SDK" \ + -destination "$PLATFORM" \ + build test + done + trap - EXIT + exit 0 +fi + +echo "Unrecognised mode '$MODE'." diff --git a/Carthage/Checkouts/FileBrowser/examples/README.md b/Carthage/Checkouts/FileBrowser/examples/README.md new file mode 100644 index 0000000..3c01ad6 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/README.md @@ -0,0 +1,6 @@ +# Sample projects + +## Building + +Run `pod install` in each sample project directory to set up their +dependencies. diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Podfile b/Carthage/Checkouts/FileBrowser/examples/Sample/Podfile new file mode 100644 index 0000000..c42d04e --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/Sample/Podfile @@ -0,0 +1,7 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, "8.0" +use_frameworks! + +target 'Sample' do + pod 'FileBrowser', :path => '../..' +end diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample.xcodeproj/project.pbxproj b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..87a3b67 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample.xcodeproj/project.pbxproj @@ -0,0 +1,384 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 48A199B61D8C53AC00C443D3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 48A199B41D8C53AC00C443D3 /* Main.storyboard */; }; + 48A199B81D8C53AC00C443D3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 48A199B71D8C53AC00C443D3 /* Assets.xcassets */; }; + 48A199BB1D8C53AC00C443D3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 48A199B91D8C53AC00C443D3 /* LaunchScreen.storyboard */; }; + 48A199C51D8C53DB00C443D3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48A199C31D8C53DB00C443D3 /* AppDelegate.swift */; }; + 48A199C81D8C53E200C443D3 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48A199C71D8C53E200C443D3 /* MainViewController.swift */; }; + 48A199CD1D8C546000C443D3 /* Baymax.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 48A199C91D8C546000C443D3 /* Baymax.jpg */; }; + 48A199CE1D8C546000C443D3 /* BB8.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 48A199CA1D8C546000C443D3 /* BB8.jpg */; }; + 48A199CF1D8C546000C443D3 /* Images.zip in Resources */ = {isa = PBXBuildFile; fileRef = 48A199CB1D8C546000C443D3 /* Images.zip */; }; + 48A199D01D8C546000C443D3 /* Stitch.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 48A199CC1D8C546000C443D3 /* Stitch.jpg */; }; + 48A24C331D8C59250044C697 /* FileBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48A24C321D8C59250044C697 /* FileBrowser.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 48A199DD1D8C564100C443D3 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 48A199AD1D8C53AC00C443D3 /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 48A199B51D8C53AC00C443D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 48A199B71D8C53AC00C443D3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 48A199BA1D8C53AC00C443D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 48A199C31D8C53DB00C443D3 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = "Supporting Files/AppDelegate.swift"; sourceTree = ""; }; + 48A199C41D8C53DB00C443D3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = "Supporting Files/Info.plist"; sourceTree = ""; }; + 48A199C71D8C53E200C443D3 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MainViewController.swift; path = "View Controller/MainViewController.swift"; sourceTree = ""; }; + 48A199C91D8C546000C443D3 /* Baymax.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = Baymax.jpg; sourceTree = ""; }; + 48A199CA1D8C546000C443D3 /* BB8.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = BB8.jpg; sourceTree = ""; }; + 48A199CB1D8C546000C443D3 /* Images.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Images.zip; sourceTree = ""; }; + 48A199CC1D8C546000C443D3 /* Stitch.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = Stitch.jpg; sourceTree = ""; }; + 48A24C321D8C59250044C697 /* FileBrowser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FileBrowser.framework; path = "../../../../Library/Developer/Xcode/DerivedData/FileBrowserWorkspace-gvwbufuzyigeyaecovnmsyswnfyi/Build/Products/Debug-iphoneos/FileBrowser.framework"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 48A199AA1D8C53AC00C443D3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 48A24C331D8C59250044C697 /* FileBrowser.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 48A199A41D8C53AC00C443D3 = { + isa = PBXGroup; + children = ( + 48A199AF1D8C53AC00C443D3 /* Sample */, + 48A199AE1D8C53AC00C443D3 /* Products */, + 48A24C2F1D8C57390044C697 /* Frameworks */, + ); + sourceTree = ""; + }; + 48A199AE1D8C53AC00C443D3 /* Products */ = { + isa = PBXGroup; + children = ( + 48A199AD1D8C53AC00C443D3 /* Sample.app */, + ); + name = Products; + sourceTree = ""; + }; + 48A199AF1D8C53AC00C443D3 /* Sample */ = { + isa = PBXGroup; + children = ( + 48A199D21D8C546F00C443D3 /* View Controller */, + 48A199C21D8C53B700C443D3 /* Supporting Files */, + ); + path = Sample; + sourceTree = ""; + }; + 48A199C21D8C53B700C443D3 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 48A199D11D8C546500C443D3 /* Resources */, + 48A199C31D8C53DB00C443D3 /* AppDelegate.swift */, + 48A199C41D8C53DB00C443D3 /* Info.plist */, + 48A199B41D8C53AC00C443D3 /* Main.storyboard */, + 48A199B71D8C53AC00C443D3 /* Assets.xcassets */, + 48A199B91D8C53AC00C443D3 /* LaunchScreen.storyboard */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 48A199D11D8C546500C443D3 /* Resources */ = { + isa = PBXGroup; + children = ( + 48A199C91D8C546000C443D3 /* Baymax.jpg */, + 48A199CA1D8C546000C443D3 /* BB8.jpg */, + 48A199CB1D8C546000C443D3 /* Images.zip */, + 48A199CC1D8C546000C443D3 /* Stitch.jpg */, + ); + name = Resources; + sourceTree = ""; + }; + 48A199D21D8C546F00C443D3 /* View Controller */ = { + isa = PBXGroup; + children = ( + 48A199C71D8C53E200C443D3 /* MainViewController.swift */, + ); + name = "View Controller"; + sourceTree = ""; + }; + 48A24C2F1D8C57390044C697 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 48A24C321D8C59250044C697 /* FileBrowser.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 48A199AC1D8C53AC00C443D3 /* Sample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 48A199BF1D8C53AC00C443D3 /* Build configuration list for PBXNativeTarget "Sample" */; + buildPhases = ( + 48A199A91D8C53AC00C443D3 /* Sources */, + 48A199AA1D8C53AC00C443D3 /* Frameworks */, + 48A199AB1D8C53AC00C443D3 /* Resources */, + 48A199DD1D8C564100C443D3 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Sample; + productName = Sample; + productReference = 48A199AD1D8C53AC00C443D3 /* Sample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 48A199A51D8C53AC00C443D3 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0800; + LastUpgradeCheck = 0800; + ORGANIZATIONNAME = "Mihail Șalari"; + TargetAttributes = { + 48A199AC1D8C53AC00C443D3 = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = U82TG7992X; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 48A199A81D8C53AC00C443D3 /* Build configuration list for PBXProject "Sample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 48A199A41D8C53AC00C443D3; + productRefGroup = 48A199AE1D8C53AC00C443D3 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 48A199AC1D8C53AC00C443D3 /* Sample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 48A199AB1D8C53AC00C443D3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 48A199BB1D8C53AC00C443D3 /* LaunchScreen.storyboard in Resources */, + 48A199CF1D8C546000C443D3 /* Images.zip in Resources */, + 48A199B81D8C53AC00C443D3 /* Assets.xcassets in Resources */, + 48A199B61D8C53AC00C443D3 /* Main.storyboard in Resources */, + 48A199CD1D8C546000C443D3 /* Baymax.jpg in Resources */, + 48A199D01D8C546000C443D3 /* Stitch.jpg in Resources */, + 48A199CE1D8C546000C443D3 /* BB8.jpg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 48A199A91D8C53AC00C443D3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 48A199C81D8C53E200C443D3 /* MainViewController.swift in Sources */, + 48A199C51D8C53DB00C443D3 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 48A199B41D8C53AC00C443D3 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 48A199B51D8C53AC00C443D3 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 48A199B91D8C53AC00C443D3 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 48A199BA1D8C53AC00C443D3 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 48A199BD1D8C53AC00C443D3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 48A199BE1D8C53AC00C443D3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 48A199C01D8C53AC00C443D3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + DEVELOPMENT_TEAM = U82TG7992X; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = "$(SRCROOT)/Sample/Supporting Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.mihailsalari.Sample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 48A199C11D8C53AC00C443D3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + DEVELOPMENT_TEAM = U82TG7992X; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = "$(SRCROOT)/Sample/Supporting Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.mihailsalari.Sample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 48A199A81D8C53AC00C443D3 /* Build configuration list for PBXProject "Sample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 48A199BD1D8C53AC00C443D3 /* Debug */, + 48A199BE1D8C53AC00C443D3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 48A199BF1D8C53AC00C443D3 /* Build configuration list for PBXNativeTarget "Sample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 48A199C01D8C53AC00C443D3 /* Debug */, + 48A199C11D8C53AC00C443D3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 48A199A51D8C53AC00C443D3 /* Project object */; +} diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..a80c038 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..36d2c80 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/BB8.jpg b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/BB8.jpg new file mode 100644 index 0000000..ecbe8a9 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/BB8.jpg differ diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Base.lproj/LaunchScreen.storyboard b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Base.lproj/Main.storyboard b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Base.lproj/Main.storyboard new file mode 100644 index 0000000..bb4bbb2 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Base.lproj/Main.storyboard @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Baymax.jpg b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Baymax.jpg new file mode 100644 index 0000000..11a5518 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Baymax.jpg differ diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Images.zip b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Images.zip new file mode 100644 index 0000000..4d903fe Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Images.zip differ diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Stitch.jpg b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Stitch.jpg new file mode 100644 index 0000000..08fa643 Binary files /dev/null and b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Stitch.jpg differ diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Supporting Files/AppDelegate.swift b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Supporting Files/AppDelegate.swift new file mode 100644 index 0000000..5be52d3 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Supporting Files/AppDelegate.swift @@ -0,0 +1,87 @@ +// +// AppDelegate.swift +// Sample +// +// Created by Mihail Șalari on 9/16/16. +// Copyright © 2016 Mihail Șalari. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + + self.populateTableViewWithFiles() + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + fileprivate func populateTableViewWithFiles() { + let defaultsKey = "firstLaunch" + let userDefaults = UserDefaults.standard + let fileManager = FileManager.default + let fileNames = ["Baymax.jpg", "BB8.jpg", "Stitch.jpg", "Info.plist"] + let documentsUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0] as URL + let bundleUrl = Bundle.main.resourceURL + + // Copy zip file to an images directory + let imagesDirectoryURL = documentsUrl.appendingPathComponent("images") + let zipFileName = "Images.zip" + let imagesDirectoryPath = imagesDirectoryURL.path + + if userDefaults.bool(forKey: defaultsKey) == false { + userDefaults.set(true, forKey: defaultsKey) + userDefaults.synchronize() + + // Copy images to documents folder + for file in fileNames { + if let srcPath = bundleUrl?.appendingPathComponent(file).path { + let toPath = documentsUrl.appendingPathComponent(file).path + do { + try fileManager.copyItem(atPath: srcPath, toPath: toPath) + } catch {} + } + } + + // Copy zip file to an images directory + do { + try fileManager.createDirectory(atPath: imagesDirectoryPath, withIntermediateDirectories: false, attributes: nil) + if let srcPath = bundleUrl?.appendingPathComponent(zipFileName).path { + let toPath = imagesDirectoryURL.appendingPathComponent(zipFileName).path + do { + try fileManager.copyItem(atPath: srcPath, toPath: toPath) + } catch {} + } + } catch {} + } + } +} + diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Supporting Files/Info.plist b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Supporting Files/Info.plist new file mode 100644 index 0000000..d052473 --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/Supporting Files/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/View Controller/MainViewController.swift b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/View Controller/MainViewController.swift new file mode 100644 index 0000000..c5594fe --- /dev/null +++ b/Carthage/Checkouts/FileBrowser/examples/Sample/Sample/View Controller/MainViewController.swift @@ -0,0 +1,32 @@ +// +// MainViewController.swift +// Sample +// +// Created by Mihail Șalari on 9/16/16. +// Copyright © 2016 Mihail Șalari. All rights reserved. +// + +import UIKit +import FileBrowser + +class MainViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + // MARK: - FileBrowser + + @IBAction func showFileBrowser(sender: AnyObject) { + let file = FileBrowser() + present(file, animated: true, completion: nil) + //self.present(fileBrowser, animated: true, completion: nil) + } +} + diff --git a/Carthage/Checkouts/LeakEye/.gitignore b/Carthage/Checkouts/LeakEye/.gitignore new file mode 100644 index 0000000..1de2633 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/LeakEye/Cartfile b/Carthage/Checkouts/LeakEye/Cartfile new file mode 100644 index 0000000..2ad6ddc --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Cartfile @@ -0,0 +1 @@ +github "zixun/AppSwizzle" >= 1.1.1 \ No newline at end of file diff --git a/Carthage/Checkouts/LeakEye/Cartfile.resolved b/Carthage/Checkouts/LeakEye/Cartfile.resolved new file mode 100644 index 0000000..0633dfa --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Cartfile.resolved @@ -0,0 +1 @@ +github "zixun/AppSwizzle" "1.1.1" diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/.gitignore b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/.gitignore new file mode 100644 index 0000000..1de2633 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle.podspec b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle.podspec new file mode 100644 index 0000000..3c9cd6e --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle.podspec @@ -0,0 +1,33 @@ +# +# Be sure to run `pod lib lint AppSwizzle.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'AppSwizzle' + s.version = '1.1.1' + s.summary = 'lightweight and flexible method swizzling wrapped by swift.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +Lightweight and flexible method swizzling wrapped by swift. enjoy it! + DESC + + s.homepage = 'https://github.com/zixun/AppSwizzle' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { '陈奕龙' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/AppSwizzle.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'AppSwizzle/Classes/**/*' +end diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Assets/.gitkeep b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/.gitkeep b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/AppSwizzle.swift b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/AppSwizzle.swift new file mode 100644 index 0000000..5312665 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/AppSwizzle.swift @@ -0,0 +1,99 @@ +// +// AppSwizzle.swift +// Pods +// +// Created by zixun on 2016/11/27. +// +// + +import Foundation + +import ObjectiveC + +public enum SwizzleResult { + case Succeed + case OriginMethodNotFound + case AlternateMethodNotFound +} + +public extension NSObject { + + public class func swizzleInstanceMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: self.classForCoder(), + isClassMethod: false) + } + + public class func swizzleClassMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: self.classForCoder(), + isClassMethod: true) + } + + + public class func swizzleInstanceMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector, + inAlterClass alterClass: AnyClass) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: alterClass, + isClassMethod: false) + } + + public class func swizzleClassMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector, + inAlterClass alterClass: AnyClass) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: alterClass, + isClassMethod: true) + } + + + private class func swizzleMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector!, + inAlterClass alterClass: AnyClass!, + isClassMethod:Bool) -> SwizzleResult { + + var alterClass = alterClass + var origClass: AnyClass = self.classForCoder() + if isClassMethod { + alterClass = object_getClass(alterClass) + origClass = object_getClass(self.classForCoder()) + } + + return SwizzleMethod(origClass: origClass, origSelector: origSelector, toAlterSelector: alterSelector, inAlterClass: alterClass) + } +} + + +private func SwizzleMethod(origClass:AnyClass!,origSelector: Selector,toAlterSelector alterSelector: Selector!,inAlterClass alterClass: AnyClass!) -> SwizzleResult{ + + guard let origMethod: Method = class_getInstanceMethod(origClass, origSelector) else { + return SwizzleResult.OriginMethodNotFound + } + + guard let altMethod: Method = class_getInstanceMethod(alterClass, alterSelector) else { + return SwizzleResult.AlternateMethodNotFound + } + + + + let didadd = class_addMethod(origClass, + origSelector,method_getImplementation(origMethod), + method_getTypeEncoding(origMethod)) + + + let didadd2 = class_addMethod(alterClass, + alterSelector,method_getImplementation(altMethod), + method_getTypeEncoding(altMethod)) + + method_exchangeImplementations(origMethod, altMethod) + + return SwizzleResult.Succeed + +} diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.pbxproj b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.pbxproj new file mode 100644 index 0000000..976270e --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.pbxproj @@ -0,0 +1,527 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 607FACEC1AFB9204008FA782 /* AppSwizzleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* AppSwizzleTests.swift */; }; + 9E24F9D91E7FB91A001AD0D7 /* AppSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24F9D71E7FB91A001AD0D7 /* AppSwizzle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24F9E01E7FB92D001AD0D7 /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = 9E24F9DE1E7FB92D001AD0D7 /* .gitkeep */; }; + 9E24F9E11E7FB92D001AD0D7 /* AppSwizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9DF1E7FB92D001AD0D7 /* AppSwizzle.swift */; }; + 9EFFB71B24C66DC6A7F031F7 /* Pods_AppSwizzle_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 491CD07646A3DE1A3E69F9D1 /* Pods_AppSwizzle_Tests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2E3BA46813095DB970DC7076 /* Pods-AppSwizzle_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppSwizzle_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests.release.xcconfig"; sourceTree = ""; }; + 491CD07646A3DE1A3E69F9D1 /* Pods_AppSwizzle_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AppSwizzle_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACE51AFB9204008FA782 /* AppSwizzle_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AppSwizzle_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* AppSwizzleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSwizzleTests.swift; sourceTree = ""; }; + 89AFF071BC9E704AA1C37D55 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 9E24F9D51E7FB91A001AD0D7 /* AppSwizzle.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AppSwizzle.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24F9D71E7FB91A001AD0D7 /* AppSwizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppSwizzle.h; sourceTree = ""; }; + 9E24F9D81E7FB91A001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24F9DE1E7FB92D001AD0D7 /* .gitkeep */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + 9E24F9DF1E7FB92D001AD0D7 /* AppSwizzle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppSwizzle.swift; sourceTree = ""; }; + E26F9D2C0E0879A1F36DBA49 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + E2A536F5AEFAB64066837735 /* AppSwizzle.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = AppSwizzle.podspec; path = ../AppSwizzle.podspec; sourceTree = ""; }; + EF9F0C8A4C454C95207FD5A2 /* Pods-AppSwizzle_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppSwizzle_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EFFB71B24C66DC6A7F031F7 /* Pods_AppSwizzle_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9D11E7FB91A001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 148CFF5A86E94370A2FFA6EB /* Frameworks */ = { + isa = PBXGroup; + children = ( + 491CD07646A3DE1A3E69F9D1 /* Pods_AppSwizzle_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24F9D61E7FB91A001AD0D7 /* AppSwizzle */, + 607FACD11AFB9204008FA782 /* Products */, + 95CAC9C1BE74BBFAF93AD32F /* Pods */, + 148CFF5A86E94370A2FFA6EB /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACE51AFB9204008FA782 /* AppSwizzle_Tests.xctest */, + 9E24F9D51E7FB91A001AD0D7 /* AppSwizzle.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* AppSwizzleTests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + E2A536F5AEFAB64066837735 /* AppSwizzle.podspec */, + 89AFF071BC9E704AA1C37D55 /* README.md */, + E26F9D2C0E0879A1F36DBA49 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 95CAC9C1BE74BBFAF93AD32F /* Pods */ = { + isa = PBXGroup; + children = ( + EF9F0C8A4C454C95207FD5A2 /* Pods-AppSwizzle_Tests.debug.xcconfig */, + 2E3BA46813095DB970DC7076 /* Pods-AppSwizzle_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9E24F9D61E7FB91A001AD0D7 /* AppSwizzle */ = { + isa = PBXGroup; + children = ( + 9E24F9DD1E7FB92D001AD0D7 /* Classes */, + 9E24F9D71E7FB91A001AD0D7 /* AppSwizzle.h */, + 9E24F9D81E7FB91A001AD0D7 /* Info.plist */, + ); + path = AppSwizzle; + sourceTree = ""; + }; + 9E24F9DD1E7FB92D001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24F9DE1E7FB92D001AD0D7 /* .gitkeep */, + 9E24F9DF1E7FB92D001AD0D7 /* AppSwizzle.swift */, + ); + name = Classes; + path = ../../AppSwizzle/Classes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24F9D21E7FB91A001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9D91E7FB91A001AD0D7 /* AppSwizzle.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACE41AFB9204008FA782 /* AppSwizzle_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppSwizzle_Tests" */; + buildPhases = ( + 7A1970CC11A178F2524BAA27 /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + C1AA5E9370E2274451F9FA64 /* [CP] Embed Pods Frameworks */, + F92510766834405DBE333382 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppSwizzle_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* AppSwizzle_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24F9D41E7FB91A001AD0D7 /* AppSwizzle */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24F9DC1E7FB91A001AD0D7 /* Build configuration list for PBXNativeTarget "AppSwizzle" */; + buildPhases = ( + 9E24F9D01E7FB91A001AD0D7 /* Sources */, + 9E24F9D11E7FB91A001AD0D7 /* Frameworks */, + 9E24F9D21E7FB91A001AD0D7 /* Headers */, + 9E24F9D31E7FB91A001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppSwizzle; + productName = AppSwizzle; + productReference = 9E24F9D51E7FB91A001AD0D7 /* AppSwizzle.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0800; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24F9D41E7FB91A001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AppSwizzle" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACE41AFB9204008FA782 /* AppSwizzle_Tests */, + 9E24F9D41E7FB91A001AD0D7 /* AppSwizzle */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9D31E7FB91A001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9E01E7FB92D001AD0D7 /* .gitkeep in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 7A1970CC11A178F2524BAA27 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + C1AA5E9370E2274451F9FA64 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F92510766834405DBE333382 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* AppSwizzleTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9D01E7FB91A001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9E11E7FB92D001AD0D7 /* AppSwizzle.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EF9F0C8A4C454C95207FD5A2 /* Pods-AppSwizzle_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2E3BA46813095DB970DC7076 /* Pods-AppSwizzle_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24F9DA1E7FB91A001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AppSwizzle/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AppSwizzle; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24F9DB1E7FB91A001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AppSwizzle/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AppSwizzle; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AppSwizzle" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppSwizzle_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24F9DC1E7FB91A001AD0D7 /* Build configuration list for PBXNativeTarget "AppSwizzle" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24F9DA1E7FB91A001AD0D7 /* Debug */, + 9E24F9DB1E7FB91A001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..79e358c --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/xcshareddata/AppSwizzle.xcscmblueprint b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/xcshareddata/AppSwizzle.xcscmblueprint new file mode 100644 index 0000000..e32fd4c --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/xcshareddata/AppSwizzle.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "0CB12C37-D96F-4E37-99A6-EA1B9BB695B0", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0" : "AppSwizzle\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "AppSwizzle", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/AppSwizzle.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/AppSwizzle.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle-Example.xcscheme b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle-Example.xcscheme new file mode 100644 index 0000000..aae5e32 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle.xcscheme b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle.xcscheme new file mode 100644 index 0000000..233c1b3 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..bbcb77a --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/AppSwizzle.h b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/AppSwizzle.h new file mode 100644 index 0000000..12be6cf --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/AppSwizzle.h @@ -0,0 +1,19 @@ +// +// AppSwizzle.h +// AppSwizzle +// +// Created by zixun on 2017/3/20. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for AppSwizzle. +FOUNDATION_EXPORT double AppSwizzleVersionNumber; + +//! Project version string for AppSwizzle. +FOUNDATION_EXPORT const unsigned char AppSwizzleVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/Info.plist b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Podfile b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Podfile new file mode 100644 index 0000000..ce647a9 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Podfile @@ -0,0 +1,6 @@ +use_frameworks! +target 'AppSwizzle_Tests' do + pod 'AppSwizzle', :path => '../' + + +end diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Podfile.lock b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Podfile.lock new file mode 100644 index 0000000..709afd2 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - AppSwizzle (0.1.0) + +DEPENDENCIES: + - AppSwizzle (from `../`) + +EXTERNAL SOURCES: + AppSwizzle: + :path: "../" + +SPEC CHECKSUMS: + AppSwizzle: eddd38c6429de033e115f66862622723274926a0 + +PODFILE CHECKSUM: 939ed1355ec6a0adef5ae3f3b1e627821b2fc52a + +COCOAPODS: 1.1.1 diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Tests/AppSwizzleTests.swift b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Tests/AppSwizzleTests.swift new file mode 100644 index 0000000..d5aabc7 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Tests/AppSwizzleTests.swift @@ -0,0 +1,96 @@ +import UIKit +import XCTest +import AppSwizzle + +class AppSwizzleTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testSwizzleInstanceMethod() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethod) + let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleInstanceMethod) + AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) + + self.origSelector_testSwizzleInstanceMethod() + } + + func testSwizzleClassMethod() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethod) + let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleClassMethod) + AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter) + + AppSwizzleTests.origSelector_testSwizzleClassMethod() + } + + func testSwizzleInstanceMethodToAlterClass() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethodToAlterClass) + let alter = #selector(OtherClass.alterSelector_testSwizzleInstanceMethodToAlterClass) + AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) + self.origSelector_testSwizzleInstanceMethodToAlterClass() + } + + func testSwizzleClassMethodToAlterClass() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethodToAlterClass) + let alter = #selector(OtherClass.alterSelector_testSwizzleClassMethodToAlterClass) + + AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) + + AppSwizzleTests.origSelector_testSwizzleClassMethodToAlterClass() + } + +} + +//MARK: testSwizzleInstanceMethod extension +extension AppSwizzleTests { + + func origSelector_testSwizzleInstanceMethod() { + XCTFail("Failed") + } + + func alterSelector_testSwizzleInstanceMethod() { + XCTAssert(true, "Pass") + } +} + +//MARK: testSwizzleClassMethod extension +extension AppSwizzleTests { + + class func origSelector_testSwizzleClassMethod() { + XCTFail("Failed") + } + + class func alterSelector_testSwizzleClassMethod() { + XCTAssert(true, "Pass") + } +} + +//MARK: testSwizzleInstanceMethodToAlterClass extension +extension AppSwizzleTests { + func origSelector_testSwizzleInstanceMethodToAlterClass() { + XCTFail("Failed") + } +} + +extension AppSwizzleTests { + class func origSelector_testSwizzleClassMethodToAlterClass() { + XCTFail("Failed") + } +} + + +class OtherClass: NSObject { + + func alterSelector_testSwizzleInstanceMethodToAlterClass() { + XCTAssert(true, "Pass") + } + + class func alterSelector_testSwizzleClassMethodToAlterClass() { + XCTAssert(true, "Pass") + } +} diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Tests/Info.plist b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/LICENSE b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/README.md b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/README.md new file mode 100644 index 0000000..9933d6d --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/README.md @@ -0,0 +1,72 @@ +# AppSwizzle + +[![Swift 3.0+](https://img.shields.io/badge/Swift-3.0%2B-orange.svg)](https://github.com/zixun/AppBaseKit) +[![Platform](https://img.shields.io/badge/Platform-iOS-lightgrey.svg)](https://github.com/zixun/AppBaseKit) +[![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) + +## Context +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly disply Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Example + +To run the example project, clone the repo, and run `pod install` from the Example directory first. + +## Requirements + +## Installation + +AppSwizzle is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "AppSwizzle" +``` +## Usage + +### Swizzle Instance Method + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethod) +let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleInstanceMethod) +AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) +``` + +### Swizzle Class Method + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethod) +let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleClassMethod) +AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter) +``` + +### Swizzle Instance Method To Alter Class + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethodToAlterClass) +let alter = #selector(OtherClass.alterSelector_testSwizzleInstanceMethodToAlterClass) +AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) +``` + +### Swizzle Class Method To Alter Class + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethodToAlterClass) +let alter = #selector(OtherClass.alterSelector_testSwizzleClassMethodToAlterClass) +AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + +## License + +AppSwizzle is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/_Pods.xcodeproj b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Carthage/Checkouts/AppSwizzle/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/project.pbxproj b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/project.pbxproj new file mode 100644 index 0000000..2157d52 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/project.pbxproj @@ -0,0 +1,855 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 5ECE86BAB9C981CA122D038B /* Pods_LeakEye_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 972B21E2412B46D814D1FD2B /* Pods_LeakEye_Example.framework */; }; + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 9E24FA811E81165D001AD0D7 /* LeakEye.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24FA7F1E81165D001AD0D7 /* LeakEye.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FA841E81165D001AD0D7 /* LeakEye.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E24FA7D1E81165D001AD0D7 /* LeakEye.framework */; }; + 9E24FA851E81165D001AD0D7 /* LeakEye.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9E24FA7D1E81165D001AD0D7 /* LeakEye.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9E24FA9D1E81166C001AD0D7 /* ObjectAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA901E81166C001AD0D7 /* ObjectAgent.swift */; }; + 9E24FA9E1E81166C001AD0D7 /* LeakEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA911E81166C001AD0D7 /* LeakEye.swift */; }; + 9E24FA9F1E81166C001AD0D7 /* NSObject+Alive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA931E81166C001AD0D7 /* NSObject+Alive.swift */; }; + 9E24FAA01E81166C001AD0D7 /* NSObject+Eye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA941E81166C001AD0D7 /* NSObject+Eye.swift */; }; + 9E24FAA11E81166C001AD0D7 /* Preparer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA951E81166C001AD0D7 /* Preparer.swift */; }; + 9E24FAA21E81166C001AD0D7 /* NSNotification+LeakEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA961E81166C001AD0D7 /* NSNotification+LeakEye.swift */; }; + 9E24FAA31E81166C001AD0D7 /* DispatchQueue+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA981E81166C001AD0D7 /* DispatchQueue+.swift */; }; + 9E24FAA41E81166C001AD0D7 /* String+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA991E81166C001AD0D7 /* String+.swift */; }; + 9E24FAA51E81166C001AD0D7 /* Variable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA9A1E81166C001AD0D7 /* Variable.swift */; }; + 9E24FAA71E812E54001AD0D7 /* AppSwizzle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E24FAA61E812E54001AD0D7 /* AppSwizzle.framework */; }; + 9E32F5531E102BC8005C7850 /* SecondViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E32F5521E102BC8005C7850 /* SecondViewController.swift */; }; + B92C4D2AE881797F9F839515 /* Pods_LeakEye_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5A031E8773354D107B0FFE4 /* Pods_LeakEye_Tests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = LeakEye; + }; + 9E24FA821E81165D001AD0D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9E24FA7C1E81165D001AD0D7; + remoteInfo = LeakEye; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9E24FA891E81165D001AD0D7 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 9E24FA851E81165D001AD0D7 /* LeakEye.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 0FB1D0765284FEEA825C5038 /* Pods-LeakEye_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeakEye_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LeakEye_Example/Pods-LeakEye_Example.debug.xcconfig"; sourceTree = ""; }; + 155AC52870DD02971EAFBE90 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + 573A2902F825A85A93560459 /* LeakEye.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LeakEye.podspec; path = ../LeakEye.podspec; sourceTree = ""; }; + 607FACD01AFB9204008FA782 /* LeakEye_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LeakEye_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 607FACE51AFB9204008FA782 /* LeakEye_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LeakEye_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + 972B21E2412B46D814D1FD2B /* Pods_LeakEye_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeakEye_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24FA7D1E81165D001AD0D7 /* LeakEye.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeakEye.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24FA7F1E81165D001AD0D7 /* LeakEye.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LeakEye.h; sourceTree = ""; }; + 9E24FA801E81165D001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24FA901E81166C001AD0D7 /* ObjectAgent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectAgent.swift; sourceTree = ""; }; + 9E24FA911E81166C001AD0D7 /* LeakEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeakEye.swift; sourceTree = ""; }; + 9E24FA931E81166C001AD0D7 /* NSObject+Alive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+Alive.swift"; sourceTree = ""; }; + 9E24FA941E81166C001AD0D7 /* NSObject+Eye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSObject+Eye.swift"; sourceTree = ""; }; + 9E24FA951E81166C001AD0D7 /* Preparer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preparer.swift; sourceTree = ""; }; + 9E24FA961E81166C001AD0D7 /* NSNotification+LeakEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSNotification+LeakEye.swift"; sourceTree = ""; }; + 9E24FA981E81166C001AD0D7 /* DispatchQueue+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+.swift"; sourceTree = ""; }; + 9E24FA991E81166C001AD0D7 /* String+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+.swift"; sourceTree = ""; }; + 9E24FA9A1E81166C001AD0D7 /* Variable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Variable.swift; sourceTree = ""; }; + 9E24FAA61E812E54001AD0D7 /* AppSwizzle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppSwizzle.framework; path = ../Carthage/Build/iOS/AppSwizzle.framework; sourceTree = ""; }; + 9E32F5521E102BC8005C7850 /* SecondViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecondViewController.swift; sourceTree = ""; }; + A5A031E8773354D107B0FFE4 /* Pods_LeakEye_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeakEye_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A94C92F5EAAB34F7E971D115 /* Pods-LeakEye_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeakEye_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-LeakEye_Example/Pods-LeakEye_Example.release.xcconfig"; sourceTree = ""; }; + B1B72E5E5CB387C8574EEE9E /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + CE8136BAB9CA3AD58411632D /* Pods-LeakEye_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeakEye_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LeakEye_Tests/Pods-LeakEye_Tests.debug.xcconfig"; sourceTree = ""; }; + DDB4991320C018B9E28E0C4A /* Pods-LeakEye_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeakEye_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-LeakEye_Tests/Pods-LeakEye_Tests.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5ECE86BAB9C981CA122D038B /* Pods_LeakEye_Example.framework in Frameworks */, + 9E24FA841E81165D001AD0D7 /* LeakEye.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B92C4D2AE881797F9F839515 /* Pods_LeakEye_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA791E81165D001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FAA71E812E54001AD0D7 /* AppSwizzle.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 40664E4FB5570DC5D64D118F /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9E24FAA61E812E54001AD0D7 /* AppSwizzle.framework */, + 972B21E2412B46D814D1FD2B /* Pods_LeakEye_Example.framework */, + A5A031E8773354D107B0FFE4 /* Pods_LeakEye_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for LeakEye */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24FA7E1E81165D001AD0D7 /* LeakEye */, + 607FACD11AFB9204008FA782 /* Products */, + EFC20B349700825A675B90F3 /* Pods */, + 40664E4FB5570DC5D64D118F /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* LeakEye_Example.app */, + 607FACE51AFB9204008FA782 /* LeakEye_Tests.xctest */, + 9E24FA7D1E81165D001AD0D7 /* LeakEye.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for LeakEye */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 9E32F5521E102BC8005C7850 /* SecondViewController.swift */, + 607FACD91AFB9204008FA782 /* Main.storyboard */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for LeakEye"; + path = LeakEye; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* Tests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + 573A2902F825A85A93560459 /* LeakEye.podspec */, + B1B72E5E5CB387C8574EEE9E /* README.md */, + 155AC52870DD02971EAFBE90 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 9E24FA7E1E81165D001AD0D7 /* LeakEye */ = { + isa = PBXGroup; + children = ( + 9E24FA8A1E81166C001AD0D7 /* LeakEye */, + 9E24FA7F1E81165D001AD0D7 /* LeakEye.h */, + 9E24FA801E81165D001AD0D7 /* Info.plist */, + ); + path = LeakEye; + sourceTree = ""; + }; + 9E24FA8A1E81166C001AD0D7 /* LeakEye */ = { + isa = PBXGroup; + children = ( + 9E24FA8D1E81166C001AD0D7 /* Classes */, + ); + name = LeakEye; + path = ../../LeakEye; + sourceTree = ""; + }; + 9E24FA8D1E81166C001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24FA8F1E81166C001AD0D7 /* Agent */, + 9E24FA911E81166C001AD0D7 /* LeakEye.swift */, + 9E24FA921E81166C001AD0D7 /* Monitor */, + 9E24FA961E81166C001AD0D7 /* NSNotification+LeakEye.swift */, + 9E24FA971E81166C001AD0D7 /* Util */, + 9E24FA9A1E81166C001AD0D7 /* Variable.swift */, + ); + path = Classes; + sourceTree = ""; + }; + 9E24FA8F1E81166C001AD0D7 /* Agent */ = { + isa = PBXGroup; + children = ( + 9E24FA901E81166C001AD0D7 /* ObjectAgent.swift */, + ); + path = Agent; + sourceTree = ""; + }; + 9E24FA921E81166C001AD0D7 /* Monitor */ = { + isa = PBXGroup; + children = ( + 9E24FA931E81166C001AD0D7 /* NSObject+Alive.swift */, + 9E24FA941E81166C001AD0D7 /* NSObject+Eye.swift */, + 9E24FA951E81166C001AD0D7 /* Preparer.swift */, + ); + path = Monitor; + sourceTree = ""; + }; + 9E24FA971E81166C001AD0D7 /* Util */ = { + isa = PBXGroup; + children = ( + 9E24FA981E81166C001AD0D7 /* DispatchQueue+.swift */, + 9E24FA991E81166C001AD0D7 /* String+.swift */, + ); + path = Util; + sourceTree = ""; + }; + EFC20B349700825A675B90F3 /* Pods */ = { + isa = PBXGroup; + children = ( + 0FB1D0765284FEEA825C5038 /* Pods-LeakEye_Example.debug.xcconfig */, + A94C92F5EAAB34F7E971D115 /* Pods-LeakEye_Example.release.xcconfig */, + CE8136BAB9CA3AD58411632D /* Pods-LeakEye_Tests.debug.xcconfig */, + DDB4991320C018B9E28E0C4A /* Pods-LeakEye_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24FA7A1E81165D001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA811E81165D001AD0D7 /* LeakEye.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* LeakEye_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "LeakEye_Example" */; + buildPhases = ( + 294A69E7AD836F4084D4B1FF /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + 303CC2F41D1300BEEBD6067F /* [CP] Embed Pods Frameworks */, + E8F0D3E8CFF7D428E52C2FA3 /* [CP] Copy Pods Resources */, + 9E24FA891E81165D001AD0D7 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 9E24FA831E81165D001AD0D7 /* PBXTargetDependency */, + ); + name = LeakEye_Example; + productName = LeakEye; + productReference = 607FACD01AFB9204008FA782 /* LeakEye_Example.app */; + productType = "com.apple.product-type.application"; + }; + 607FACE41AFB9204008FA782 /* LeakEye_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "LeakEye_Tests" */; + buildPhases = ( + C6FFD762E2699A1232764C32 /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + 07FCD37D6B062C190B218EC7 /* [CP] Embed Pods Frameworks */, + A8CBFA9F32C65B983790E626 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 607FACE71AFB9204008FA782 /* PBXTargetDependency */, + ); + name = LeakEye_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* LeakEye_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24FA7C1E81165D001AD0D7 /* LeakEye */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24FA881E81165D001AD0D7 /* Build configuration list for PBXNativeTarget "LeakEye" */; + buildPhases = ( + 9E24FA781E81165D001AD0D7 /* Sources */, + 9E24FA791E81165D001AD0D7 /* Frameworks */, + 9E24FA7A1E81165D001AD0D7 /* Headers */, + 9E24FA7B1E81165D001AD0D7 /* Resources */, + 9E24FAA81E812E57001AD0D7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LeakEye; + productName = LeakEye; + productReference = 9E24FA7D1E81165D001AD0D7 /* LeakEye.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + }; + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24FA7C1E81165D001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + LastSwiftMigration = 0820; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "LeakEye" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* LeakEye_Example */, + 607FACE41AFB9204008FA782 /* LeakEye_Tests */, + 9E24FA7C1E81165D001AD0D7 /* LeakEye */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA7B1E81165D001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 07FCD37D6B062C190B218EC7 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LeakEye_Tests/Pods-LeakEye_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 294A69E7AD836F4084D4B1FF /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 303CC2F41D1300BEEBD6067F /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LeakEye_Example/Pods-LeakEye_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9E24FAA81E812E57001AD0D7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/../Carthage/Build/iOS/AppSwizzle.framework", + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/usr/local/bin/carthage copy-frameworks"; + }; + A8CBFA9F32C65B983790E626 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LeakEye_Tests/Pods-LeakEye_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + C6FFD762E2699A1232764C32 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + E8F0D3E8CFF7D428E52C2FA3 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LeakEye_Example/Pods-LeakEye_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E32F5531E102BC8005C7850 /* SecondViewController.swift in Sources */, + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FA781E81165D001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FAA21E81166C001AD0D7 /* NSNotification+LeakEye.swift in Sources */, + 9E24FAA51E81166C001AD0D7 /* Variable.swift in Sources */, + 9E24FA9F1E81166C001AD0D7 /* NSObject+Alive.swift in Sources */, + 9E24FAA41E81166C001AD0D7 /* String+.swift in Sources */, + 9E24FAA11E81166C001AD0D7 /* Preparer.swift in Sources */, + 9E24FA9E1E81166C001AD0D7 /* LeakEye.swift in Sources */, + 9E24FAA31E81166C001AD0D7 /* DispatchQueue+.swift in Sources */, + 9E24FA9D1E81166C001AD0D7 /* ObjectAgent.swift in Sources */, + 9E24FAA01E81166C001AD0D7 /* NSObject+Eye.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* LeakEye_Example */; + targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; + }; + 9E24FA831E81165D001AD0D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9E24FA7C1E81165D001AD0D7 /* LeakEye */; + targetProxy = 9E24FA821E81165D001AD0D7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 607FACD91AFB9204008FA782 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 607FACDA1AFB9204008FA782 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0FB1D0765284FEEA825C5038 /* Pods-LeakEye_Example.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = LeakEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A94C92F5EAAB34F7E971D115 /* Pods-LeakEye_Example.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = LeakEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CE8136BAB9CA3AD58411632D /* Pods-LeakEye_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DDB4991320C018B9E28E0C4A /* Pods-LeakEye_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24FA861E81165D001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../Carthage/Build/iOS/**"; + INFOPLIST_FILE = LeakEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.LeakEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24FA871E81165D001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../Carthage/Build/iOS/**"; + INFOPLIST_FILE = LeakEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.LeakEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "LeakEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "LeakEye_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "LeakEye_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24FA881E81165D001AD0D7 /* Build configuration list for PBXNativeTarget "LeakEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24FA861E81165D001AD0D7 /* Debug */, + 9E24FA871E81165D001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ee6310a --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/project.xcworkspace/xcshareddata/LeakEye.xcscmblueprint b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/project.xcworkspace/xcshareddata/LeakEye.xcscmblueprint new file mode 100644 index 0000000..930ec99 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/project.xcworkspace/xcshareddata/LeakEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "1DB58DD37EA1B5358CB1103D5133CD67EC14E207", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "1DB58DD37EA1B5358CB1103D5133CD67EC14E207" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "A296F9FC-02BF-416D-8E81-CFC94935D588", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "1DB58DD37EA1B5358CB1103D5133CD67EC14E207" : "LeakEye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "LeakEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/LeakEye.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/LeakEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "1DB58DD37EA1B5358CB1103D5133CD67EC14E207" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/xcshareddata/xcschemes/LeakEye-Example.xcscheme b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/xcshareddata/xcschemes/LeakEye-Example.xcscheme new file mode 100644 index 0000000..dbd8c16 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/xcshareddata/xcschemes/LeakEye-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/xcshareddata/xcschemes/LeakEye.xcscheme b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/xcshareddata/xcschemes/LeakEye.xcscheme new file mode 100644 index 0000000..b64d2e5 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcodeproj/xcshareddata/xcschemes/LeakEye.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..89bb6b3 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye.xcworkspace/xcshareddata/LeakEye.xcscmblueprint b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcworkspace/xcshareddata/LeakEye.xcscmblueprint new file mode 100644 index 0000000..35b6e4b --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye.xcworkspace/xcshareddata/LeakEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "32D68B495BD0BCE3D91146399EB5FAE11A784068", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "32D68B495BD0BCE3D91146399EB5FAE11A784068" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "C8F0E8D0-B429-412F-B9BA-F12086FDCEFB", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "32D68B495BD0BCE3D91146399EB5FAE11A784068" : "LeakEye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "LeakEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/LeakEye.xcworkspace", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:GodEyeSwift\/LeakEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "32D68B495BD0BCE3D91146399EB5FAE11A784068" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye/AppDelegate.swift b/Carthage/Checkouts/LeakEye/Example/LeakEye/AppDelegate.swift new file mode 100644 index 0000000..287cc8a --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye/AppDelegate.swift @@ -0,0 +1,34 @@ +// +// AppDelegate.swift +// LeakEye +// +// Created by zixun on 12/26/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit +import LeakEye + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + var eye = LeakEye() + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + + self.eye.delegate = self + self.eye.start() + + return true + } +} + +extension AppDelegate: LeakEyeDelegate { + func leakEye(leakEye:LeakEye,didCatchLeak object:NSObject) { + print(object) + } + +} + diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/LeakEye/Example/LeakEye/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..a0ce57a --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye/Base.lproj/LaunchScreen.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye/Base.lproj/Main.storyboard b/Carthage/Checkouts/LeakEye/Example/LeakEye/Base.lproj/Main.storyboard new file mode 100644 index 0000000..a93444a --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye/Base.lproj/Main.storyboard @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/LeakEye/Example/LeakEye/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d3942e9 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye/Info.plist b/Carthage/Checkouts/LeakEye/Example/LeakEye/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye/LeakEye.h b/Carthage/Checkouts/LeakEye/Example/LeakEye/LeakEye.h new file mode 100644 index 0000000..13ec344 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye/LeakEye.h @@ -0,0 +1,19 @@ +// +// LeakEye.h +// LeakEye +// +// Created by zixun on 2017/3/21. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for LeakEye. +FOUNDATION_EXPORT double LeakEyeVersionNumber; + +//! Project version string for LeakEye. +FOUNDATION_EXPORT const unsigned char LeakEyeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye/SecondViewController.swift b/Carthage/Checkouts/LeakEye/Example/LeakEye/SecondViewController.swift new file mode 100644 index 0000000..614e772 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye/SecondViewController.swift @@ -0,0 +1,52 @@ +// +// SecondViewController.swift +// LeakEye +// +// Created by zixun on 16/12/26. +// Copyright © 2016年 CocoaPods. All rights reserved. +// + +import Foundation +import UIKit + +class LeakTest: NSObject { + + var block: (() -> ())! + + init(block: @escaping () -> () ) { + super.init() + self.block = block + } +} + +class SecondViewController: UIViewController { + + private var test : LeakTest! + + private var str: String = "" + + override func viewDidLoad() { + super.viewDidLoad() + + + let btn = UIButton(frame: CGRect(x: 200, y: 100, width: 100, height: 100)) + btn.setTitle("Pop", for: UIControlState.normal) + btn.setTitleColor(UIColor.red, for: UIControlState.normal) + btn.addTarget(self, action: #selector(SecondViewController.pop), for: UIControlEvents.touchUpInside) + self.view.addSubview(btn) + + self.test = LeakTest { + self.str.append("leak") + } + + } + + func pop() { + _ = self.navigationController?.popViewController(animated: true) + + } + + deinit { + print("deinit") + } +} diff --git a/Carthage/Checkouts/LeakEye/Example/LeakEye/ViewController.swift b/Carthage/Checkouts/LeakEye/Example/LeakEye/ViewController.swift new file mode 100644 index 0000000..95ea7ea --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/LeakEye/ViewController.swift @@ -0,0 +1,31 @@ +// +// ViewController.swift +// LeakEye +// +// Created by zixun on 12/26/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit +import LeakEye + +class ViewController: UIViewController { + + + override func viewDidLoad() { + super.viewDidLoad() + + let btn = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 100)) + btn.setTitle("Push", for: UIControlState.normal) + btn.setTitleColor(UIColor.red, for: UIControlState.normal) + btn.addTarget(self, action: #selector(ViewController.push), for: UIControlEvents.touchUpInside) + self.view.addSubview(btn) + + } + + func push() { + self.navigationController?.pushViewController(SecondViewController(), animated: true) + } + +} + diff --git a/Carthage/Checkouts/LeakEye/Example/Podfile b/Carthage/Checkouts/LeakEye/Example/Podfile new file mode 100644 index 0000000..35ab922 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/Podfile @@ -0,0 +1,10 @@ +use_frameworks! + +target 'LeakEye_Example' do + pod 'LeakEye', :path => '../' + target 'LeakEye_Tests' do + inherit! :search_paths + + + end +end diff --git a/Carthage/Checkouts/LeakEye/Example/Podfile.lock b/Carthage/Checkouts/LeakEye/Example/Podfile.lock new file mode 100644 index 0000000..f2a80b8 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/Podfile.lock @@ -0,0 +1,19 @@ +PODS: + - AppSwizzle (1.0.0) + - LeakEye (0.1.0): + - AppSwizzle (~> 1.0.0) + +DEPENDENCIES: + - LeakEye (from `../`) + +EXTERNAL SOURCES: + LeakEye: + :path: "../" + +SPEC CHECKSUMS: + AppSwizzle: 0ba5dc3d884a5315a89ac4ab08c7f8e1c85c795c + LeakEye: aa57f4b814579985063f5a7678c5b81753bdf073 + +PODFILE CHECKSUM: 63e89493110ff745cf47b7b8f73f2abfa6f21719 + +COCOAPODS: 1.2.0 diff --git a/Carthage/Checkouts/LeakEye/Example/Tests/Info.plist b/Carthage/Checkouts/LeakEye/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/LeakEye/Example/Tests/Tests.swift b/Carthage/Checkouts/LeakEye/Example/Tests/Tests.swift new file mode 100644 index 0000000..51ff160 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/Example/Tests/Tests.swift @@ -0,0 +1,29 @@ +import UIKit +import XCTest +import LeakEye + +class Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + XCTAssert(true, "Pass") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure() { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Carthage/Checkouts/LeakEye/LICENSE b/Carthage/Checkouts/LeakEye/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/LeakEye/LeakEye.podspec b/Carthage/Checkouts/LeakEye/LeakEye.podspec new file mode 100644 index 0000000..4efeb9d --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LeakEye.podspec @@ -0,0 +1,35 @@ +# +# Be sure to run `pod lib lint LeakEye.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'LeakEye' + s.version = '1.1.1' + s.summary = 'LeakEye is a memory leak monitor write by swift inspired by PLeakSniffer.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +LeakEye is a memory leak monitor write by swift inspired by PLeakSniffer.. + DESC + + s.homepage = 'https://github.com/zixun/LeakEye' + # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'zixun' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/LeakEye.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'LeakEye/Classes/**/*' + s.dependency 'AppSwizzle', '~> 1.1.1' +end diff --git a/Carthage/Checkouts/LeakEye/LeakEye/Classes/Agent/ObjectAgent.swift b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Agent/ObjectAgent.swift new file mode 100644 index 0000000..f6a2f38 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Agent/ObjectAgent.swift @@ -0,0 +1,87 @@ +// +// ObjectAgent.swift +// Pods +// +// Created by zixun on 16/12/12. +// +// + +import Foundation + +//-------------------------------------------------------------------------- +// MARK: - ObjectAgent +// DESCRIPTION: the agent of object instance +//-------------------------------------------------------------------------- +class ObjectAgent: NSObject { + + //-------------------------------------------------------------------------- + // MARK: INTERNAL PROPERTY + //-------------------------------------------------------------------------- + weak var object: NSObject? + + weak var host: NSObject? + + weak var responder: NSObject? + + //-------------------------------------------------------------------------- + // MARK: LIFE CYCLE + //-------------------------------------------------------------------------- + init(object: NSObject) { + super.init() + self.object = object + + NotificationCenter.default.removeObserver(self, + name: NSNotification.Name.scan, + object: nil) + NotificationCenter.default.addObserver(self, + selector: #selector(ObjectAgent.handleScan), + name: NSNotification.Name.scan, + object: nil) + + } + + deinit { + NotificationCenter.default.removeObserver(self, + name: NSNotification.Name.scan, + object: nil) + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE FUNCTION + //-------------------------------------------------------------------------- + @objc private func handleScan() { + + if self.object == nil { + return + } + + if self.didNotified { + return + } + + let alive = self.object?.isAlive() + if alive == false { + self.leakCheckFailCount += 1 + } + + if self.leakCheckFailCount >= 5 { + self.notifyPossibleLeak() + } + } + + private func notifyPossibleLeak() { + if self.didNotified { + return + } + + self.didNotified = true + NotificationCenter.default.post(name: NSNotification.Name.receive, object: self.object) + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE PROPERTY + //-------------------------------------------------------------------------- + private var didNotified: Bool = false + + fileprivate var leakCheckFailCount: Int = 0 +} diff --git a/Carthage/Checkouts/LeakEye/LeakEye/Classes/LeakEye.swift b/Carthage/Checkouts/LeakEye/LeakEye/Classes/LeakEye.swift new file mode 100644 index 0000000..8d51f82 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LeakEye/Classes/LeakEye.swift @@ -0,0 +1,89 @@ +// +// LeakEye.swift +// Pods +// +// Created by zixun on 16/12/12. +// +// + +import Foundation + +//-------------------------------------------------------------------------- +// MARK: - LeakEyeDelegate +//-------------------------------------------------------------------------- +@objc public protocol LeakEyeDelegate: NSObjectProtocol { + @objc optional func leakEye(_ leakEye:LeakEye,didCatchLeak object:NSObject) +} + +//-------------------------------------------------------------------------- +// MARK: - LeakEye +//-------------------------------------------------------------------------- +open class LeakEye: NSObject { + + //-------------------------------------------------------------------------- + // MARK: OPEN PROPERTY + //-------------------------------------------------------------------------- + open weak var delegate: LeakEyeDelegate? + + open var isOpening: Bool { + get { + return self.timer?.isValid ?? false + } + } + //-------------------------------------------------------------------------- + // MARK: LIFE CYCLE + //-------------------------------------------------------------------------- + public override init() { + super.init() + NotificationCenter.default.addObserver(self, selector: #selector(LeakEye.receive), name: NSNotification.Name.receive, object: nil) + } + + //-------------------------------------------------------------------------- + // MARK: OPEN FUNCTION + //-------------------------------------------------------------------------- + open func open() { + Preparer.binding() + self.startPingTimer() + } + + open func close() { + self.timer?.invalidate() + self.timer = nil + } + + private func startPingTimer() { + if Thread.isMainThread == false { + DispatchQueue.main.async { + self.startPingTimer() + return + } + } + self.close() + + self.timer = Timer.scheduledTimer(timeInterval: 0.5, + target: self, + selector: #selector(LeakEye.scan), + userInfo: nil, + repeats: true) + + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE FUNCTION + //-------------------------------------------------------------------------- + @objc private func scan() { + NotificationCenter.default.post(name: NSNotification.Name.scan, object: nil) + } + + @objc private func receive(notif:NSNotification) { + guard let leakObj = notif.object as? NSObject else { + return + } + self.delegate?.leakEye?(self, didCatchLeak: leakObj) + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE PROPEERTY + //-------------------------------------------------------------------------- + private var timer: Timer? +} diff --git a/Carthage/Checkouts/LeakEye/LeakEye/Classes/Monitor/NSObject+Alive.swift b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Monitor/NSObject+Alive.swift new file mode 100644 index 0000000..9d8721b --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Monitor/NSObject+Alive.swift @@ -0,0 +1,111 @@ +// +// NSObject+Alive.swift +// Pods +// +// Created by zixun on 16/12/13. +// +// + +import Foundation +//-------------------------------------------------------------------------- +// MARK: - NSObject+Alive +// DESCRIPTION: NSObject extension for judge if the instance is alive +//-------------------------------------------------------------------------- +extension NSObject { + + //-------------------------------------------------------------------------- + // MARK: INTERNAL FUNCTION + //-------------------------------------------------------------------------- + func judgeAlive() -> Bool { + if self.isKind(of: UIViewController.classForCoder()) { + return self.judge(self as! UIViewController) + }else if self.isKind(of: UIView.classForCoder()) { + return self.judge(self as! UIView ) + }else { + return self.judge(self) + } + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE FUNCTION + //-------------------------------------------------------------------------- + + /// judeg a comman instance is alive + fileprivate func judge(_ common:NSObject) -> Bool { + var alive = true + if common.agent?.host == nil { + alive = false + } + + return alive + } + + /// judge the controller instance is alive + fileprivate func judge(_ controller:UIViewController) -> Bool { + //1. self.view is not in the window + //2. self is not in the navigation controllers + + var visiable = false + + var view = controller.view + + while ((view?.superview) != nil) { + view = view?.superview + } + + if view!.isKind(of: UIWindow.self) { + visiable = true + } + + var holdable = false + if controller.navigationController != nil || controller.presentingViewController != nil { + holdable = true + } + + if visiable == false && holdable == false { + return false + }else { + return true + } + } + + /// judge the view instance is alive + fileprivate func judge(_ view:UIView) -> Bool { + + var alive = true + var onUIStack = false + var v = view + + while v.superview != nil { + v = v.superview! + } + + if v.isKind(of: UIWindow.classForCoder()) { + onUIStack = true + } + + if view.agent?.responder == nil { + var r = view.next + while r != nil { + if r!.next == nil { + break + }else { + r = r!.next + } + + if (r?.isKind(of: UIViewController.classForCoder()))! { + break + } + } + view.agent?.responder = r + } + + if onUIStack == false { + alive = false + if let r = view.agent?.responder { + alive = r.isKind(of: UIViewController.classForCoder()) + } + } + return alive + } +} diff --git a/Carthage/Checkouts/LeakEye/LeakEye/Classes/Monitor/NSObject+Eye.swift b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Monitor/NSObject+Eye.swift new file mode 100644 index 0000000..2f08c66 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Monitor/NSObject+Eye.swift @@ -0,0 +1,173 @@ +// +// NSObject+Monitor.swift +// Pods +// +// Created by zixun on 16/12/12. +// +// + +import Foundation + +//-------------------------------------------------------------------------- +// MARK: - NSObject agent extension +//-------------------------------------------------------------------------- +extension NSObject { + fileprivate struct key { + static var objectAgent = "\(#file)+\(#line)" + } + + var agent: ObjectAgent? { + get { + return objc_getAssociatedObject(self, &key.objectAgent) as? ObjectAgent + } + set { + objc_setAssociatedObject(self, &key.objectAgent, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } +} + +//-------------------------------------------------------------------------- +// MARK: - NSObject monitor extension +//-------------------------------------------------------------------------- +extension NSObject { + + /// monitor all retain variable of the NSObject instance + /// + /// - Parameter level: extend chain level + func monitorAllRetainVariable(level: Int) { + if level >= 5 { + return + } + + var monitorVariables = [String]() + + //track class level1 + if self.isSystemClass(self.classForCoder) == false { + let var_level1 = self.getAllVariableName(self.classForCoder) + monitorVariables.append(contentsOf: var_level1) + } + + if self.isSystemClass(self.superclass) { + let var_level2 = self.getAllVariableName(self.superclass!) + monitorVariables.append(contentsOf: var_level2) + } + + if self.isSystemClass(self.superclass?.superclass()) { + let var_level3 = self.getAllVariableName(self.superclass!.superclass()!) + monitorVariables.append(contentsOf: var_level3) + } + + for name in monitorVariables { + + guard let cur = self.value(forKey: name) else { + continue + } + + guard let obj = cur as? NSObject else { + continue + } + + let ret = obj.makeAlive() + if ret { + obj.agent?.host = self + obj.monitorAllRetainVariable(level: level+1) + } + } + } + + fileprivate func getAllVariableName(_ cls:AnyClass) -> [String] { + + let count = UnsafeMutablePointer.allocate(capacity: 0) + let properties = class_copyPropertyList(cls, count) + + if Int(count[0]) == 0 { + free(properties) + return [String]() + } + + var result = [String]() + for i in 0.. Bool { + return self.judgeAlive() + } + + /// labeled the object is alive + func makeAlive() -> Bool { + //agent mask be nil + if self.agent != nil { + return false + } + //not check system class + if self.isSystemClass(self.classForCoder) { + return false + } + //view object needs a super view ti be alive + if self.isKind(of: UIView.classForCoder()) { + let v: UIView = self as! UIView + if v.superview == nil { + return false + } + } + //view controller need in the navigation or presenting + if self.isKind(of: UIViewController.classForCoder()) { + let vc: UIViewController = self as! UIViewController + if vc.navigationController == nil && vc.presentingViewController == nil { + return false + } + } + self.agent = ObjectAgent(object: self) + return true + } + + /// judeg the specified class is one of the system class + func isSystemClass(_ clazz:AnyClass?) -> Bool { + + guard let clazz = clazz else { + return false + } + + let bundle = Bundle(for: clazz) + + guard bundle.bundlePath.hasSuffix("/usr/lib") == false else { + return true + } + + //need below /usr/lib check, because "/usr/lib" bundle also has no bundleIdentifier + guard let bundleIdentifier = bundle.bundleIdentifier else { + return false + } + + if bundleIdentifier.hasPrefix("com.apple."){ + return true + }else { + return false + } + } + +} diff --git a/Carthage/Checkouts/LeakEye/LeakEye/Classes/Monitor/Preparer.swift b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Monitor/Preparer.swift new file mode 100644 index 0000000..4f01ab2 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Monitor/Preparer.swift @@ -0,0 +1,101 @@ +// +// Preparer.swift +// Pods +// +// Created by zixun on 16/12/13. +// +// + +import Foundation +import AppSwizzle + +//-------------------------------------------------------------------------- +// MARK: - Preparer +// DESCRIPTION: Preparer for leak monitor +//-------------------------------------------------------------------------- +class Preparer: NSObject { + + class func binding() { + + DispatchQueue.once { () in + // UINavigationController + var orig = #selector(UINavigationController.pushViewController(_:animated:)) + var alter = #selector(UINavigationController.app_pushViewController(_:animated:)) + UINavigationController.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) + + + // UIView + orig = #selector(UIView.didMoveToSuperview) + alter = #selector(UIView.app_didMoveToSuperview) + UIView.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) + + // UIViewController + orig = #selector(UIViewController.present(_:animated:completion:)) + alter = #selector(UIViewController.app_present(_:animated:completion:)) + UIViewController.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) + + orig = #selector(UIViewController.viewDidAppear(_:)) + alter = #selector(UIViewController.app_viewDidAppear(_:)) + UIViewController.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) + + } + } + +} + +//-------------------------------------------------------------------------- +// MARK: - UINavigationController + Preparer +//-------------------------------------------------------------------------- +extension UINavigationController { + + @objc fileprivate func app_pushViewController(_ viewController: UIViewController, animated: Bool) { + self.app_pushViewController(viewController, animated: animated) + + viewController.makeAlive() + } +} + +//-------------------------------------------------------------------------- +// MARK: - UIView + Preparer +//-------------------------------------------------------------------------- +extension UIView { + + @objc fileprivate func app_didMoveToSuperview() { + self.app_didMoveToSuperview() + + var hasAliveParent = false + + var r = self.next + while (r != nil) { + if r!.agent != nil { + hasAliveParent = true + break + } + + r = r!.next + } + + if hasAliveParent { + self.makeAlive() + } + } +} + +//-------------------------------------------------------------------------- +// MARK: - UIViewController + Preparer +//-------------------------------------------------------------------------- +extension UIViewController { + + @objc fileprivate func app_present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Swift.Void)? = nil) { + self.app_present(viewControllerToPresent, animated: flag, completion: completion) + + viewControllerToPresent.makeAlive() + } + + @objc fileprivate func app_viewDidAppear(_ animated: Bool) { + self.app_viewDidAppear(animated) + + self.monitorAllRetainVariable(level: 0) + } +} + diff --git a/Carthage/Checkouts/LeakEye/LeakEye/Classes/NSNotification+LeakEye.swift b/Carthage/Checkouts/LeakEye/LeakEye/Classes/NSNotification+LeakEye.swift new file mode 100644 index 0000000..55b41e3 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LeakEye/Classes/NSNotification+LeakEye.swift @@ -0,0 +1,16 @@ +// +// NSNotification+LeakEye.swift +// Pods +// +// Created by zixun on 16/12/13. +// +// + +import Foundation + +extension Notification.Name { + + static let scan = NSNotification.Name("scan") + + static let receive = NSNotification.Name("receive") +} diff --git a/Carthage/Checkouts/LeakEye/LeakEye/Classes/Util/DispatchQueue+.swift b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Util/DispatchQueue+.swift new file mode 100644 index 0000000..47cff20 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Util/DispatchQueue+.swift @@ -0,0 +1,38 @@ +// +// DispatchQueue+.swift +// Pods +// +// Created by zixun on 16/12/12. +// +// + +import Foundation + +public extension DispatchQueue { + fileprivate static var _onceTracker = [String]() + + public class func once(_ file: String = #file, function: String = #function, line: Int = #line, block:(Void)->Void) { + let token = file + ":" + function + ":" + String(line) + once(token: token, block: block) + } + + /** + Executes a block of code, associated with a unique token, only once. The code is thread safe and will + only execute the code once even in the presence of multithreaded calls. + + - parameter token: A unique reverse DNS style name such as com.vectorform. or a GUID + - parameter block: Block to execute once + */ + public class func once(token: String, block:(Void)->Void) { + objc_sync_enter(self) + defer { objc_sync_exit(self) } + + + if _onceTracker.contains(token) { + return + } + + _onceTracker.append(token) + block() + } +} diff --git a/Carthage/Checkouts/LeakEye/LeakEye/Classes/Util/String+.swift b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Util/String+.swift new file mode 100644 index 0000000..d0633fc --- /dev/null +++ b/Carthage/Checkouts/LeakEye/LeakEye/Classes/Util/String+.swift @@ -0,0 +1,32 @@ +// +// String+.swift +// Pods +// +// Created by zixun on 16/12/12. +// +// + +import Foundation + +extension String { + + /// Finds the string between two bookend strings if it can be found. + /// + /// - parameter left: The left bookend + /// - parameter right: The right bookend + /// + /// - returns: The string between the two bookends, or nil if the bookends cannot be found, the bookends are the same or appear contiguously. + public func between(_ left: String, _ right: String) -> String? { + + + guard + let leftRange = range(of:left), + let rightRange = self.range(of: right, options: String.CompareOptions.backwards, range: nil, locale: nil), + left != right && leftRange.upperBound != rightRange.lowerBound + else { return nil } + + + return self[leftRange.upperBound.. Bool { + let attr = String(cString: property_getAttributes(self.property)) + return attr.contains("&") + } + + /// name of the property + func name() -> String { + return String(cString: property_getName(self.property)) + } + + /// type of the property + func type() -> AnyClass? { + let t = String(cString: property_getAttributes(self.property)).components(separatedBy: ",").first + guard let type = t?.between("@\"", "\"") else { + return nil + } + return NSClassFromString(type) + } + //-------------------------------------------------------------------------- + // MARK: PRIVATE PROPERTY + //-------------------------------------------------------------------------- + fileprivate var property: objc_property_t! +} + diff --git a/Carthage/Checkouts/LeakEye/README.md b/Carthage/Checkouts/LeakEye/README.md new file mode 100644 index 0000000..3f61a3f --- /dev/null +++ b/Carthage/Checkouts/LeakEye/README.md @@ -0,0 +1,87 @@ +# LeakEye + +[![Version](https://img.shields.io/cocoapods/v/LeakEye.svg?style=flat)](http://cocoapods.org/pods/LeakEye) +[![License](https://img.shields.io/cocoapods/l/LeakEye.svg?style=flat)](http://cocoapods.org/pods/LeakEye) +[![Platform](https://img.shields.io/cocoapods/p/LeakEye.svg?style=flat)](http://cocoapods.org/pods/LeakEye) +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) + +LeakEye is a memory leak monitor inspired by PLeakSniffer. + +## Family +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Book & Principle + +**I has wrote a book named [《iOS监控编程》](),each chapter records the course function of the implementation details and the way to explore.sorry for english friends,this book wrote by chineses.** + + +## Example + +To run the example project, clone the repo, and run `pod install` from the Example directory first. + + +## Installation + +### CocoaPods +LeakEye is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "LeakEye" +``` + +### Carthage +Or, if you’re using [Carthage](https://github.com/Carthage/Carthage), add SwViewCapture to your Cartfile: + +``` +github "zixun/LeakEye" +``` + +## Usage +Import the lib: + +```swift +import LeakEye +``` + +Declare an instance variable: + +```swift +var eye = LeakEye() +``` + +Start monitor: + +```swift +self.eye.delegate = self +self.eye.start() +``` + +Implement the delegate: + +```swift +func leakEye(leakEye:LeakEye,didCatchLeak object:NSObject) { + print(object) +} +``` + +that's all!(就酱) + +## Thanks +Thanks for [PLeakSniffer](https://github.com/music4kid/PLeakSniffer),LeakEye is inspired by it. + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + +## License + +LeakEye is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/LeakEye/_Pods.xcodeproj b/Carthage/Checkouts/LeakEye/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/LeakEye/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/Log4G/.gitignore b/Carthage/Checkouts/Log4G/.gitignore new file mode 100644 index 0000000..a119ed5 --- /dev/null +++ b/Carthage/Checkouts/Log4G/.gitignore @@ -0,0 +1,33 @@ +# OS X +.DS_Store + +# Xcode +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ +*.xccheckout +profile +*.moved-aside +DerivedData +*.hmap +*.ipa + +# Bundler +.bundle + +Carthage +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control +# +# Note: if you ignore the Pods directory, make sure to uncomment +# `pod install` in .travis.yml +# +Pods/ diff --git a/Carthage/Checkouts/Log4G/.travis.yml b/Carthage/Checkouts/Log4G/.travis.yml new file mode 100644 index 0000000..f5dfff7 --- /dev/null +++ b/Carthage/Checkouts/Log4G/.travis.yml @@ -0,0 +1,14 @@ +# references: +# * http://www.objc.io/issue-6/travis-ci.html +# * https://github.com/supermarin/xcpretty#usage + +osx_image: xcode7.3 +language: objective-c +# cache: cocoapods +# podfile: Example/Podfile +# before_install: +# - gem install cocoapods # Since Travis is not always on latest version +# - pod install --project-directory=Example +script: +- set -o pipefail && xcodebuild test -workspace Example/Log4G.xcworkspace -scheme Log4G-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty +- pod lib lint diff --git a/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/project.pbxproj b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/project.pbxproj new file mode 100644 index 0000000..4371bb2 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/project.pbxproj @@ -0,0 +1,778 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 0C6F630DBD1682CA852E794A /* Pods_Log4G_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A98246568D56EE5EA68DF5A5 /* Pods_Log4G_Tests.framework */; }; + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 8A351A4E2131F12E4C2FA0E3 /* Pods_Log4G_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17C4EB897EDD3F2C11F8B2B3 /* Pods_Log4G_Example.framework */; }; + 9E24FAB21E8131C3001AD0D7 /* Log4G.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24FAB01E8131C3001AD0D7 /* Log4G.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FAB51E8131C3001AD0D7 /* Log4G.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E24FAAE1E8131C3001AD0D7 /* Log4G.framework */; }; + 9E24FAB61E8131C3001AD0D7 /* Log4G.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9E24FAAE1E8131C3001AD0D7 /* Log4G.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9E24FAC41E8131D9001AD0D7 /* Log4G.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FAC01E8131D9001AD0D7 /* Log4G.swift */; }; + 9E24FAC51E8131D9001AD0D7 /* LogModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FAC11E8131D9001AD0D7 /* LogModel.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = Log4G; + }; + 9E24FAB31E8131C3001AD0D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9E24FAAD1E8131C3001AD0D7; + remoteInfo = Log4G; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9E24FABA1E8131C3001AD0D7 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 9E24FAB61E8131C3001AD0D7 /* Log4G.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 053FA2A3BF0AAB165BDBA4AB /* Pods-Log4G_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Log4G_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Log4G_Tests/Pods-Log4G_Tests.release.xcconfig"; sourceTree = ""; }; + 17C4EB897EDD3F2C11F8B2B3 /* Pods_Log4G_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Log4G_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1AF339AE1549EB9A8C44C885 /* Log4G.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Log4G.podspec; path = ../Log4G.podspec; sourceTree = ""; }; + 607FACD01AFB9204008FA782 /* Log4G_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Log4G_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 607FACE51AFB9204008FA782 /* Log4G_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Log4G_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + 78A0C2D5556632C1429AA2B5 /* Pods-Log4G_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Log4G_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Log4G_Tests/Pods-Log4G_Tests.debug.xcconfig"; sourceTree = ""; }; + 9D898033BD06DC866833562A /* Pods-Log4G_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Log4G_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Log4G_Example/Pods-Log4G_Example.debug.xcconfig"; sourceTree = ""; }; + 9E24FAAE1E8131C3001AD0D7 /* Log4G.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Log4G.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24FAB01E8131C3001AD0D7 /* Log4G.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Log4G.h; sourceTree = ""; }; + 9E24FAB11E8131C3001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24FAC01E8131D9001AD0D7 /* Log4G.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Log4G.swift; sourceTree = ""; }; + 9E24FAC11E8131D9001AD0D7 /* LogModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogModel.swift; sourceTree = ""; }; + A98246568D56EE5EA68DF5A5 /* Pods_Log4G_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Log4G_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AE68586604F868B31BDE91C1 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + B1D9518840F6632805105E77 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + EF5915D41EA2ACF248E32589 /* Pods-Log4G_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Log4G_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Log4G_Example/Pods-Log4G_Example.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FAB51E8131C3001AD0D7 /* Log4G.framework in Frameworks */, + 8A351A4E2131F12E4C2FA0E3 /* Pods_Log4G_Example.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C6F630DBD1682CA852E794A /* Pods_Log4G_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FAAA1E8131C3001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 39538B3B6211F95982509B4C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 17C4EB897EDD3F2C11F8B2B3 /* Pods_Log4G_Example.framework */, + A98246568D56EE5EA68DF5A5 /* Pods_Log4G_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for Log4G */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24FAAF1E8131C3001AD0D7 /* Log4G */, + 607FACD11AFB9204008FA782 /* Products */, + 9CFAAA2DEE6C17DD46A5D77C /* Pods */, + 39538B3B6211F95982509B4C /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* Log4G_Example.app */, + 607FACE51AFB9204008FA782 /* Log4G_Tests.xctest */, + 9E24FAAE1E8131C3001AD0D7 /* Log4G.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for Log4G */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 607FACD91AFB9204008FA782 /* Main.storyboard */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for Log4G"; + path = Log4G; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* Tests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + 1AF339AE1549EB9A8C44C885 /* Log4G.podspec */, + B1D9518840F6632805105E77 /* README.md */, + AE68586604F868B31BDE91C1 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 9CFAAA2DEE6C17DD46A5D77C /* Pods */ = { + isa = PBXGroup; + children = ( + 9D898033BD06DC866833562A /* Pods-Log4G_Example.debug.xcconfig */, + EF5915D41EA2ACF248E32589 /* Pods-Log4G_Example.release.xcconfig */, + 78A0C2D5556632C1429AA2B5 /* Pods-Log4G_Tests.debug.xcconfig */, + 053FA2A3BF0AAB165BDBA4AB /* Pods-Log4G_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9E24FAAF1E8131C3001AD0D7 /* Log4G */ = { + isa = PBXGroup; + children = ( + 9E24FABB1E8131D9001AD0D7 /* Log4G */, + 9E24FAB01E8131C3001AD0D7 /* Log4G.h */, + 9E24FAB11E8131C3001AD0D7 /* Info.plist */, + ); + path = Log4G; + sourceTree = ""; + }; + 9E24FABB1E8131D9001AD0D7 /* Log4G */ = { + isa = PBXGroup; + children = ( + 9E24FABE1E8131D9001AD0D7 /* Classes */, + ); + name = Log4G; + path = ../../Log4G; + sourceTree = ""; + }; + 9E24FABE1E8131D9001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24FAC01E8131D9001AD0D7 /* Log4G.swift */, + 9E24FAC11E8131D9001AD0D7 /* LogModel.swift */, + ); + path = Classes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24FAAB1E8131C3001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FAB21E8131C3001AD0D7 /* Log4G.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* Log4G_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Log4G_Example" */; + buildPhases = ( + 85BD5E65B754CA7E5D7C904B /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + 9D23396872A4714E966BC92B /* [CP] Embed Pods Frameworks */, + F14D49268C84BCF2DAD7D9F1 /* [CP] Copy Pods Resources */, + 9E24FABA1E8131C3001AD0D7 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 9E24FAB41E8131C3001AD0D7 /* PBXTargetDependency */, + ); + name = Log4G_Example; + productName = Log4G; + productReference = 607FACD01AFB9204008FA782 /* Log4G_Example.app */; + productType = "com.apple.product-type.application"; + }; + 607FACE41AFB9204008FA782 /* Log4G_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Log4G_Tests" */; + buildPhases = ( + B15D4D79B1689AB750A839A4 /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + F1E4F01CE1EB5A491515B849 /* [CP] Embed Pods Frameworks */, + 591790C08501D8BB056CCA7A /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 607FACE71AFB9204008FA782 /* PBXTargetDependency */, + ); + name = Log4G_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* Log4G_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24FAAD1E8131C3001AD0D7 /* Log4G */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24FAB91E8131C3001AD0D7 /* Build configuration list for PBXNativeTarget "Log4G" */; + buildPhases = ( + 9E24FAA91E8131C3001AD0D7 /* Sources */, + 9E24FAAA1E8131C3001AD0D7 /* Frameworks */, + 9E24FAAB1E8131C3001AD0D7 /* Headers */, + 9E24FAAC1E8131C3001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Log4G; + productName = Log4G; + productReference = 9E24FAAE1E8131C3001AD0D7 /* Log4G.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0820; + }; + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0820; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24FAAD1E8131C3001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + LastSwiftMigration = 0820; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Log4G" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* Log4G_Example */, + 607FACE41AFB9204008FA782 /* Log4G_Tests */, + 9E24FAAD1E8131C3001AD0D7 /* Log4G */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FAAC1E8131C3001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 591790C08501D8BB056CCA7A /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Log4G_Tests/Pods-Log4G_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 85BD5E65B754CA7E5D7C904B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 9D23396872A4714E966BC92B /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Log4G_Example/Pods-Log4G_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + B15D4D79B1689AB750A839A4 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + F14D49268C84BCF2DAD7D9F1 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Log4G_Example/Pods-Log4G_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + F1E4F01CE1EB5A491515B849 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Log4G_Tests/Pods-Log4G_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FAA91E8131C3001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FAC51E8131D9001AD0D7 /* LogModel.swift in Sources */, + 9E24FAC41E8131D9001AD0D7 /* Log4G.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* Log4G_Example */; + targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; + }; + 9E24FAB41E8131C3001AD0D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9E24FAAD1E8131C3001AD0D7 /* Log4G */; + targetProxy = 9E24FAB31E8131C3001AD0D7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 607FACD91AFB9204008FA782 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 607FACDA1AFB9204008FA782 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9D898033BD06DC866833562A /* Pods-Log4G_Example.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Log4G/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EF5915D41EA2ACF248E32589 /* Pods-Log4G_Example.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = Log4G/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 78A0C2D5556632C1429AA2B5 /* Pods-Log4G_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 053FA2A3BF0AAB165BDBA4AB /* Pods-Log4G_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24FAB71E8131C3001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Log4G/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.Log4G; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24FAB81E8131C3001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Log4G/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.Log4G; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Log4G" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Log4G_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Log4G_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24FAB91E8131C3001AD0D7 /* Build configuration list for PBXNativeTarget "Log4G" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24FAB71E8131C3001AD0D7 /* Debug */, + 9E24FAB81E8131C3001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..59159cd --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/project.xcworkspace/xcshareddata/Log4G.xcscmblueprint b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/project.xcworkspace/xcshareddata/Log4G.xcscmblueprint new file mode 100644 index 0000000..04967a7 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/project.xcworkspace/xcshareddata/Log4G.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "6A57C0EFFA2BEA231211B8412CEAF2E3BCCFF7BE", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807, + "6A57C0EFFA2BEA231211B8412CEAF2E3BCCFF7BE" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "0F64A67B-AFB4-49FD-B01D-5FC4D526AC9B", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/..", + "6A57C0EFFA2BEA231211B8412CEAF2E3BCCFF7BE" : "Log4G\/" + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "Log4G", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/Log4G.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/Log4G.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "6A57C0EFFA2BEA231211B8412CEAF2E3BCCFF7BE" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/xcshareddata/xcschemes/Log4G-Example.xcscheme b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/xcshareddata/xcschemes/Log4G-Example.xcscheme new file mode 100644 index 0000000..eea380a --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/xcshareddata/xcschemes/Log4G-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/xcshareddata/xcschemes/Log4G.xcscheme b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/xcshareddata/xcschemes/Log4G.xcscheme new file mode 100644 index 0000000..6128dd3 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G.xcodeproj/xcshareddata/xcschemes/Log4G.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/Log4G/Example/Log4G.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/Log4G/Example/Log4G.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..a05a6b1 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/Log4G/Example/Log4G/AppDelegate.swift b/Carthage/Checkouts/Log4G/Example/Log4G/AppDelegate.swift new file mode 100644 index 0000000..32dac93 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G/AppDelegate.swift @@ -0,0 +1,23 @@ +// +// AppDelegate.swift +// Log4G +// +// Created by zixun on 01/10/2017. +// Copyright (c) 2017 zixun. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + +} + diff --git a/Carthage/Checkouts/Log4G/Example/Log4G/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/Log4G/Example/Log4G/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..552e112 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G/Base.lproj/LaunchScreen.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/Log4G/Example/Log4G/Base.lproj/Main.storyboard b/Carthage/Checkouts/Log4G/Example/Log4G/Base.lproj/Main.storyboard new file mode 100644 index 0000000..52ea29e --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/Log4G/Example/Log4G/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/Log4G/Example/Log4G/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d3942e9 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/Carthage/Checkouts/Log4G/Example/Log4G/Info.plist b/Carthage/Checkouts/Log4G/Example/Log4G/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/Log4G/Example/Log4G/Log4G.h b/Carthage/Checkouts/Log4G/Example/Log4G/Log4G.h new file mode 100644 index 0000000..6ecabbf --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G/Log4G.h @@ -0,0 +1,19 @@ +// +// Log4G.h +// Log4G +// +// Created by zixun on 2017/3/21. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for Log4G. +FOUNDATION_EXPORT double Log4GVersionNumber; + +//! Project version string for Log4G. +FOUNDATION_EXPORT const unsigned char Log4GVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/Log4G/Example/Log4G/ViewController.swift b/Carthage/Checkouts/Log4G/Example/Log4G/ViewController.swift new file mode 100644 index 0000000..4ed6595 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Log4G/ViewController.swift @@ -0,0 +1,86 @@ +// +// ViewController.swift +// Log4G +// +// Created by zixun on 01/10/2017. +// Copyright (c) 2017 zixun. All rights reserved. +// + +import UIKit +import Log4G + + +class ViewController: UIViewController,Log4GDelegate { + + override func viewDidLoad() { + super.viewDidLoad() + + let btn = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 100)) + btn.backgroundColor = UIColor.yellow + btn.setTitle("Present", for: .normal) + btn.addTarget(self, action: #selector(ViewController.presentViewController2), for: .touchUpInside) + self.view.addSubview(btn) + + let btn2 = UIButton(frame: CGRect(x: 100, y: 250, width: 100, height: 100)) + btn2.backgroundColor = UIColor.red + btn2.setTitle("LOG", for: .normal) + btn2.addTarget(self, action: #selector(ViewController.log), for: .touchUpInside) + self.view.addSubview(btn2) + + Log4G.add(delegate: self) + + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + } + + @objc private func presentViewController2() { + self.present(ViewController2(), animated: true, completion: nil) + } + + @objc private func log() { + Log4G.log("log") + } + func log4gDidRecord(with model:LogModel) { + print(model) + print("ViewController log4gDidRecord") + } +} + + + +class ViewController2: UIViewController,Log4GDelegate { + + override func viewDidLoad() { + super.viewDidLoad() + self.view.backgroundColor = UIColor.red + + let btn = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 100)) + btn.backgroundColor = UIColor.yellow + btn.setTitle("Dismiss", for: .normal) + btn.addTarget(self, action: #selector(ViewController2.dismissSelf), for: .touchUpInside) + self.view.addSubview(btn) + + Log4G.add(delegate: self) + + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + Log4G.log("ViewController2") + } + + deinit { + print("ViewController2 deinit") + } + + @objc private func dismissSelf() { + self.dismiss(animated: true, completion: nil) + } + + func log4gDidRecord(with model:LogModel) { + print(model) + print("ViewController2 log4gDidRecord") + } +} diff --git a/Carthage/Checkouts/Log4G/Example/Podfile b/Carthage/Checkouts/Log4G/Example/Podfile new file mode 100644 index 0000000..9b8ae09 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Podfile @@ -0,0 +1,11 @@ +use_frameworks! + +target 'Log4G_Example' do + pod 'Log4G', :path => '../' + + target 'Log4G_Tests' do + inherit! :search_paths + + + end +end diff --git a/Carthage/Checkouts/Log4G/Example/Podfile.lock b/Carthage/Checkouts/Log4G/Example/Podfile.lock new file mode 100644 index 0000000..e127676 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - Log4G (0.1.0) + +DEPENDENCIES: + - Log4G (from `../`) + +EXTERNAL SOURCES: + Log4G: + :path: "../" + +SPEC CHECKSUMS: + Log4G: f03eeb05f55a8602779d8c57dce0bf32bf0e0820 + +PODFILE CHECKSUM: 81a56c400e4e3d22ee496be04e2e43d21e6071c8 + +COCOAPODS: 1.1.1 diff --git a/Carthage/Checkouts/Log4G/Example/Tests/Info.plist b/Carthage/Checkouts/Log4G/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/Log4G/Example/Tests/Tests.swift b/Carthage/Checkouts/Log4G/Example/Tests/Tests.swift new file mode 100644 index 0000000..eb38fee --- /dev/null +++ b/Carthage/Checkouts/Log4G/Example/Tests/Tests.swift @@ -0,0 +1,29 @@ +import UIKit +import XCTest +import Log4G + +class Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + XCTAssert(true, "Pass") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure() { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Carthage/Checkouts/Log4G/LICENSE b/Carthage/Checkouts/Log4G/LICENSE new file mode 100644 index 0000000..be8a1fd --- /dev/null +++ b/Carthage/Checkouts/Log4G/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2017 Yilong Chen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Carthage/Checkouts/Log4G/Log4G.podspec b/Carthage/Checkouts/Log4G/Log4G.podspec new file mode 100644 index 0000000..3a3ee14 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Log4G.podspec @@ -0,0 +1,42 @@ +# +# Be sure to run `pod lib lint Log4G.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'Log4G' + s.version = '0.2.0' + s.summary = 'Simple, lightweight logging framework written in Swift.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +Simple, lightweight logging framework written in Swift.4G means for GodEye, it was development for GodEye at the beginning of the time. + DESC + + s.homepage = 'https://github.com/zixun/Log4G' + # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'zixun' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/Log4G.git', :tag => s.version.to_s } + # s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'Log4G/Classes/**/*' + + # s.resource_bundles = { + # 'Log4G' => ['Log4G/Assets/*.png'] + # } + + # s.public_header_files = 'Pod/Classes/**/*.h' + # s.frameworks = 'UIKit', 'MapKit' + # s.dependency 'AFNetworking', '~> 2.3' +end diff --git a/Carthage/Checkouts/Log4G/Log4G/Classes/Log4G.swift b/Carthage/Checkouts/Log4G/Log4G/Classes/Log4G.swift new file mode 100644 index 0000000..8224980 --- /dev/null +++ b/Carthage/Checkouts/Log4G/Log4G/Classes/Log4G.swift @@ -0,0 +1,197 @@ +// +// Log4G.swift +// Pods +// +// Created by zixun on 17/1/10. +// +// + +import Foundation + +//-------------------------------------------------------------------------- +// MARK: - Log4gDelegate +//-------------------------------------------------------------------------- +public protocol Log4GDelegate: NSObjectProtocol { + func log4gDidRecord(with model:LogModel) +} + +//-------------------------------------------------------------------------- +// MARK: - WeakLog4gDelegate +// DESCRIPTION: Weak wrap of delegate +//-------------------------------------------------------------------------- +class WeakLog4GDelegate: NSObject { + weak var delegate : Log4GDelegate? + init (delegate: Log4GDelegate) { + super.init() + self.delegate = delegate + } +} + +//-------------------------------------------------------------------------- +// MARK: - Log4G +// DESCRIPTION: Simple, lightweight logging framework written in Swift +// 4G means for GodEye, it was development for GodEye at the beginning of the time +//-------------------------------------------------------------------------- +open class Log4G: NSObject { + + //-------------------------------------------------------------------------- + // MARK: OPEN FUNCTION + //-------------------------------------------------------------------------- + + /// record a log type message + /// + /// - Parameters: + /// - message: log message + /// - file: file which call the api + /// - line: line number at file which call the api + /// - function: function name which call the api + open class func log(_ message: Any = "", + file: String = #file, + line: Int = #line, + function: String = #function) { + self.shared.record(type: .log, + thread: Thread.current, + message: "\(message)", + file: file, + line: line, + function: function) + } + + /// record a warning type message + /// + /// - Parameters: + /// - message: warning message + /// - file: file which call the api + /// - line: line number at file which call the api + /// - function: function name which call the api + open class func warning(_ message: Any = "", + file: String = #file, + line: Int = #line, + function: String = #function) { + self.shared.record(type: .warning, + thread: Thread.current, + message: "\(message)", + file: file, + line: line, + function: function) + } + + /// record an error type message + /// + /// - Parameters: + /// - message: error message + /// - file: file which call the api + /// - line: line number at file which call the api + /// - function: function name which call the api + open class func error(_ message: Any = "", + file: String = #file, + line: Int = #line, + function: String = #function) { + self.shared.record(type: .error, + thread: Thread.current, + message: "\(message)", + file: file, + line: line, + function: function) + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE FUNCTION + //-------------------------------------------------------------------------- + + /// record message base function + /// + /// - Parameters: + /// - type: log type + /// - thread: thread which log the messsage + /// - message: log message + /// - file: file which call the api + /// - line: line number at file which call the api + /// - function: function name which call the api + private func record(type:Log4gType, + thread:Thread, + message: String, + file: String, + line: Int, + function: String) { + self.queue.async { + let model = LogModel(type: type, + thread: thread, + message: message, + file: self.name(of: file), + line: line, + function: function) + print(message) + + for delegate in self.delegates { + delegate.delegate?.log4gDidRecord(with: model) + } + + } + } + + /// get the name of file in filepath + /// + /// - Parameter file: path of file + /// - Returns: filename + private func name(of file:String) -> String { + return URL(fileURLWithPath: file).lastPathComponent + } + + + //MARK: - Private Variable + + /// singleton for Log4g + fileprivate static let shared = Log4G() + /// log queue + private let queue = DispatchQueue(label: "Log4g") + /// weak delegates + fileprivate var delegates = [WeakLog4GDelegate]() + +} + +//-------------------------------------------------------------------------- +// MARK: - Log4gDelegate Fucntion Extension +//-------------------------------------------------------------------------- +extension Log4G { + + open class var delegateCount: Int { + get { + return self.shared.delegates.count + } + } + + open class func add(delegate:Log4GDelegate) { + let log4g = self.shared + + // delete null week delegate + log4g.delegates = log4g.delegates.filter { + return $0.delegate != nil + } + + // judge if contains the delegate from parameter + let contains = log4g.delegates.contains { + return $0.delegate?.hash == delegate.hash + } + // if not contains, append it with weak wrapped + if contains == false { + let week = WeakLog4GDelegate(delegate: delegate) + + self.shared.delegates.append(week) + } + } + + open class func remove(delegate:Log4GDelegate) { + let log4g = self.shared + + log4g.delegates = log4g.delegates.filter { + // filter null weak delegate + return $0.delegate != nil + }.filter { + // filter the delegate from parameter + return $0.delegate?.hash != delegate.hash + } + } +} + + diff --git a/Carthage/Checkouts/Log4G/Log4G/Classes/LogModel.swift b/Carthage/Checkouts/Log4G/Log4G/Classes/LogModel.swift new file mode 100644 index 0000000..0510dee --- /dev/null +++ b/Carthage/Checkouts/Log4G/Log4G/Classes/LogModel.swift @@ -0,0 +1,54 @@ +// +// LogModel.swift +// Pods +// +// Created by zixun on 17/1/10. +// +// + +import Foundation + +public enum Log4gType: Int { + case log = 1 + case warning = 2 + case error = 3 +} + +open class LogModel: NSObject { + + open private(set) var type: Log4gType! + + /// date for Time stamp + open private(set) var date: Date! + + /// thread which log the message + open private(set) var thread: Thread! + + /// filename with extension + open private(set) var file: String! + + /// number of line in source code file + open private(set) var line: Int! + + /// name of the function which log the message + open private(set) var function: String! + + /// message be logged + open private(set) var message: String! + + init(type:Log4gType, + thread:Thread, + message: String, + file: String, + line: Int, + function: String) { + super.init() + self.date = Date() + self.type = type + self.thread = thread + self.file = file + self.line = line + self.function = function + self.message = message + } +} diff --git a/Carthage/Checkouts/Log4G/README.md b/Carthage/Checkouts/Log4G/README.md new file mode 100644 index 0000000..090ab9d --- /dev/null +++ b/Carthage/Checkouts/Log4G/README.md @@ -0,0 +1,91 @@ +# Log4G + +[![Version](https://img.shields.io/cocoapods/v/Log4G.svg?style=flat)](http://cocoapods.org/pods/Log4G) +[![License](https://img.shields.io/cocoapods/l/Log4G.svg?style=flat)](http://cocoapods.org/pods/Log4G) +[![Platform](https://img.shields.io/cocoapods/p/Log4G.svg?style=flat)](http://cocoapods.org/pods/Log4G) +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) + +Simple, lightweight logging framework written in Swift + +## Context +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly disply Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Features + +- [x] Log type support: `log`,`warning`,`error`. +- [x] Automaticly get log‘s file, line, function and thread. +- [x] Allow multiple delegate listeners to monitor log behavior. + + +## Installation + +### CocoaPods +Log4G is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "Log4G" +``` + +### Carthage +Or, if you’re using [Carthage](https://github.com/Carthage/Carthage), add SwViewCapture to your Cartfile: + +``` +github "zixun/Log4G" +``` + +## Usage +### Log a log type message + +```swift +Log4G.log("message") +``` + +### Log a warning type message + +```swift +Log4G.warning("message") +``` + +### Log an error type message + +```swift +Log4G.error("message") +``` + +### Add to the log delegate listener + +```swift +Log4G.add(delegate: self) +``` + +And implement delegate of `Log4GDelegate`: + +```swift +func log4gDidRecord(with model:LogModel) { + //Some Monitor Action +} +``` + +### Remove frome the log delegate listener +```swift +Log4G.remove(delegate: self) +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + + + +## License + +Log4G is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/Log4G/_Pods.xcodeproj b/Carthage/Checkouts/Log4G/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/Log4G/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/.gitignore b/Carthage/Checkouts/MJRefresh/.gitignore new file mode 100644 index 0000000..7b02935 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/.gitignore @@ -0,0 +1,18 @@ +.DS_Store + +# Xcode +build/* +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +*.xcworkspace +!default.xcworkspace +xcuserdata +profile +*.moved-aside +*.xcuserstate diff --git a/Carthage/Checkouts/MJRefresh/Carthage/Build b/Carthage/Checkouts/MJRefresh/Carthage/Build new file mode 120000 index 0000000..76f9ba2 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/Carthage/Build @@ -0,0 +1 @@ +../../../../Carthage/Build \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/LICENSE b/Carthage/Checkouts/MJRefresh/LICENSE new file mode 100644 index 0000000..11bf234 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh.podspec b/Carthage/Checkouts/MJRefresh/MJRefresh.podspec new file mode 100644 index 0000000..e676c61 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh.podspec @@ -0,0 +1,13 @@ +Pod::Spec.new do |s| + s.name = 'MJRefresh' + s.version = '3.1.12' + s.summary = 'An easy way to use pull-to-refresh' + s.homepage = 'https://github.com/CoderMJLee/MJRefresh' + s.license = 'MIT' + s.authors = {'MJ Lee' => '199109106@qq.com'} + s.platform = :ios, '6.0' + s.source = {:git => 'https://github.com/CoderMJLee/MJRefresh.git', :tag => s.version} + s.source_files = 'MJRefresh/**/*.{h,m}' + s.resource = 'MJRefresh/MJRefresh.bundle' + s.requires_arc = true +end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.h new file mode 100644 index 0000000..82a0249 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.h @@ -0,0 +1,20 @@ +// +// MJRefreshAutoFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshFooter.h" + +@interface MJRefreshAutoFooter : MJRefreshFooter +/** 是否自动刷新(默认为YES) */ +@property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; + +/** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ +@property (assign, nonatomic) CGFloat appearencePercentTriggerAutoRefresh MJRefreshDeprecated("请使用triggerAutomaticallyRefreshPercent属性"); + +/** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ +@property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.m new file mode 100644 index 0000000..7327096 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshAutoFooter.m @@ -0,0 +1,139 @@ +// +// MJRefreshAutoFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoFooter.h" + +@interface MJRefreshAutoFooter() +@end + +@implementation MJRefreshAutoFooter + +#pragma mark - 初始化 +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + if (newSuperview) { // 新的父控件 + if (self.hidden == NO) { + self.scrollView.mj_insetB += self.mj_h; + } + + // 设置位置 + self.mj_y = _scrollView.mj_contentH; + } else { // 被移除了 + if (self.hidden == NO) { + self.scrollView.mj_insetB -= self.mj_h; + } + } +} + +#pragma mark - 过期方法 +- (void)setAppearencePercentTriggerAutoRefresh:(CGFloat)appearencePercentTriggerAutoRefresh +{ + self.triggerAutomaticallyRefreshPercent = appearencePercentTriggerAutoRefresh; +} + +- (CGFloat)appearencePercentTriggerAutoRefresh +{ + return self.triggerAutomaticallyRefreshPercent; +} + +#pragma mark - 实现父类的方法 +- (void)prepare +{ + [super prepare]; + + // 默认底部控件100%出现时才会自动刷新 + self.triggerAutomaticallyRefreshPercent = 1.0; + + // 设置为默认状态 + self.automaticallyRefresh = YES; +} + +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change +{ + [super scrollViewContentSizeDidChange:change]; + + // 设置位置 + self.mj_y = self.scrollView.mj_contentH; +} + +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change +{ + [super scrollViewContentOffsetDidChange:change]; + + if (self.state != MJRefreshStateIdle || !self.automaticallyRefresh || self.mj_y == 0) return; + + if (_scrollView.mj_insetT + _scrollView.mj_contentH > _scrollView.mj_h) { // 内容超过一个屏幕 + // 这里的_scrollView.mj_contentH替换掉self.mj_y更为合理 + if (_scrollView.mj_offsetY >= _scrollView.mj_contentH - _scrollView.mj_h + self.mj_h * self.triggerAutomaticallyRefreshPercent + _scrollView.mj_insetB - self.mj_h) { + // 防止手松开时连续调用 + CGPoint old = [change[@"old"] CGPointValue]; + CGPoint new = [change[@"new"] CGPointValue]; + if (new.y <= old.y) return; + + // 当底部刷新控件完全出现时,才刷新 + [self beginRefreshing]; + } + } +} + +- (void)scrollViewPanStateDidChange:(NSDictionary *)change +{ + [super scrollViewPanStateDidChange:change]; + + if (self.state != MJRefreshStateIdle) return; + + if (_scrollView.panGestureRecognizer.state == UIGestureRecognizerStateEnded) {// 手松开 + if (_scrollView.mj_insetT + _scrollView.mj_contentH <= _scrollView.mj_h) { // 不够一个屏幕 + if (_scrollView.mj_offsetY >= - _scrollView.mj_insetT) { // 向上拽 + [self beginRefreshing]; + } + } else { // 超出一个屏幕 + if (_scrollView.mj_offsetY >= _scrollView.mj_contentH + _scrollView.mj_insetB - _scrollView.mj_h) { + [self beginRefreshing]; + } + } + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + if (state == MJRefreshStateRefreshing) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self executeRefreshingCallback]; + }); + } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { + if (MJRefreshStateRefreshing == oldState) { + if (self.endRefreshingCompletionBlock) { + self.endRefreshingCompletionBlock(); + } + } + } +} + +- (void)setHidden:(BOOL)hidden +{ + BOOL lastHidden = self.isHidden; + + [super setHidden:hidden]; + + if (!lastHidden && hidden) { + self.state = MJRefreshStateIdle; + + self.scrollView.mj_insetB -= self.mj_h; + } else if (lastHidden && !hidden) { + self.scrollView.mj_insetB += self.mj_h; + + // 设置位置 + self.mj_y = _scrollView.mj_contentH; + } +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.h new file mode 100644 index 0000000..347083c --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.h @@ -0,0 +1,13 @@ +// +// MJRefreshBackFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshFooter.h" + +@interface MJRefreshBackFooter : MJRefreshFooter + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.m new file mode 100644 index 0000000..83978ad --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshBackFooter.m @@ -0,0 +1,160 @@ +// +// MJRefreshBackFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackFooter.h" + +@interface MJRefreshBackFooter() +@property (assign, nonatomic) NSInteger lastRefreshCount; +@property (assign, nonatomic) CGFloat lastBottomDelta; +@end + +@implementation MJRefreshBackFooter + +#pragma mark - 初始化 +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + [self scrollViewContentSizeDidChange:nil]; +} + +#pragma mark - 实现父类的方法 +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change +{ + [super scrollViewContentOffsetDidChange:change]; + + // 如果正在刷新,直接返回 + if (self.state == MJRefreshStateRefreshing) return; + + _scrollViewOriginalInset = self.scrollView.contentInset; + + // 当前的contentOffset + CGFloat currentOffsetY = self.scrollView.mj_offsetY; + // 尾部控件刚好出现的offsetY + CGFloat happenOffsetY = [self happenOffsetY]; + // 如果是向下滚动到看不见尾部控件,直接返回 + if (currentOffsetY <= happenOffsetY) return; + + CGFloat pullingPercent = (currentOffsetY - happenOffsetY) / self.mj_h; + + // 如果已全部加载,仅设置pullingPercent,然后返回 + if (self.state == MJRefreshStateNoMoreData) { + self.pullingPercent = pullingPercent; + return; + } + + if (self.scrollView.isDragging) { + self.pullingPercent = pullingPercent; + // 普通 和 即将刷新 的临界点 + CGFloat normal2pullingOffsetY = happenOffsetY + self.mj_h; + + if (self.state == MJRefreshStateIdle && currentOffsetY > normal2pullingOffsetY) { + // 转为即将刷新状态 + self.state = MJRefreshStatePulling; + } else if (self.state == MJRefreshStatePulling && currentOffsetY <= normal2pullingOffsetY) { + // 转为普通状态 + self.state = MJRefreshStateIdle; + } + } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 + // 开始刷新 + [self beginRefreshing]; + } else if (pullingPercent < 1) { + self.pullingPercent = pullingPercent; + } +} + +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change +{ + [super scrollViewContentSizeDidChange:change]; + + // 内容的高度 + CGFloat contentHeight = self.scrollView.mj_contentH + self.ignoredScrollViewContentInsetBottom; + // 表格的高度 + CGFloat scrollHeight = self.scrollView.mj_h - self.scrollViewOriginalInset.top - self.scrollViewOriginalInset.bottom + self.ignoredScrollViewContentInsetBottom; + // 设置位置和尺寸 + self.mj_y = MAX(contentHeight, scrollHeight); +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态来设置属性 + if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { + // 刷新完毕 + if (MJRefreshStateRefreshing == oldState) { + [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ + self.scrollView.mj_insetB -= self.lastBottomDelta; + + // 自动调整透明度 + if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; + } completion:^(BOOL finished) { + self.pullingPercent = 0.0; + + if (self.endRefreshingCompletionBlock) { + self.endRefreshingCompletionBlock(); + } + }]; + } + + CGFloat deltaH = [self heightForContentBreakView]; + // 刚刷新完毕 + if (MJRefreshStateRefreshing == oldState && deltaH > 0 && self.scrollView.mj_totalDataCount != self.lastRefreshCount) { + self.scrollView.mj_offsetY = self.scrollView.mj_offsetY; + } + } else if (state == MJRefreshStateRefreshing) { + // 记录刷新前的数量 + self.lastRefreshCount = self.scrollView.mj_totalDataCount; + + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ + CGFloat bottom = self.mj_h + self.scrollViewOriginalInset.bottom; + CGFloat deltaH = [self heightForContentBreakView]; + if (deltaH < 0) { // 如果内容高度小于view的高度 + bottom -= deltaH; + } + self.lastBottomDelta = bottom - self.scrollView.mj_insetB; + self.scrollView.mj_insetB = bottom; + self.scrollView.mj_offsetY = [self happenOffsetY] + self.mj_h; + } completion:^(BOOL finished) { + [self executeRefreshingCallback]; + }]; + } +} + +- (void)endRefreshing +{ + dispatch_async(dispatch_get_main_queue(), ^{ + self.state = MJRefreshStateIdle; + }); +} + +- (void)endRefreshingWithNoMoreData +{ + dispatch_async(dispatch_get_main_queue(), ^{ + self.state = MJRefreshStateNoMoreData; + }); +} +#pragma mark - 私有方法 +#pragma mark 获得scrollView的内容 超出 view 的高度 +- (CGFloat)heightForContentBreakView +{ + CGFloat h = self.scrollView.frame.size.height - self.scrollViewOriginalInset.bottom - self.scrollViewOriginalInset.top; + return self.scrollView.contentSize.height - h; +} + +#pragma mark 刚好看到上拉刷新控件时的contentOffset.y +- (CGFloat)happenOffsetY +{ + CGFloat deltaH = [self heightForContentBreakView]; + if (deltaH > 0) { + return deltaH - self.scrollViewOriginalInset.top; + } else { + return - self.scrollViewOriginalInset.top; + } +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshComponent.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshComponent.h new file mode 100644 index 0000000..9e96c89 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshComponent.h @@ -0,0 +1,106 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshComponent.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// 刷新控件的基类 + +#import +#import "MJRefreshConst.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" +#import "NSBundle+MJRefresh.h" + +/** 刷新控件的状态 */ +typedef NS_ENUM(NSInteger, MJRefreshState) { + /** 普通闲置状态 */ + MJRefreshStateIdle = 1, + /** 松开就可以进行刷新的状态 */ + MJRefreshStatePulling, + /** 正在刷新中的状态 */ + MJRefreshStateRefreshing, + /** 即将刷新的状态 */ + MJRefreshStateWillRefresh, + /** 所有数据加载完毕,没有更多的数据了 */ + MJRefreshStateNoMoreData +}; + +/** 进入刷新状态的回调 */ +typedef void (^MJRefreshComponentRefreshingBlock)(); +/** 开始刷新后的回调(进入刷新状态后的回调) */ +typedef void (^MJRefreshComponentbeginRefreshingCompletionBlock)(); +/** 结束刷新后的回调 */ +typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(); + +/** 刷新控件的基类 */ +@interface MJRefreshComponent : UIView +{ + /** 记录scrollView刚开始的inset */ + UIEdgeInsets _scrollViewOriginalInset; + /** 父控件 */ + __weak UIScrollView *_scrollView; +} +#pragma mark - 刷新回调 +/** 正在刷新的回调 */ +@property (copy, nonatomic) MJRefreshComponentRefreshingBlock refreshingBlock; +/** 设置回调对象和回调方法 */ +- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** 回调对象 */ +@property (weak, nonatomic) id refreshingTarget; +/** 回调方法 */ +@property (assign, nonatomic) SEL refreshingAction; +/** 触发回调(交给子类去调用) */ +- (void)executeRefreshingCallback; + +#pragma mark - 刷新状态控制 +/** 进入刷新状态 */ +- (void)beginRefreshing; +- (void)beginRefreshingWithCompletionBlock:(void (^)())completionBlock; +/** 开始刷新后的回调(进入刷新状态后的回调) */ +@property (copy, nonatomic) MJRefreshComponentbeginRefreshingCompletionBlock beginRefreshingCompletionBlock; +/** 结束刷新的回调 */ +@property (copy, nonatomic) MJRefreshComponentEndRefreshingCompletionBlock endRefreshingCompletionBlock; +/** 结束刷新状态 */ +- (void)endRefreshing; +- (void)endRefreshingWithCompletionBlock:(void (^)())completionBlock; +/** 是否正在刷新 */ +- (BOOL)isRefreshing; +/** 刷新状态 一般交给子类内部实现 */ +@property (assign, nonatomic) MJRefreshState state; + +#pragma mark - 交给子类去访问 +/** 记录scrollView刚开始的inset */ +@property (assign, nonatomic, readonly) UIEdgeInsets scrollViewOriginalInset; +/** 父控件 */ +@property (weak, nonatomic, readonly) UIScrollView *scrollView; + +#pragma mark - 交给子类们去实现 +/** 初始化 */ +- (void)prepare NS_REQUIRES_SUPER; +/** 摆放子控件frame */ +- (void)placeSubviews NS_REQUIRES_SUPER; +/** 当scrollView的contentOffset发生改变的时候调用 */ +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change NS_REQUIRES_SUPER; +/** 当scrollView的contentSize发生改变的时候调用 */ +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change NS_REQUIRES_SUPER; +/** 当scrollView的拖拽状态发生改变的时候调用 */ +- (void)scrollViewPanStateDidChange:(NSDictionary *)change NS_REQUIRES_SUPER; + + +#pragma mark - 其他 +/** 拉拽的百分比(交给子类重写) */ +@property (assign, nonatomic) CGFloat pullingPercent; +/** 根据拖拽比例自动切换透明度 */ +@property (assign, nonatomic, getter=isAutoChangeAlpha) BOOL autoChangeAlpha MJRefreshDeprecated("请使用automaticallyChangeAlpha属性"); +/** 根据拖拽比例自动切换透明度 */ +@property (assign, nonatomic, getter=isAutomaticallyChangeAlpha) BOOL automaticallyChangeAlpha; +@end + +@interface UILabel(MJRefresh) ++ (instancetype)mj_label; +- (CGFloat)mj_textWith; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshComponent.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshComponent.m new file mode 100644 index 0000000..fec5ed7 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshComponent.m @@ -0,0 +1,274 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshComponent.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshComponent.h" +#import "MJRefreshConst.h" + +@interface MJRefreshComponent() +@property (strong, nonatomic) UIPanGestureRecognizer *pan; +@end + +@implementation MJRefreshComponent +#pragma mark - 初始化 +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + // 准备工作 + [self prepare]; + + // 默认是普通状态 + self.state = MJRefreshStateIdle; + } + return self; +} + +- (void)prepare +{ + // 基本属性 + self.autoresizingMask = UIViewAutoresizingFlexibleWidth; + self.backgroundColor = [UIColor clearColor]; +} + +- (void)layoutSubviews +{ + [self placeSubviews]; + + [super layoutSubviews]; +} + +- (void)placeSubviews{} + +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + // 如果不是UIScrollView,不做任何事情 + if (newSuperview && ![newSuperview isKindOfClass:[UIScrollView class]]) return; + + // 旧的父控件移除监听 + [self removeObservers]; + + if (newSuperview) { // 新的父控件 + // 设置宽度 + self.mj_w = newSuperview.mj_w; + // 设置位置 + self.mj_x = 0; + + // 记录UIScrollView + _scrollView = (UIScrollView *)newSuperview; + // 设置永远支持垂直弹簧效果 + _scrollView.alwaysBounceVertical = YES; + // 记录UIScrollView最开始的contentInset + _scrollViewOriginalInset = _scrollView.contentInset; + + // 添加监听 + [self addObservers]; + } +} + +- (void)drawRect:(CGRect)rect +{ + [super drawRect:rect]; + + if (self.state == MJRefreshStateWillRefresh) { + // 预防view还没显示出来就调用了beginRefreshing + self.state = MJRefreshStateRefreshing; + } +} + +#pragma mark - KVO监听 +- (void)addObservers +{ + NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld; + [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentOffset options:options context:nil]; + [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentSize options:options context:nil]; + self.pan = self.scrollView.panGestureRecognizer; + [self.pan addObserver:self forKeyPath:MJRefreshKeyPathPanState options:options context:nil]; +} + +- (void)removeObservers +{ + [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentOffset]; + [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentSize];; + [self.pan removeObserver:self forKeyPath:MJRefreshKeyPathPanState]; + self.pan = nil; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // 遇到这些情况就直接返回 + if (!self.userInteractionEnabled) return; + + // 这个就算看不见也需要处理 + if ([keyPath isEqualToString:MJRefreshKeyPathContentSize]) { + [self scrollViewContentSizeDidChange:change]; + } + + // 看不见 + if (self.hidden) return; + if ([keyPath isEqualToString:MJRefreshKeyPathContentOffset]) { + [self scrollViewContentOffsetDidChange:change]; + } else if ([keyPath isEqualToString:MJRefreshKeyPathPanState]) { + [self scrollViewPanStateDidChange:change]; + } +} + +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{} +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change{} +- (void)scrollViewPanStateDidChange:(NSDictionary *)change{} + +#pragma mark - 公共方法 +#pragma mark 设置回调对象和回调方法 +- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + self.refreshingTarget = target; + self.refreshingAction = action; +} + +- (void)setState:(MJRefreshState)state +{ + _state = state; + + // 加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件 + dispatch_async(dispatch_get_main_queue(), ^{ + [self setNeedsLayout]; + }); +} + +#pragma mark 进入刷新状态 +- (void)beginRefreshing +{ + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ + self.alpha = 1.0; + }]; + self.pullingPercent = 1.0; + // 只要正在刷新,就完全显示 + if (self.window) { + self.state = MJRefreshStateRefreshing; + } else { + // 预防正在刷新中时,调用本方法使得header inset回置失败 + if (self.state != MJRefreshStateRefreshing) { + self.state = MJRefreshStateWillRefresh; + // 刷新(预防从另一个控制器回到这个控制器的情况,回来要重新刷新一下) + [self setNeedsDisplay]; + } + } +} + +- (void)beginRefreshingWithCompletionBlock:(void (^)())completionBlock +{ + self.beginRefreshingCompletionBlock = completionBlock; + + [self beginRefreshing]; +} + +#pragma mark 结束刷新状态 +- (void)endRefreshing +{ + self.state = MJRefreshStateIdle; +} + +- (void)endRefreshingWithCompletionBlock:(void (^)())completionBlock +{ + self.endRefreshingCompletionBlock = completionBlock; + + [self endRefreshing]; +} + +#pragma mark 是否正在刷新 +- (BOOL)isRefreshing +{ + return self.state == MJRefreshStateRefreshing || self.state == MJRefreshStateWillRefresh; +} + +#pragma mark 自动切换透明度 +- (void)setAutoChangeAlpha:(BOOL)autoChangeAlpha +{ + self.automaticallyChangeAlpha = autoChangeAlpha; +} + +- (BOOL)isAutoChangeAlpha +{ + return self.isAutomaticallyChangeAlpha; +} + +- (void)setAutomaticallyChangeAlpha:(BOOL)automaticallyChangeAlpha +{ + _automaticallyChangeAlpha = automaticallyChangeAlpha; + + if (self.isRefreshing) return; + + if (automaticallyChangeAlpha) { + self.alpha = self.pullingPercent; + } else { + self.alpha = 1.0; + } +} + +#pragma mark 根据拖拽进度设置透明度 +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + _pullingPercent = pullingPercent; + + if (self.isRefreshing) return; + + if (self.isAutomaticallyChangeAlpha) { + self.alpha = pullingPercent; + } +} + +#pragma mark - 内部方法 +- (void)executeRefreshingCallback +{ + dispatch_async(dispatch_get_main_queue(), ^{ + if (self.refreshingBlock) { + self.refreshingBlock(); + } + if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) { + MJRefreshMsgSend(MJRefreshMsgTarget(self.refreshingTarget), self.refreshingAction, self); + } + if (self.beginRefreshingCompletionBlock) { + self.beginRefreshingCompletionBlock(); + } + }); +} +@end + +@implementation UILabel(MJRefresh) ++ (instancetype)mj_label +{ + UILabel *label = [[self alloc] init]; + label.font = MJRefreshLabelFont; + label.textColor = MJRefreshLabelTextColor; + label.autoresizingMask = UIViewAutoresizingFlexibleWidth; + label.textAlignment = NSTextAlignmentCenter; + label.backgroundColor = [UIColor clearColor]; + return label; +} + +- (CGFloat)mj_textWith { + CGFloat stringWidth = 0; + CGSize size = CGSizeMake(MAXFLOAT, MAXFLOAT); + if (self.text.length > 0) { +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 + stringWidth =[self.text + boundingRectWithSize:size + options:NSStringDrawingUsesLineFragmentOrigin + attributes:@{NSFontAttributeName:self.font} + context:nil].size.width; +#else + + stringWidth = [self.text sizeWithFont:self.font + constrainedToSize:size + lineBreakMode:NSLineBreakByCharWrapping].width; +#endif + } + return stringWidth; +} +@end \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshFooter.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshFooter.h new file mode 100644 index 0000000..22d23e5 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshFooter.h @@ -0,0 +1,30 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// 上拉刷新控件 + +#import "MJRefreshComponent.h" + +@interface MJRefreshFooter : MJRefreshComponent +/** 创建footer */ ++ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; +/** 创建footer */ ++ (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** 提示没有更多的数据 */ +- (void)endRefreshingWithNoMoreData; +- (void)noticeNoMoreData MJRefreshDeprecated("使用endRefreshingWithNoMoreData"); + +/** 重置没有更多的数据(消除没有更多数据的状态) */ +- (void)resetNoMoreData; + +/** 忽略多少scrollView的contentInset的bottom */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom; + +/** 自动根据有无数据来显示和隐藏(有数据就显示,没有数据隐藏。默认是NO) */ +@property (assign, nonatomic, getter=isAutomaticallyHidden) BOOL automaticallyHidden; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshFooter.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshFooter.m new file mode 100644 index 0000000..69f65e7 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshFooter.m @@ -0,0 +1,74 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshFooter.h" + +@interface MJRefreshFooter() + +@end + +@implementation MJRefreshFooter +#pragma mark - 构造方法 ++ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock +{ + MJRefreshFooter *cmp = [[self alloc] init]; + cmp.refreshingBlock = refreshingBlock; + return cmp; +} ++ (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + MJRefreshFooter *cmp = [[self alloc] init]; + [cmp setRefreshingTarget:target refreshingAction:action]; + return cmp; +} + +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + + // 设置自己的高度 + self.mj_h = MJRefreshFooterHeight; + + // 默认不会自动隐藏 + self.automaticallyHidden = NO; +} + +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + if (newSuperview) { + // 监听scrollView数据的变化 + if ([self.scrollView isKindOfClass:[UITableView class]] || [self.scrollView isKindOfClass:[UICollectionView class]]) { + [self.scrollView setMj_reloadDataBlock:^(NSInteger totalDataCount) { + if (self.isAutomaticallyHidden) { + self.hidden = (totalDataCount == 0); + } + }]; + } + } +} + +#pragma mark - 公共方法 +- (void)endRefreshingWithNoMoreData +{ + self.state = MJRefreshStateNoMoreData; +} + +- (void)noticeNoMoreData +{ + [self endRefreshingWithNoMoreData]; +} + +- (void)resetNoMoreData +{ + self.state = MJRefreshStateIdle; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshHeader.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshHeader.h new file mode 100644 index 0000000..0816024 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshHeader.h @@ -0,0 +1,25 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshHeader.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// 下拉刷新控件:负责监控用户下拉的状态 + +#import "MJRefreshComponent.h" + +@interface MJRefreshHeader : MJRefreshComponent +/** 创建header */ ++ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; +/** 创建header */ ++ (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** 这个key用来存储上一次下拉刷新成功的时间 */ +@property (copy, nonatomic) NSString *lastUpdatedTimeKey; +/** 上一次下拉刷新成功的时间 */ +@property (strong, nonatomic, readonly) NSDate *lastUpdatedTime; + +/** 忽略多少scrollView的contentInset的top */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshHeader.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshHeader.m new file mode 100644 index 0000000..070cea6 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Base/MJRefreshHeader.m @@ -0,0 +1,153 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshHeader.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshHeader.h" + +@interface MJRefreshHeader() +@property (assign, nonatomic) CGFloat insetTDelta; +@end + +@implementation MJRefreshHeader +#pragma mark - 构造方法 ++ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock +{ + MJRefreshHeader *cmp = [[self alloc] init]; + cmp.refreshingBlock = refreshingBlock; + return cmp; +} ++ (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + MJRefreshHeader *cmp = [[self alloc] init]; + [cmp setRefreshingTarget:target refreshingAction:action]; + return cmp; +} + +#pragma mark - 覆盖父类的方法 +- (void)prepare +{ + [super prepare]; + + // 设置key + self.lastUpdatedTimeKey = MJRefreshHeaderLastUpdatedTimeKey; + + // 设置高度 + self.mj_h = MJRefreshHeaderHeight; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + // 设置y值(当自己的高度发生改变了,肯定要重新调整Y值,所以放到placeSubviews方法中设置y值) + self.mj_y = - self.mj_h - self.ignoredScrollViewContentInsetTop; +} + +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change +{ + [super scrollViewContentOffsetDidChange:change]; + + // 在刷新的refreshing状态 + if (self.state == MJRefreshStateRefreshing) { + if (self.window == nil) return; + + // sectionheader停留解决 + CGFloat insetT = - self.scrollView.mj_offsetY > _scrollViewOriginalInset.top ? - self.scrollView.mj_offsetY : _scrollViewOriginalInset.top; + insetT = insetT > self.mj_h + _scrollViewOriginalInset.top ? self.mj_h + _scrollViewOriginalInset.top : insetT; + self.scrollView.mj_insetT = insetT; + + self.insetTDelta = _scrollViewOriginalInset.top - insetT; + return; + } + + // 跳转到下一个控制器时,contentInset可能会变 + _scrollViewOriginalInset = self.scrollView.contentInset; + + // 当前的contentOffset + CGFloat offsetY = self.scrollView.mj_offsetY; + // 头部控件刚好出现的offsetY + CGFloat happenOffsetY = - self.scrollViewOriginalInset.top; + + // 如果是向上滚动到看不见头部控件,直接返回 + // >= -> > + if (offsetY > happenOffsetY) return; + + // 普通 和 即将刷新 的临界点 + CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_h; + CGFloat pullingPercent = (happenOffsetY - offsetY) / self.mj_h; + + if (self.scrollView.isDragging) { // 如果正在拖拽 + self.pullingPercent = pullingPercent; + if (self.state == MJRefreshStateIdle && offsetY < normal2pullingOffsetY) { + // 转为即将刷新状态 + self.state = MJRefreshStatePulling; + } else if (self.state == MJRefreshStatePulling && offsetY >= normal2pullingOffsetY) { + // 转为普通状态 + self.state = MJRefreshStateIdle; + } + } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开 + // 开始刷新 + [self beginRefreshing]; + } else if (pullingPercent < 1) { + self.pullingPercent = pullingPercent; + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateIdle) { + if (oldState != MJRefreshStateRefreshing) return; + + // 保存刷新时间 + [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:self.lastUpdatedTimeKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; + + // 恢复inset和offset + [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ + self.scrollView.mj_insetT += self.insetTDelta; + + // 自动调整透明度 + if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; + } completion:^(BOOL finished) { + self.pullingPercent = 0.0; + + if (self.endRefreshingCompletionBlock) { + self.endRefreshingCompletionBlock(); + } + }]; + } else if (state == MJRefreshStateRefreshing) { + dispatch_async(dispatch_get_main_queue(), ^{ + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ + CGFloat top = self.scrollViewOriginalInset.top + self.mj_h; + // 增加滚动区域top + self.scrollView.mj_insetT = top; + // 设置滚动位置 + [self.scrollView setContentOffset:CGPointMake(0, -top) animated:NO]; + } completion:^(BOOL finished) { + [self executeRefreshingCallback]; + }]; + }); + } +} + +#pragma mark - 公共方法 +- (void)endRefreshing +{ + dispatch_async(dispatch_get_main_queue(), ^{ + self.state = MJRefreshStateIdle; + }); +} + +- (NSDate *)lastUpdatedTime +{ + return [[NSUserDefaults standardUserDefaults] objectForKey:self.lastUpdatedTimeKey]; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h new file mode 100644 index 0000000..6a127e6 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.h @@ -0,0 +1,17 @@ +// +// MJRefreshAutoGifFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoStateFooter.h" + +@interface MJRefreshAutoGifFooter : MJRefreshAutoStateFooter +@property (weak, nonatomic, readonly) UIImageView *gifView; + +/** 设置state状态下的动画图片images 动画持续时间duration*/ +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m new file mode 100644 index 0000000..2507138 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoGifFooter.m @@ -0,0 +1,116 @@ +// +// MJRefreshAutoGifFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoGifFooter.h" + +@interface MJRefreshAutoGifFooter() +{ + __unsafe_unretained UIImageView *_gifView; +} +/** 所有状态对应的动画图片 */ +@property (strong, nonatomic) NSMutableDictionary *stateImages; +/** 所有状态对应的动画时间 */ +@property (strong, nonatomic) NSMutableDictionary *stateDurations; +@end + +@implementation MJRefreshAutoGifFooter +#pragma mark - 懒加载 +- (UIImageView *)gifView +{ + if (!_gifView) { + UIImageView *gifView = [[UIImageView alloc] init]; + [self addSubview:_gifView = gifView]; + } + return _gifView; +} + +- (NSMutableDictionary *)stateImages +{ + if (!_stateImages) { + self.stateImages = [NSMutableDictionary dictionary]; + } + return _stateImages; +} + +- (NSMutableDictionary *)stateDurations +{ + if (!_stateDurations) { + self.stateDurations = [NSMutableDictionary dictionary]; + } + return _stateDurations; +} + +#pragma mark - 公共方法 +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state +{ + if (images == nil) return; + + self.stateImages[@(state)] = images; + self.stateDurations[@(state)] = @(duration); + + /* 根据图片设置控件的高度 */ + UIImage *image = [images firstObject]; + if (image.size.height > self.mj_h) { + self.mj_h = image.size.height; + } +} + +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state +{ + [self setImages:images duration:images.count * 0.1 forState:state]; +} + +#pragma mark - 实现父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = 20; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.gifView.constraints.count) return; + + self.gifView.frame = self.bounds; + if (self.isRefreshingTitleHidden) { + self.gifView.contentMode = UIViewContentModeCenter; + } else { + self.gifView.contentMode = UIViewContentModeRight; + self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWith * 0.5; + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateRefreshing) { + NSArray *images = self.stateImages[@(state)]; + if (images.count == 0) return; + [self.gifView stopAnimating]; + + self.gifView.hidden = NO; + if (images.count == 1) { // 单张图片 + self.gifView.image = [images lastObject]; + } else { // 多张图片 + self.gifView.animationImages = images; + self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; + [self.gifView startAnimating]; + } + } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { + [self.gifView stopAnimating]; + self.gifView.hidden = YES; + } +} +@end + diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h new file mode 100644 index 0000000..5549cff --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.h @@ -0,0 +1,14 @@ +// +// MJRefreshAutoNormalFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoStateFooter.h" + +@interface MJRefreshAutoNormalFooter : MJRefreshAutoStateFooter +/** 菊花的样式 */ +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m new file mode 100644 index 0000000..dae9060 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoNormalFooter.m @@ -0,0 +1,69 @@ +// +// MJRefreshAutoNormalFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoNormalFooter.h" + +@interface MJRefreshAutoNormalFooter() +@property (weak, nonatomic) UIActivityIndicatorView *loadingView; +@end + +@implementation MJRefreshAutoNormalFooter +#pragma mark - 懒加载子控件 +- (UIActivityIndicatorView *)loadingView +{ + if (!_loadingView) { + UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorViewStyle]; + loadingView.hidesWhenStopped = YES; + [self addSubview:_loadingView = loadingView]; + } + return _loadingView; +} + +- (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle +{ + _activityIndicatorViewStyle = activityIndicatorViewStyle; + + self.loadingView = nil; + [self setNeedsLayout]; +} +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + + self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.loadingView.constraints.count) return; + + // 圈圈 + CGFloat loadingCenterX = self.mj_w * 0.5; + if (!self.isRefreshingTitleHidden) { + loadingCenterX -= self.stateLabel.mj_textWith * 0.5 + self.labelLeftInset; + } + CGFloat loadingCenterY = self.mj_h * 0.5; + self.loadingView.center = CGPointMake(loadingCenterX, loadingCenterY); +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { + [self.loadingView stopAnimating]; + } else if (state == MJRefreshStateRefreshing) { + [self.loadingView startAnimating]; + } +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h new file mode 100644 index 0000000..9fe7915 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.h @@ -0,0 +1,22 @@ +// +// MJRefreshAutoStateFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoFooter.h" + +@interface MJRefreshAutoStateFooter : MJRefreshAutoFooter +/** 文字距离圈圈、箭头的距离 */ +@property (assign, nonatomic) CGFloat labelLeftInset; +/** 显示刷新状态的label */ +@property (weak, nonatomic, readonly) UILabel *stateLabel; + +/** 设置state状态下的文字 */ +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state; + +/** 隐藏刷新状态的文字 */ +@property (assign, nonatomic, getter=isRefreshingTitleHidden) BOOL refreshingTitleHidden; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m new file mode 100644 index 0000000..d16547d --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Auto/MJRefreshAutoStateFooter.m @@ -0,0 +1,92 @@ +// +// MJRefreshAutoStateFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoStateFooter.h" + +@interface MJRefreshAutoStateFooter() +{ + /** 显示刷新状态的label */ + __unsafe_unretained UILabel *_stateLabel; +} +/** 所有状态对应的文字 */ +@property (strong, nonatomic) NSMutableDictionary *stateTitles; +@end + +@implementation MJRefreshAutoStateFooter +#pragma mark - 懒加载 +- (NSMutableDictionary *)stateTitles +{ + if (!_stateTitles) { + self.stateTitles = [NSMutableDictionary dictionary]; + } + return _stateTitles; +} + +- (UILabel *)stateLabel +{ + if (!_stateLabel) { + [self addSubview:_stateLabel = [UILabel mj_label]]; + } + return _stateLabel; +} + +#pragma mark - 公共方法 +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state +{ + if (title == nil) return; + self.stateTitles[@(state)] = title; + self.stateLabel.text = self.stateTitles[@(self.state)]; +} + +#pragma mark - 私有方法 +- (void)stateLabelClick +{ + if (self.state == MJRefreshStateIdle) { + [self beginRefreshing]; + } +} + +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = MJRefreshLabelLeftInset; + + // 初始化文字 + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterIdleText] forState:MJRefreshStateIdle]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterRefreshingText] forState:MJRefreshStateRefreshing]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshAutoFooterNoMoreDataText] forState:MJRefreshStateNoMoreData]; + + // 监听label + self.stateLabel.userInteractionEnabled = YES; + [self.stateLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(stateLabelClick)]]; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.stateLabel.constraints.count) return; + + // 状态标签 + self.stateLabel.frame = self.bounds; +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + if (self.isRefreshingTitleHidden && state == MJRefreshStateRefreshing) { + self.stateLabel.text = nil; + } else { + self.stateLabel.text = self.stateTitles[@(state)]; + } +} +@end \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h new file mode 100644 index 0000000..b29af86 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.h @@ -0,0 +1,17 @@ +// +// MJRefreshBackGifFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackStateFooter.h" + +@interface MJRefreshBackGifFooter : MJRefreshBackStateFooter +@property (weak, nonatomic, readonly) UIImageView *gifView; + +/** 设置state状态下的动画图片images 动画持续时间duration*/ +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.m new file mode 100644 index 0000000..fa97c72 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackGifFooter.m @@ -0,0 +1,127 @@ +// +// MJRefreshBackGifFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackGifFooter.h" + +@interface MJRefreshBackGifFooter() +{ + __unsafe_unretained UIImageView *_gifView; +} +/** 所有状态对应的动画图片 */ +@property (strong, nonatomic) NSMutableDictionary *stateImages; +/** 所有状态对应的动画时间 */ +@property (strong, nonatomic) NSMutableDictionary *stateDurations; +@end + +@implementation MJRefreshBackGifFooter +#pragma mark - 懒加载 +- (UIImageView *)gifView +{ + if (!_gifView) { + UIImageView *gifView = [[UIImageView alloc] init]; + [self addSubview:_gifView = gifView]; + } + return _gifView; +} + +- (NSMutableDictionary *)stateImages +{ + if (!_stateImages) { + self.stateImages = [NSMutableDictionary dictionary]; + } + return _stateImages; +} + +- (NSMutableDictionary *)stateDurations +{ + if (!_stateDurations) { + self.stateDurations = [NSMutableDictionary dictionary]; + } + return _stateDurations; +} + +#pragma mark - 公共方法 +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state +{ + if (images == nil) return; + + self.stateImages[@(state)] = images; + self.stateDurations[@(state)] = @(duration); + + /* 根据图片设置控件的高度 */ + UIImage *image = [images firstObject]; + if (image.size.height > self.mj_h) { + self.mj_h = image.size.height; + } +} + +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state +{ + [self setImages:images duration:images.count * 0.1 forState:state]; +} + +#pragma mark - 实现父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = 20; +} + +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + [super setPullingPercent:pullingPercent]; + NSArray *images = self.stateImages[@(MJRefreshStateIdle)]; + if (self.state != MJRefreshStateIdle || images.count == 0) return; + [self.gifView stopAnimating]; + NSUInteger index = images.count * pullingPercent; + if (index >= images.count) index = images.count - 1; + self.gifView.image = images[index]; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.gifView.constraints.count) return; + + self.gifView.frame = self.bounds; + if (self.stateLabel.hidden) { + self.gifView.contentMode = UIViewContentModeCenter; + } else { + self.gifView.contentMode = UIViewContentModeRight; + self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWith * 0.5; + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStatePulling || state == MJRefreshStateRefreshing) { + NSArray *images = self.stateImages[@(state)]; + if (images.count == 0) return; + + self.gifView.hidden = NO; + [self.gifView stopAnimating]; + if (images.count == 1) { // 单张图片 + self.gifView.image = [images lastObject]; + } else { // 多张图片 + self.gifView.animationImages = images; + self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; + [self.gifView startAnimating]; + } + } else if (state == MJRefreshStateIdle) { + self.gifView.hidden = NO; + } else if (state == MJRefreshStateNoMoreData) { + self.gifView.hidden = YES; + } +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h new file mode 100644 index 0000000..90e8b77 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.h @@ -0,0 +1,15 @@ +// +// MJRefreshBackNormalFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackStateFooter.h" + +@interface MJRefreshBackNormalFooter : MJRefreshBackStateFooter +@property (weak, nonatomic, readonly) UIImageView *arrowView; +/** 菊花的样式 */ +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.m new file mode 100644 index 0000000..30e5ecf --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackNormalFooter.m @@ -0,0 +1,120 @@ +// +// MJRefreshBackNormalFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackNormalFooter.h" +#import "NSBundle+MJRefresh.h" + +@interface MJRefreshBackNormalFooter() +{ + __unsafe_unretained UIImageView *_arrowView; +} +@property (weak, nonatomic) UIActivityIndicatorView *loadingView; +@end + +@implementation MJRefreshBackNormalFooter +#pragma mark - 懒加载子控件 +- (UIImageView *)arrowView +{ + if (!_arrowView) { + UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_arrowImage]]; + [self addSubview:_arrowView = arrowView]; + } + return _arrowView; +} + + +- (UIActivityIndicatorView *)loadingView +{ + if (!_loadingView) { + UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorViewStyle]; + loadingView.hidesWhenStopped = YES; + [self addSubview:_loadingView = loadingView]; + } + return _loadingView; +} + +- (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle +{ + _activityIndicatorViewStyle = activityIndicatorViewStyle; + + self.loadingView = nil; + [self setNeedsLayout]; +} +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + + self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + // 箭头的中心点 + CGFloat arrowCenterX = self.mj_w * 0.5; + if (!self.stateLabel.hidden) { + arrowCenterX -= self.labelLeftInset + self.stateLabel.mj_textWith * 0.5; + } + CGFloat arrowCenterY = self.mj_h * 0.5; + CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY); + + // 箭头 + if (self.arrowView.constraints.count == 0) { + self.arrowView.mj_size = self.arrowView.image.size; + self.arrowView.center = arrowCenter; + } + + // 圈圈 + if (self.loadingView.constraints.count == 0) { + self.loadingView.center = arrowCenter; + } + + self.arrowView.tintColor = self.stateLabel.textColor; +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateIdle) { + if (oldState == MJRefreshStateRefreshing) { + self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); + [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ + self.loadingView.alpha = 0.0; + } completion:^(BOOL finished) { + self.loadingView.alpha = 1.0; + [self.loadingView stopAnimating]; + + self.arrowView.hidden = NO; + }]; + } else { + self.arrowView.hidden = NO; + [self.loadingView stopAnimating]; + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); + }]; + } + } else if (state == MJRefreshStatePulling) { + self.arrowView.hidden = NO; + [self.loadingView stopAnimating]; + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformIdentity; + }]; + } else if (state == MJRefreshStateRefreshing) { + self.arrowView.hidden = YES; + [self.loadingView startAnimating]; + } else if (state == MJRefreshStateNoMoreData) { + self.arrowView.hidden = YES; + [self.loadingView stopAnimating]; + } +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h new file mode 100644 index 0000000..99b1483 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.h @@ -0,0 +1,21 @@ +// +// MJRefreshBackStateFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackFooter.h" + +@interface MJRefreshBackStateFooter : MJRefreshBackFooter +/** 文字距离圈圈、箭头的距离 */ +@property (assign, nonatomic) CGFloat labelLeftInset; +/** 显示刷新状态的label */ +@property (weak, nonatomic, readonly) UILabel *stateLabel; +/** 设置state状态下的文字 */ +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state; + +/** 获取state状态下的title */ +- (NSString *)titleForState:(MJRefreshState)state; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.m new file mode 100644 index 0000000..cc784d0 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Footer/Back/MJRefreshBackStateFooter.m @@ -0,0 +1,82 @@ +// +// MJRefreshBackStateFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackStateFooter.h" + +@interface MJRefreshBackStateFooter() +{ + /** 显示刷新状态的label */ + __unsafe_unretained UILabel *_stateLabel; +} +/** 所有状态对应的文字 */ +@property (strong, nonatomic) NSMutableDictionary *stateTitles; +@end + +@implementation MJRefreshBackStateFooter +#pragma mark - 懒加载 +- (NSMutableDictionary *)stateTitles +{ + if (!_stateTitles) { + self.stateTitles = [NSMutableDictionary dictionary]; + } + return _stateTitles; +} + +- (UILabel *)stateLabel +{ + if (!_stateLabel) { + [self addSubview:_stateLabel = [UILabel mj_label]]; + } + return _stateLabel; +} + +#pragma mark - 公共方法 +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state +{ + if (title == nil) return; + self.stateTitles[@(state)] = title; + self.stateLabel.text = self.stateTitles[@(self.state)]; +} + +- (NSString *)titleForState:(MJRefreshState)state { + return self.stateTitles[@(state)]; +} + +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = MJRefreshLabelLeftInset; + + // 初始化文字 + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterIdleText] forState:MJRefreshStateIdle]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterPullingText] forState:MJRefreshStatePulling]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterRefreshingText] forState:MJRefreshStateRefreshing]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshBackFooterNoMoreDataText] forState:MJRefreshStateNoMoreData]; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.stateLabel.constraints.count) return; + + // 状态标签 + self.stateLabel.frame = self.bounds; +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 设置状态文字 + self.stateLabel.text = self.stateTitles[@(state)]; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.h new file mode 100644 index 0000000..ce3ed42 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.h @@ -0,0 +1,17 @@ +// +// MJRefreshGifHeader.h +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshStateHeader.h" + +@interface MJRefreshGifHeader : MJRefreshStateHeader +@property (weak, nonatomic, readonly) UIImageView *gifView; + +/** 设置state状态下的动画图片images 动画持续时间duration*/ +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.m new file mode 100644 index 0000000..f8bcc9b --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshGifHeader.m @@ -0,0 +1,133 @@ +// +// MJRefreshGifHeader.m +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshGifHeader.h" + +@interface MJRefreshGifHeader() +{ + __unsafe_unretained UIImageView *_gifView; +} +/** 所有状态对应的动画图片 */ +@property (strong, nonatomic) NSMutableDictionary *stateImages; +/** 所有状态对应的动画时间 */ +@property (strong, nonatomic) NSMutableDictionary *stateDurations; +@end + +@implementation MJRefreshGifHeader +#pragma mark - 懒加载 +- (UIImageView *)gifView +{ + if (!_gifView) { + UIImageView *gifView = [[UIImageView alloc] init]; + [self addSubview:_gifView = gifView]; + } + return _gifView; +} + +- (NSMutableDictionary *)stateImages +{ + if (!_stateImages) { + self.stateImages = [NSMutableDictionary dictionary]; + } + return _stateImages; +} + +- (NSMutableDictionary *)stateDurations +{ + if (!_stateDurations) { + self.stateDurations = [NSMutableDictionary dictionary]; + } + return _stateDurations; +} + +#pragma mark - 公共方法 +- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state +{ + if (images == nil) return; + + self.stateImages[@(state)] = images; + self.stateDurations[@(state)] = @(duration); + + /* 根据图片设置控件的高度 */ + UIImage *image = [images firstObject]; + if (image.size.height > self.mj_h) { + self.mj_h = image.size.height; + } +} + +- (void)setImages:(NSArray *)images forState:(MJRefreshState)state +{ + [self setImages:images duration:images.count * 0.1 forState:state]; +} + +#pragma mark - 实现父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = 20; +} + +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + [super setPullingPercent:pullingPercent]; + NSArray *images = self.stateImages[@(MJRefreshStateIdle)]; + if (self.state != MJRefreshStateIdle || images.count == 0) return; + // 停止动画 + [self.gifView stopAnimating]; + // 设置当前需要显示的图片 + NSUInteger index = images.count * pullingPercent; + if (index >= images.count) index = images.count - 1; + self.gifView.image = images[index]; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.gifView.constraints.count) return; + + self.gifView.frame = self.bounds; + if (self.stateLabel.hidden && self.lastUpdatedTimeLabel.hidden) { + self.gifView.contentMode = UIViewContentModeCenter; + } else { + self.gifView.contentMode = UIViewContentModeRight; + + CGFloat stateWidth = self.stateLabel.mj_textWith; + CGFloat timeWidth = 0.0; + if (!self.lastUpdatedTimeLabel.hidden) { + timeWidth = self.lastUpdatedTimeLabel.mj_textWith; + } + CGFloat textWidth = MAX(stateWidth, timeWidth); + self.gifView.mj_w = self.mj_w * 0.5 - textWidth * 0.5 - self.labelLeftInset; + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStatePulling || state == MJRefreshStateRefreshing) { + NSArray *images = self.stateImages[@(state)]; + if (images.count == 0) return; + + [self.gifView stopAnimating]; + if (images.count == 1) { // 单张图片 + self.gifView.image = [images lastObject]; + } else { // 多张图片 + self.gifView.animationImages = images; + self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue]; + [self.gifView startAnimating]; + } + } else if (state == MJRefreshStateIdle) { + [self.gifView stopAnimating]; + } +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.h new file mode 100644 index 0000000..547d05e --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.h @@ -0,0 +1,15 @@ +// +// MJRefreshNormalHeader.h +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshStateHeader.h" + +@interface MJRefreshNormalHeader : MJRefreshStateHeader +@property (weak, nonatomic, readonly) UIImageView *arrowView; +/** 菊花的样式 */ +@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.m new file mode 100644 index 0000000..32d8de7 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshNormalHeader.m @@ -0,0 +1,127 @@ +// +// MJRefreshNormalHeader.m +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshNormalHeader.h" +#import "NSBundle+MJRefresh.h" + +@interface MJRefreshNormalHeader() +{ + __unsafe_unretained UIImageView *_arrowView; +} +@property (weak, nonatomic) UIActivityIndicatorView *loadingView; +@end + +@implementation MJRefreshNormalHeader +#pragma mark - 懒加载子控件 +- (UIImageView *)arrowView +{ + if (!_arrowView) { + UIImageView *arrowView = [[UIImageView alloc] initWithImage:[NSBundle mj_arrowImage]]; + [self addSubview:_arrowView = arrowView]; + } + return _arrowView; +} + +- (UIActivityIndicatorView *)loadingView +{ + if (!_loadingView) { + UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorViewStyle]; + loadingView.hidesWhenStopped = YES; + [self addSubview:_loadingView = loadingView]; + } + return _loadingView; +} + +#pragma mark - 公共方法 +- (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)activityIndicatorViewStyle +{ + _activityIndicatorViewStyle = activityIndicatorViewStyle; + + self.loadingView = nil; + [self setNeedsLayout]; +} + +#pragma mark - 重写父类的方法 +- (void)prepare +{ + [super prepare]; + + self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + // 箭头的中心点 + CGFloat arrowCenterX = self.mj_w * 0.5; + if (!self.stateLabel.hidden) { + CGFloat stateWidth = self.stateLabel.mj_textWith; + CGFloat timeWidth = 0.0; + if (!self.lastUpdatedTimeLabel.hidden) { + timeWidth = self.lastUpdatedTimeLabel.mj_textWith; + } + CGFloat textWidth = MAX(stateWidth, timeWidth); + arrowCenterX -= textWidth / 2 + self.labelLeftInset; + } + CGFloat arrowCenterY = self.mj_h * 0.5; + CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY); + + // 箭头 + if (self.arrowView.constraints.count == 0) { + self.arrowView.mj_size = self.arrowView.image.size; + self.arrowView.center = arrowCenter; + } + + // 圈圈 + if (self.loadingView.constraints.count == 0) { + self.loadingView.center = arrowCenter; + } + + self.arrowView.tintColor = self.stateLabel.textColor; +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 根据状态做事情 + if (state == MJRefreshStateIdle) { + if (oldState == MJRefreshStateRefreshing) { + self.arrowView.transform = CGAffineTransformIdentity; + + [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ + self.loadingView.alpha = 0.0; + } completion:^(BOOL finished) { + // 如果执行完动画发现不是idle状态,就直接返回,进入其他状态 + if (self.state != MJRefreshStateIdle) return; + + self.loadingView.alpha = 1.0; + [self.loadingView stopAnimating]; + self.arrowView.hidden = NO; + }]; + } else { + [self.loadingView stopAnimating]; + self.arrowView.hidden = NO; + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformIdentity; + }]; + } + } else if (state == MJRefreshStatePulling) { + [self.loadingView stopAnimating]; + self.arrowView.hidden = NO; + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ + self.arrowView.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); + }]; + } else if (state == MJRefreshStateRefreshing) { + self.loadingView.alpha = 1.0; // 防止refreshing -> idle的动画完毕动作没有被执行 + [self.loadingView startAnimating]; + self.arrowView.hidden = YES; + } +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.h b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.h new file mode 100644 index 0000000..1f3dbc4 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.h @@ -0,0 +1,25 @@ +// +// MJRefreshStateHeader.h +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshHeader.h" + +@interface MJRefreshStateHeader : MJRefreshHeader +#pragma mark - 刷新时间相关 +/** 利用这个block来决定显示的更新时间文字 */ +@property (copy, nonatomic) NSString *(^lastUpdatedTimeText)(NSDate *lastUpdatedTime); +/** 显示上一次刷新时间的label */ +@property (weak, nonatomic, readonly) UILabel *lastUpdatedTimeLabel; + +#pragma mark - 状态相关 +/** 文字距离圈圈、箭头的距离 */ +@property (assign, nonatomic) CGFloat labelLeftInset; +/** 显示刷新状态的label */ +@property (weak, nonatomic, readonly) UILabel *stateLabel; +/** 设置state状态下的文字 */ +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.m b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.m new file mode 100644 index 0000000..ca78b52 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/Custom/Header/MJRefreshStateHeader.m @@ -0,0 +1,167 @@ +// +// MJRefreshStateHeader.m +// MJRefreshExample +// +// Created by MJ Lee on 15/4/24. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshStateHeader.h" + +@interface MJRefreshStateHeader() +{ + /** 显示上一次刷新时间的label */ + __unsafe_unretained UILabel *_lastUpdatedTimeLabel; + /** 显示刷新状态的label */ + __unsafe_unretained UILabel *_stateLabel; +} +/** 所有状态对应的文字 */ +@property (strong, nonatomic) NSMutableDictionary *stateTitles; +@end + +@implementation MJRefreshStateHeader +#pragma mark - 懒加载 +- (NSMutableDictionary *)stateTitles +{ + if (!_stateTitles) { + self.stateTitles = [NSMutableDictionary dictionary]; + } + return _stateTitles; +} + +- (UILabel *)stateLabel +{ + if (!_stateLabel) { + [self addSubview:_stateLabel = [UILabel mj_label]]; + } + return _stateLabel; +} + +- (UILabel *)lastUpdatedTimeLabel +{ + if (!_lastUpdatedTimeLabel) { + [self addSubview:_lastUpdatedTimeLabel = [UILabel mj_label]]; + } + return _lastUpdatedTimeLabel; +} + +#pragma mark - 公共方法 +- (void)setTitle:(NSString *)title forState:(MJRefreshState)state +{ + if (title == nil) return; + self.stateTitles[@(state)] = title; + self.stateLabel.text = self.stateTitles[@(self.state)]; +} + +#pragma mark - 日历获取在9.x之后的系统使用currentCalendar会出异常。在8.0之后使用系统新API。 +- (NSCalendar *)currentCalendar { + if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) { + return [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; + } + return [NSCalendar currentCalendar]; +} + +#pragma mark key的处理 +- (void)setLastUpdatedTimeKey:(NSString *)lastUpdatedTimeKey +{ + [super setLastUpdatedTimeKey:lastUpdatedTimeKey]; + + // 如果label隐藏了,就不用再处理 + if (self.lastUpdatedTimeLabel.hidden) return; + + NSDate *lastUpdatedTime = [[NSUserDefaults standardUserDefaults] objectForKey:lastUpdatedTimeKey]; + + // 如果有block + if (self.lastUpdatedTimeText) { + self.lastUpdatedTimeLabel.text = self.lastUpdatedTimeText(lastUpdatedTime); + return; + } + + if (lastUpdatedTime) { + // 1.获得年月日 + NSCalendar *calendar = [self currentCalendar]; + NSUInteger unitFlags = NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay |NSCalendarUnitHour |NSCalendarUnitMinute; + NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:lastUpdatedTime]; + NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]]; + + // 2.格式化日期 + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + BOOL isToday = NO; + if ([cmp1 day] == [cmp2 day]) { // 今天 + formatter.dateFormat = @" HH:mm"; + isToday = YES; + } else if ([cmp1 year] == [cmp2 year]) { // 今年 + formatter.dateFormat = @"MM-dd HH:mm"; + } else { + formatter.dateFormat = @"yyyy-MM-dd HH:mm"; + } + NSString *time = [formatter stringFromDate:lastUpdatedTime]; + + // 3.显示日期 + self.lastUpdatedTimeLabel.text = [NSString stringWithFormat:@"%@%@%@", + [NSBundle mj_localizedStringForKey:MJRefreshHeaderLastTimeText], + isToday ? [NSBundle mj_localizedStringForKey:MJRefreshHeaderDateTodayText] : @"", + time]; + } else { + self.lastUpdatedTimeLabel.text = [NSString stringWithFormat:@"%@%@", + [NSBundle mj_localizedStringForKey:MJRefreshHeaderLastTimeText], + [NSBundle mj_localizedStringForKey:MJRefreshHeaderNoneLastDateText]]; + } +} + +#pragma mark - 覆盖父类的方法 +- (void)prepare +{ + [super prepare]; + + // 初始化间距 + self.labelLeftInset = MJRefreshLabelLeftInset; + + // 初始化文字 + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderIdleText] forState:MJRefreshStateIdle]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderPullingText] forState:MJRefreshStatePulling]; + [self setTitle:[NSBundle mj_localizedStringForKey:MJRefreshHeaderRefreshingText] forState:MJRefreshStateRefreshing]; +} + +- (void)placeSubviews +{ + [super placeSubviews]; + + if (self.stateLabel.hidden) return; + + BOOL noConstrainsOnStatusLabel = self.stateLabel.constraints.count == 0; + + if (self.lastUpdatedTimeLabel.hidden) { + // 状态 + if (noConstrainsOnStatusLabel) self.stateLabel.frame = self.bounds; + } else { + CGFloat stateLabelH = self.mj_h * 0.5; + // 状态 + if (noConstrainsOnStatusLabel) { + self.stateLabel.mj_x = 0; + self.stateLabel.mj_y = 0; + self.stateLabel.mj_w = self.mj_w; + self.stateLabel.mj_h = stateLabelH; + } + + // 更新时间 + if (self.lastUpdatedTimeLabel.constraints.count == 0) { + self.lastUpdatedTimeLabel.mj_x = 0; + self.lastUpdatedTimeLabel.mj_y = stateLabelH; + self.lastUpdatedTimeLabel.mj_w = self.mj_w; + self.lastUpdatedTimeLabel.mj_h = self.mj_h - self.lastUpdatedTimeLabel.mj_y; + } + } +} + +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState + + // 设置状态文字 + self.stateLabel.text = self.stateTitles[@(state)]; + + // 重新设置key(重新显示时间) + self.lastUpdatedTimeKey = self.lastUpdatedTimeKey; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/arrow@2x.png b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/arrow@2x.png new file mode 100755 index 0000000..b1078de Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/arrow@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings new file mode 100644 index 0000000..a75f6b1 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/en.lproj/Localizable.strings differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings new file mode 100644 index 0000000..0a36d7e Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hans.lproj/Localizable.strings differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hant.lproj/Localizable.strings b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hant.lproj/Localizable.strings new file mode 100644 index 0000000..7924bba --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.bundle/zh-Hant.lproj/Localizable.strings @@ -0,0 +1,16 @@ +"MJRefreshHeaderIdleText" = "下拉可以刷新"; +"MJRefreshHeaderPullingText" = "鬆開立即刷新"; +"MJRefreshHeaderRefreshingText" = "正在刷新數據中..."; + +"MJRefreshAutoFooterIdleText" = "點擊或上拉加載更多"; +"MJRefreshAutoFooterRefreshingText" = "正在加載更多的數據..."; +"MJRefreshAutoFooterNoMoreDataText" = "已經全部加載完畢"; + +"MJRefreshBackFooterIdleText" = "上拉可以加載更多"; +"MJRefreshBackFooterPullingText" = "鬆開立即加載更多"; +"MJRefreshBackFooterRefreshingText" = "正在加載更多的數據..."; +"MJRefreshBackFooterNoMoreDataText" = "已經全部加載完畢"; + +"MJRefreshHeaderLastTimeText" = "最後更新:"; +"MJRefreshHeaderDateTodayText" = "今天"; +"MJRefreshHeaderNoneLastDateText" = "無記錄"; diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.h b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.h new file mode 100644 index 0000000..196e6ec --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefresh.h @@ -0,0 +1,14 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 + +#import "UIScrollView+MJRefresh.h" +#import "UIScrollView+MJExtension.h" +#import "UIView+MJExtension.h" + +#import "MJRefreshNormalHeader.h" +#import "MJRefreshGifHeader.h" + +#import "MJRefreshBackNormalFooter.h" +#import "MJRefreshBackGifFooter.h" +#import "MJRefreshAutoNormalFooter.h" +#import "MJRefreshAutoGifFooter.h" \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefreshConst.h b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefreshConst.h new file mode 100644 index 0000000..4a72021 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefreshConst.h @@ -0,0 +1,67 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +#import +#import + +// 弱引用 +#define MJWeakSelf __weak typeof(self) weakSelf = self; + +// 日志输出 +#ifdef DEBUG +#define MJRefreshLog(...) NSLog(__VA_ARGS__) +#else +#define MJRefreshLog(...) +#endif + +// 过期提醒 +#define MJRefreshDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead) + +// 运行时objc_msgSend +#define MJRefreshMsgSend(...) ((void (*)(void *, SEL, UIView *))objc_msgSend)(__VA_ARGS__) +#define MJRefreshMsgTarget(target) (__bridge void *)(target) + +// RGB颜色 +#define MJRefreshColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] + +// 文字颜色 +#define MJRefreshLabelTextColor MJRefreshColor(90, 90, 90) + +// 字体大小 +#define MJRefreshLabelFont [UIFont boldSystemFontOfSize:14] + +// 常量 +UIKIT_EXTERN const CGFloat MJRefreshLabelLeftInset; +UIKIT_EXTERN const CGFloat MJRefreshHeaderHeight; +UIKIT_EXTERN const CGFloat MJRefreshFooterHeight; +UIKIT_EXTERN const CGFloat MJRefreshFastAnimationDuration; +UIKIT_EXTERN const CGFloat MJRefreshSlowAnimationDuration; + +UIKIT_EXTERN NSString *const MJRefreshKeyPathContentOffset; +UIKIT_EXTERN NSString *const MJRefreshKeyPathContentSize; +UIKIT_EXTERN NSString *const MJRefreshKeyPathContentInset; +UIKIT_EXTERN NSString *const MJRefreshKeyPathPanState; + +UIKIT_EXTERN NSString *const MJRefreshHeaderLastUpdatedTimeKey; + +UIKIT_EXTERN NSString *const MJRefreshHeaderIdleText; +UIKIT_EXTERN NSString *const MJRefreshHeaderPullingText; +UIKIT_EXTERN NSString *const MJRefreshHeaderRefreshingText; + +UIKIT_EXTERN NSString *const MJRefreshAutoFooterIdleText; +UIKIT_EXTERN NSString *const MJRefreshAutoFooterRefreshingText; +UIKIT_EXTERN NSString *const MJRefreshAutoFooterNoMoreDataText; + +UIKIT_EXTERN NSString *const MJRefreshBackFooterIdleText; +UIKIT_EXTERN NSString *const MJRefreshBackFooterPullingText; +UIKIT_EXTERN NSString *const MJRefreshBackFooterRefreshingText; +UIKIT_EXTERN NSString *const MJRefreshBackFooterNoMoreDataText; + +UIKIT_EXTERN NSString *const MJRefreshHeaderLastTimeText; +UIKIT_EXTERN NSString *const MJRefreshHeaderDateTodayText; +UIKIT_EXTERN NSString *const MJRefreshHeaderNoneLastDateText; + +// 状态检查 +#define MJRefreshCheckState \ +MJRefreshState oldState = self.state; \ +if (state == oldState) return; \ +[super setState:state]; diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefreshConst.m b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefreshConst.m new file mode 100644 index 0000000..7c0733e --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/MJRefreshConst.m @@ -0,0 +1,33 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +#import + +const CGFloat MJRefreshLabelLeftInset = 25; +const CGFloat MJRefreshHeaderHeight = 54.0; +const CGFloat MJRefreshFooterHeight = 44.0; +const CGFloat MJRefreshFastAnimationDuration = 0.25; +const CGFloat MJRefreshSlowAnimationDuration = 0.4; + +NSString *const MJRefreshKeyPathContentOffset = @"contentOffset"; +NSString *const MJRefreshKeyPathContentInset = @"contentInset"; +NSString *const MJRefreshKeyPathContentSize = @"contentSize"; +NSString *const MJRefreshKeyPathPanState = @"state"; + +NSString *const MJRefreshHeaderLastUpdatedTimeKey = @"MJRefreshHeaderLastUpdatedTimeKey"; + +NSString *const MJRefreshHeaderIdleText = @"MJRefreshHeaderIdleText"; +NSString *const MJRefreshHeaderPullingText = @"MJRefreshHeaderPullingText"; +NSString *const MJRefreshHeaderRefreshingText = @"MJRefreshHeaderRefreshingText"; + +NSString *const MJRefreshAutoFooterIdleText = @"MJRefreshAutoFooterIdleText"; +NSString *const MJRefreshAutoFooterRefreshingText = @"MJRefreshAutoFooterRefreshingText"; +NSString *const MJRefreshAutoFooterNoMoreDataText = @"MJRefreshAutoFooterNoMoreDataText"; + +NSString *const MJRefreshBackFooterIdleText = @"MJRefreshBackFooterIdleText"; +NSString *const MJRefreshBackFooterPullingText = @"MJRefreshBackFooterPullingText"; +NSString *const MJRefreshBackFooterRefreshingText = @"MJRefreshBackFooterRefreshingText"; +NSString *const MJRefreshBackFooterNoMoreDataText = @"MJRefreshBackFooterNoMoreDataText"; + +NSString *const MJRefreshHeaderLastTimeText = @"MJRefreshHeaderLastTimeText"; +NSString *const MJRefreshHeaderDateTodayText = @"MJRefreshHeaderDateTodayText"; +NSString *const MJRefreshHeaderNoneLastDateText = @"MJRefreshHeaderNoneLastDateText"; \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/NSBundle+MJRefresh.h b/Carthage/Checkouts/MJRefresh/MJRefresh/NSBundle+MJRefresh.h new file mode 100644 index 0000000..01df06c --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/NSBundle+MJRefresh.h @@ -0,0 +1,16 @@ +// +// NSBundle+MJRefresh.h +// MJRefreshExample +// +// Created by MJ Lee on 16/6/13. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import + +@interface NSBundle (MJRefresh) ++ (instancetype)mj_refreshBundle; ++ (UIImage *)mj_arrowImage; ++ (NSString *)mj_localizedStringForKey:(NSString *)key value:(NSString *)value; ++ (NSString *)mj_localizedStringForKey:(NSString *)key; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/NSBundle+MJRefresh.m b/Carthage/Checkouts/MJRefresh/MJRefresh/NSBundle+MJRefresh.m new file mode 100644 index 0000000..c155ad4 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/NSBundle+MJRefresh.m @@ -0,0 +1,61 @@ +// +// NSBundle+MJRefresh.m +// MJRefreshExample +// +// Created by MJ Lee on 16/6/13. +// Copyright © 2016年 小码哥. All rights reserved. +// + +#import "NSBundle+MJRefresh.h" +#import "MJRefreshComponent.h" + +@implementation NSBundle (MJRefresh) ++ (instancetype)mj_refreshBundle +{ + static NSBundle *refreshBundle = nil; + if (refreshBundle == nil) { + // 这里不使用mainBundle是为了适配pod 1.x和0.x + refreshBundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[MJRefreshComponent class]] pathForResource:@"MJRefresh" ofType:@"bundle"]]; + } + return refreshBundle; +} + ++ (UIImage *)mj_arrowImage +{ + static UIImage *arrowImage = nil; + if (arrowImage == nil) { + arrowImage = [[UIImage imageWithContentsOfFile:[[self mj_refreshBundle] pathForResource:@"arrow@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + } + return arrowImage; +} + ++ (NSString *)mj_localizedStringForKey:(NSString *)key +{ + return [self mj_localizedStringForKey:key value:nil]; +} + ++ (NSString *)mj_localizedStringForKey:(NSString *)key value:(NSString *)value +{ + static NSBundle *bundle = nil; + if (bundle == nil) { + // (iOS获取的语言字符串比较不稳定)目前框架只处理en、zh-Hans、zh-Hant三种情况,其他按照系统默认处理 + NSString *language = [NSLocale preferredLanguages].firstObject; + if ([language hasPrefix:@"en"]) { + language = @"en"; + } else if ([language hasPrefix:@"zh"]) { + if ([language rangeOfString:@"Hans"].location != NSNotFound) { + language = @"zh-Hans"; // 简体中文 + } else { // zh-Hant\zh-HK\zh-TW + language = @"zh-Hant"; // 繁體中文 + } + } else { + language = @"en"; + } + + // 从MJRefresh.bundle中查找资源 + bundle = [NSBundle bundleWithPath:[[NSBundle mj_refreshBundle] pathForResource:language ofType:@"lproj"]]; + } + value = [bundle localizedStringForKey:key value:value table:nil]; + return [[NSBundle mainBundle] localizedStringForKey:key value:value table:nil]; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJExtension.h b/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJExtension.h new file mode 100644 index 0000000..734110f --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJExtension.h @@ -0,0 +1,23 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// UIScrollView+Extension.h +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 小码哥. All rights reserved. +// + +#import + +@interface UIScrollView (MJExtension) +@property (assign, nonatomic) CGFloat mj_insetT; +@property (assign, nonatomic) CGFloat mj_insetB; +@property (assign, nonatomic) CGFloat mj_insetL; +@property (assign, nonatomic) CGFloat mj_insetR; + +@property (assign, nonatomic) CGFloat mj_offsetX; +@property (assign, nonatomic) CGFloat mj_offsetY; + +@property (assign, nonatomic) CGFloat mj_contentW; +@property (assign, nonatomic) CGFloat mj_contentH; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJExtension.m b/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJExtension.m new file mode 100644 index 0000000..6a13f5f --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJExtension.m @@ -0,0 +1,110 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// UIScrollView+Extension.m +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 小码哥. All rights reserved. +// + +#import "UIScrollView+MJExtension.h" +#import + +@implementation UIScrollView (MJExtension) + +- (void)setMj_insetT:(CGFloat)mj_insetT +{ + UIEdgeInsets inset = self.contentInset; + inset.top = mj_insetT; + self.contentInset = inset; +} + +- (CGFloat)mj_insetT +{ + return self.contentInset.top; +} + +- (void)setMj_insetB:(CGFloat)mj_insetB +{ + UIEdgeInsets inset = self.contentInset; + inset.bottom = mj_insetB; + self.contentInset = inset; +} + +- (CGFloat)mj_insetB +{ + return self.contentInset.bottom; +} + +- (void)setMj_insetL:(CGFloat)mj_insetL +{ + UIEdgeInsets inset = self.contentInset; + inset.left = mj_insetL; + self.contentInset = inset; +} + +- (CGFloat)mj_insetL +{ + return self.contentInset.left; +} + +- (void)setMj_insetR:(CGFloat)mj_insetR +{ + UIEdgeInsets inset = self.contentInset; + inset.right = mj_insetR; + self.contentInset = inset; +} + +- (CGFloat)mj_insetR +{ + return self.contentInset.right; +} + +- (void)setMj_offsetX:(CGFloat)mj_offsetX +{ + CGPoint offset = self.contentOffset; + offset.x = mj_offsetX; + self.contentOffset = offset; +} + +- (CGFloat)mj_offsetX +{ + return self.contentOffset.x; +} + +- (void)setMj_offsetY:(CGFloat)mj_offsetY +{ + CGPoint offset = self.contentOffset; + offset.y = mj_offsetY; + self.contentOffset = offset; +} + +- (CGFloat)mj_offsetY +{ + return self.contentOffset.y; +} + +- (void)setMj_contentW:(CGFloat)mj_contentW +{ + CGSize size = self.contentSize; + size.width = mj_contentW; + self.contentSize = size; +} + +- (CGFloat)mj_contentW +{ + return self.contentSize.width; +} + +- (void)setMj_contentH:(CGFloat)mj_contentH +{ + CGSize size = self.contentSize; + size.height = mj_contentH; + self.contentSize = size; +} + +- (CGFloat)mj_contentH +{ + return self.contentSize.height; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJRefresh.h b/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJRefresh.h new file mode 100644 index 0000000..17d4715 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJRefresh.h @@ -0,0 +1,26 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// UIScrollView+MJRefresh.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// 给ScrollView增加下拉刷新、上拉刷新的功能 + +#import +#import "MJRefreshConst.h" + +@class MJRefreshHeader, MJRefreshFooter; + +@interface UIScrollView (MJRefresh) +/** 下拉刷新控件 */ +@property (strong, nonatomic) MJRefreshHeader *mj_header; +@property (strong, nonatomic) MJRefreshHeader *header MJRefreshDeprecated("使用mj_header"); +/** 上拉刷新控件 */ +@property (strong, nonatomic) MJRefreshFooter *mj_footer; +@property (strong, nonatomic) MJRefreshFooter *footer MJRefreshDeprecated("使用mj_footer"); + +#pragma mark - other +- (NSInteger)mj_totalDataCount; +@property (copy, nonatomic) void (^mj_reloadDataBlock)(NSInteger totalDataCount); +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJRefresh.m b/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJRefresh.m new file mode 100644 index 0000000..b1b9942 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/UIScrollView+MJRefresh.m @@ -0,0 +1,163 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// UIScrollView+MJRefresh.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "UIScrollView+MJRefresh.h" +#import "MJRefreshHeader.h" +#import "MJRefreshFooter.h" +#import + +@implementation NSObject (MJRefresh) + ++ (void)exchangeInstanceMethod1:(SEL)method1 method2:(SEL)method2 +{ + method_exchangeImplementations(class_getInstanceMethod(self, method1), class_getInstanceMethod(self, method2)); +} + ++ (void)exchangeClassMethod1:(SEL)method1 method2:(SEL)method2 +{ + method_exchangeImplementations(class_getClassMethod(self, method1), class_getClassMethod(self, method2)); +} + +@end + +@implementation UIScrollView (MJRefresh) + +#pragma mark - header +static const char MJRefreshHeaderKey = '\0'; +- (void)setMj_header:(MJRefreshHeader *)mj_header +{ + if (mj_header != self.mj_header) { + // 删除旧的,添加新的 + [self.mj_header removeFromSuperview]; + [self insertSubview:mj_header atIndex:0]; + + // 存储新的 + [self willChangeValueForKey:@"mj_header"]; // KVO + objc_setAssociatedObject(self, &MJRefreshHeaderKey, + mj_header, OBJC_ASSOCIATION_ASSIGN); + [self didChangeValueForKey:@"mj_header"]; // KVO + } +} + +- (MJRefreshHeader *)mj_header +{ + return objc_getAssociatedObject(self, &MJRefreshHeaderKey); +} + +#pragma mark - footer +static const char MJRefreshFooterKey = '\0'; +- (void)setMj_footer:(MJRefreshFooter *)mj_footer +{ + if (mj_footer != self.mj_footer) { + // 删除旧的,添加新的 + [self.mj_footer removeFromSuperview]; + [self insertSubview:mj_footer atIndex:0]; + + // 存储新的 + [self willChangeValueForKey:@"mj_footer"]; // KVO + objc_setAssociatedObject(self, &MJRefreshFooterKey, + mj_footer, OBJC_ASSOCIATION_ASSIGN); + [self didChangeValueForKey:@"mj_footer"]; // KVO + } +} + +- (MJRefreshFooter *)mj_footer +{ + return objc_getAssociatedObject(self, &MJRefreshFooterKey); +} + +#pragma mark - 过期 +- (void)setFooter:(MJRefreshFooter *)footer +{ + self.mj_footer = footer; +} + +- (MJRefreshFooter *)footer +{ + return self.mj_footer; +} + +- (void)setHeader:(MJRefreshHeader *)header +{ + self.mj_header = header; +} + +- (MJRefreshHeader *)header +{ + return self.mj_header; +} + +#pragma mark - other +- (NSInteger)mj_totalDataCount +{ + NSInteger totalCount = 0; + if ([self isKindOfClass:[UITableView class]]) { + UITableView *tableView = (UITableView *)self; + + for (NSInteger section = 0; section + +@interface UIView (MJExtension) +@property (assign, nonatomic) CGFloat mj_x; +@property (assign, nonatomic) CGFloat mj_y; +@property (assign, nonatomic) CGFloat mj_w; +@property (assign, nonatomic) CGFloat mj_h; +@property (assign, nonatomic) CGSize mj_size; +@property (assign, nonatomic) CGPoint mj_origin; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefresh/UIView+MJExtension.m b/Carthage/Checkouts/MJRefresh/MJRefresh/UIView+MJExtension.m new file mode 100644 index 0000000..7e8eda2 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefresh/UIView+MJExtension.m @@ -0,0 +1,84 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// UIView+Extension.m +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 小码哥. All rights reserved. +// + +#import "UIView+MJExtension.h" + +@implementation UIView (MJExtension) +- (void)setMj_x:(CGFloat)mj_x +{ + CGRect frame = self.frame; + frame.origin.x = mj_x; + self.frame = frame; +} + +- (CGFloat)mj_x +{ + return self.frame.origin.x; +} + +- (void)setMj_y:(CGFloat)mj_y +{ + CGRect frame = self.frame; + frame.origin.y = mj_y; + self.frame = frame; +} + +- (CGFloat)mj_y +{ + return self.frame.origin.y; +} + +- (void)setMj_w:(CGFloat)mj_w +{ + CGRect frame = self.frame; + frame.size.width = mj_w; + self.frame = frame; +} + +- (CGFloat)mj_w +{ + return self.frame.size.width; +} + +- (void)setMj_h:(CGFloat)mj_h +{ + CGRect frame = self.frame; + frame.size.height = mj_h; + self.frame = frame; +} + +- (CGFloat)mj_h +{ + return self.frame.size.height; +} + +- (void)setMj_size:(CGSize)mj_size +{ + CGRect frame = self.frame; + frame.size = mj_size; + self.frame = frame; +} + +- (CGSize)mj_size +{ + return self.frame.size; +} + +- (void)setMj_origin:(CGPoint)mj_origin +{ + CGRect frame = self.frame; + frame.origin = mj_origin; + self.frame = frame; +} + +- (CGPoint)mj_origin +{ + return self.frame.origin; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample.xcodeproj/project.pbxproj b/Carthage/Checkouts/MJRefresh/MJRefreshExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d761744 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample.xcodeproj/project.pbxproj @@ -0,0 +1,773 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 2D4698861D0EE6A400CB8025 /* NSBundle+MJRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D4698851D0EE6A400CB8025 /* NSBundle+MJRefresh.m */; }; + 2D9BEB091BB15F4A00AED473 /* UIViewController+Example.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAE01BB15F4A00AED473 /* UIViewController+Example.m */; }; + 2D9BEB0A1BB15F4A00AED473 /* MJChiBaoZiFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAE31BB15F4A00AED473 /* MJChiBaoZiFooter.m */; }; + 2D9BEB0B1BB15F4A00AED473 /* MJChiBaoZiFooter2.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAE51BB15F4A00AED473 /* MJChiBaoZiFooter2.m */; }; + 2D9BEB0C1BB15F4A00AED473 /* MJChiBaoZiHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAE71BB15F4A00AED473 /* MJChiBaoZiHeader.m */; }; + 2D9BEB0D1BB15F4A00AED473 /* MJDIYAutoFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAE91BB15F4A00AED473 /* MJDIYAutoFooter.m */; }; + 2D9BEB0E1BB15F4A00AED473 /* MJDIYBackFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAEB1BB15F4A00AED473 /* MJDIYBackFooter.m */; }; + 2D9BEB0F1BB15F4A00AED473 /* MJDIYHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAED1BB15F4A00AED473 /* MJDIYHeader.m */; }; + 2D9BEB101BB15F4A00AED473 /* MJExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAF01BB15F4A00AED473 /* MJExample.m */; }; + 2D9BEB111BB15F4A00AED473 /* MJExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAF21BB15F4A00AED473 /* MJExampleViewController.m */; }; + 2D9BEB121BB15F4A00AED473 /* MJExampleWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAF41BB15F4A00AED473 /* MJExampleWindow.m */; }; + 2D9BEB131BB15F4A00AED473 /* MJNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAF61BB15F4A00AED473 /* MJNavigationController.m */; }; + 2D9BEB141BB15F4A00AED473 /* MJSingleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAF81BB15F4A00AED473 /* MJSingleViewController.m */; }; + 2D9BEB151BB15F4A00AED473 /* MJTempViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAFA1BB15F4A00AED473 /* MJTempViewController.m */; }; + 2D9BEB161BB15F4A00AED473 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEAFD1BB15F4A00AED473 /* AppDelegate.m */; }; + 2D9BEB171BB15F4A00AED473 /* MJCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEB001BB15F4A00AED473 /* MJCollectionViewController.m */; }; + 2D9BEB181BB15F4A00AED473 /* MJTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEB021BB15F4A00AED473 /* MJTableViewController.m */; }; + 2D9BEB191BB15F4A00AED473 /* MJTestViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEB041BB15F4A00AED473 /* MJTestViewController.m */; }; + 2D9BEB1A1BB15F4A00AED473 /* MJTestViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2D9BEB051BB15F4A00AED473 /* MJTestViewController.xib */; }; + 2D9BEB1B1BB15F4A00AED473 /* MJWebViewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D9BEB071BB15F4A00AED473 /* MJWebViewViewController.m */; }; + 2D9BEB1C1BB15F4A00AED473 /* MJWebViewViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2D9BEB081BB15F4A00AED473 /* MJWebViewViewController.xib */; }; + 2DA7F92B1AA6B4C4005627AB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7F92A1AA6B4C4005627AB /* main.m */; }; + 2DA7F9341AA6B4C4005627AB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2DA7F9321AA6B4C4005627AB /* Main.storyboard */; }; + 2DA7F9361AA6B4C4005627AB /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DA7F9351AA6B4C4005627AB /* Images.xcassets */; }; + 2DA7F9391AA6B4C4005627AB /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2DA7F9371AA6B4C4005627AB /* LaunchScreen.xib */; }; + 2DA7F9451AA6B4C4005627AB /* MJRefreshExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7F9441AA6B4C4005627AB /* MJRefreshExampleTests.m */; }; + 2DB2EA171BECBE6700D58F6A /* MJRefreshAutoFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2E9ED1BECBE6700D58F6A /* MJRefreshAutoFooter.m */; }; + 2DB2EA181BECBE6700D58F6A /* MJRefreshBackFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2E9EF1BECBE6700D58F6A /* MJRefreshBackFooter.m */; }; + 2DB2EA191BECBE6700D58F6A /* MJRefreshComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2E9F11BECBE6700D58F6A /* MJRefreshComponent.m */; }; + 2DB2EA1A1BECBE6700D58F6A /* MJRefreshFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2E9F31BECBE6700D58F6A /* MJRefreshFooter.m */; }; + 2DB2EA1B1BECBE6700D58F6A /* MJRefreshHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2E9F51BECBE6700D58F6A /* MJRefreshHeader.m */; }; + 2DB2EA1C1BECBE6700D58F6A /* MJRefreshAutoGifFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2E9FA1BECBE6700D58F6A /* MJRefreshAutoGifFooter.m */; }; + 2DB2EA1D1BECBE6700D58F6A /* MJRefreshAutoNormalFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2E9FC1BECBE6700D58F6A /* MJRefreshAutoNormalFooter.m */; }; + 2DB2EA1E1BECBE6700D58F6A /* MJRefreshAutoStateFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2E9FE1BECBE6700D58F6A /* MJRefreshAutoStateFooter.m */; }; + 2DB2EA1F1BECBE6700D58F6A /* MJRefreshBackGifFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA011BECBE6700D58F6A /* MJRefreshBackGifFooter.m */; }; + 2DB2EA201BECBE6700D58F6A /* MJRefreshBackNormalFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA031BECBE6700D58F6A /* MJRefreshBackNormalFooter.m */; }; + 2DB2EA211BECBE6700D58F6A /* MJRefreshBackStateFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA051BECBE6700D58F6A /* MJRefreshBackStateFooter.m */; }; + 2DB2EA221BECBE6700D58F6A /* MJRefreshGifHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA081BECBE6700D58F6A /* MJRefreshGifHeader.m */; }; + 2DB2EA231BECBE6700D58F6A /* MJRefreshNormalHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA0A1BECBE6700D58F6A /* MJRefreshNormalHeader.m */; }; + 2DB2EA241BECBE6700D58F6A /* MJRefreshStateHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA0C1BECBE6700D58F6A /* MJRefreshStateHeader.m */; }; + 2DB2EA251BECBE6700D58F6A /* MJRefresh.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 2DB2EA0D1BECBE6700D58F6A /* MJRefresh.bundle */; }; + 2DB2EA261BECBE6700D58F6A /* MJRefreshConst.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA101BECBE6700D58F6A /* MJRefreshConst.m */; }; + 2DB2EA271BECBE6700D58F6A /* UIScrollView+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA121BECBE6700D58F6A /* UIScrollView+MJExtension.m */; }; + 2DB2EA281BECBE6700D58F6A /* UIScrollView+MJRefresh.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA141BECBE6700D58F6A /* UIScrollView+MJRefresh.m */; }; + 2DB2EA291BECBE6700D58F6A /* UIView+MJExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DB2EA161BECBE6700D58F6A /* UIView+MJExtension.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 2DA7F93F1AA6B4C4005627AB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2DA7F91D1AA6B4C4005627AB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2DA7F9241AA6B4C4005627AB; + remoteInfo = MJRefreshExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 2D4698841D0EE6A400CB8025 /* NSBundle+MJRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+MJRefresh.h"; sourceTree = ""; }; + 2D4698851D0EE6A400CB8025 /* NSBundle+MJRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+MJRefresh.m"; sourceTree = ""; }; + 2D9BEADF1BB15F4A00AED473 /* UIViewController+Example.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+Example.h"; sourceTree = ""; }; + 2D9BEAE01BB15F4A00AED473 /* UIViewController+Example.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+Example.m"; sourceTree = ""; }; + 2D9BEAE21BB15F4A00AED473 /* MJChiBaoZiFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJChiBaoZiFooter.h; sourceTree = ""; }; + 2D9BEAE31BB15F4A00AED473 /* MJChiBaoZiFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJChiBaoZiFooter.m; sourceTree = ""; }; + 2D9BEAE41BB15F4A00AED473 /* MJChiBaoZiFooter2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJChiBaoZiFooter2.h; sourceTree = ""; }; + 2D9BEAE51BB15F4A00AED473 /* MJChiBaoZiFooter2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJChiBaoZiFooter2.m; sourceTree = ""; }; + 2D9BEAE61BB15F4A00AED473 /* MJChiBaoZiHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJChiBaoZiHeader.h; sourceTree = ""; }; + 2D9BEAE71BB15F4A00AED473 /* MJChiBaoZiHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJChiBaoZiHeader.m; sourceTree = ""; }; + 2D9BEAE81BB15F4A00AED473 /* MJDIYAutoFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJDIYAutoFooter.h; sourceTree = ""; }; + 2D9BEAE91BB15F4A00AED473 /* MJDIYAutoFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJDIYAutoFooter.m; sourceTree = ""; }; + 2D9BEAEA1BB15F4A00AED473 /* MJDIYBackFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJDIYBackFooter.h; sourceTree = ""; }; + 2D9BEAEB1BB15F4A00AED473 /* MJDIYBackFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJDIYBackFooter.m; sourceTree = ""; }; + 2D9BEAEC1BB15F4A00AED473 /* MJDIYHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJDIYHeader.h; sourceTree = ""; }; + 2D9BEAED1BB15F4A00AED473 /* MJDIYHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJDIYHeader.m; sourceTree = ""; }; + 2D9BEAEF1BB15F4A00AED473 /* MJExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJExample.h; sourceTree = ""; }; + 2D9BEAF01BB15F4A00AED473 /* MJExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJExample.m; sourceTree = ""; }; + 2D9BEAF11BB15F4A00AED473 /* MJExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJExampleViewController.h; sourceTree = ""; }; + 2D9BEAF21BB15F4A00AED473 /* MJExampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJExampleViewController.m; sourceTree = ""; }; + 2D9BEAF31BB15F4A00AED473 /* MJExampleWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJExampleWindow.h; sourceTree = ""; }; + 2D9BEAF41BB15F4A00AED473 /* MJExampleWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJExampleWindow.m; sourceTree = ""; }; + 2D9BEAF51BB15F4A00AED473 /* MJNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJNavigationController.h; sourceTree = ""; }; + 2D9BEAF61BB15F4A00AED473 /* MJNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJNavigationController.m; sourceTree = ""; }; + 2D9BEAF71BB15F4A00AED473 /* MJSingleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJSingleViewController.h; sourceTree = ""; }; + 2D9BEAF81BB15F4A00AED473 /* MJSingleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJSingleViewController.m; sourceTree = ""; }; + 2D9BEAF91BB15F4A00AED473 /* MJTempViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJTempViewController.h; sourceTree = ""; }; + 2D9BEAFA1BB15F4A00AED473 /* MJTempViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJTempViewController.m; sourceTree = ""; }; + 2D9BEAFC1BB15F4A00AED473 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 2D9BEAFD1BB15F4A00AED473 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 2D9BEAFF1BB15F4A00AED473 /* MJCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJCollectionViewController.h; sourceTree = ""; }; + 2D9BEB001BB15F4A00AED473 /* MJCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJCollectionViewController.m; sourceTree = ""; }; + 2D9BEB011BB15F4A00AED473 /* MJTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJTableViewController.h; sourceTree = ""; }; + 2D9BEB021BB15F4A00AED473 /* MJTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJTableViewController.m; sourceTree = ""; }; + 2D9BEB031BB15F4A00AED473 /* MJTestViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJTestViewController.h; sourceTree = ""; }; + 2D9BEB041BB15F4A00AED473 /* MJTestViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJTestViewController.m; sourceTree = ""; }; + 2D9BEB051BB15F4A00AED473 /* MJTestViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MJTestViewController.xib; sourceTree = ""; }; + 2D9BEB061BB15F4A00AED473 /* MJWebViewViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJWebViewViewController.h; sourceTree = ""; }; + 2D9BEB071BB15F4A00AED473 /* MJWebViewViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJWebViewViewController.m; sourceTree = ""; }; + 2D9BEB081BB15F4A00AED473 /* MJWebViewViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MJWebViewViewController.xib; sourceTree = ""; }; + 2DA7F9251AA6B4C4005627AB /* MJRefreshExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MJRefreshExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 2DA7F9291AA6B4C4005627AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2DA7F92A1AA6B4C4005627AB /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 2DA7F9331AA6B4C4005627AB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 2DA7F9351AA6B4C4005627AB /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 2DA7F9381AA6B4C4005627AB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 2DA7F93E1AA6B4C4005627AB /* MJRefreshExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MJRefreshExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 2DA7F9431AA6B4C4005627AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2DA7F9441AA6B4C4005627AB /* MJRefreshExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MJRefreshExampleTests.m; sourceTree = ""; }; + 2DAA837B1BB1685300B62152 /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; + 2DB2E9EC1BECBE6700D58F6A /* MJRefreshAutoFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshAutoFooter.h; sourceTree = ""; }; + 2DB2E9ED1BECBE6700D58F6A /* MJRefreshAutoFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshAutoFooter.m; sourceTree = ""; }; + 2DB2E9EE1BECBE6700D58F6A /* MJRefreshBackFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshBackFooter.h; sourceTree = ""; }; + 2DB2E9EF1BECBE6700D58F6A /* MJRefreshBackFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshBackFooter.m; sourceTree = ""; }; + 2DB2E9F01BECBE6700D58F6A /* MJRefreshComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshComponent.h; sourceTree = ""; }; + 2DB2E9F11BECBE6700D58F6A /* MJRefreshComponent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshComponent.m; sourceTree = ""; }; + 2DB2E9F21BECBE6700D58F6A /* MJRefreshFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshFooter.h; sourceTree = ""; }; + 2DB2E9F31BECBE6700D58F6A /* MJRefreshFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshFooter.m; sourceTree = ""; }; + 2DB2E9F41BECBE6700D58F6A /* MJRefreshHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshHeader.h; sourceTree = ""; }; + 2DB2E9F51BECBE6700D58F6A /* MJRefreshHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshHeader.m; sourceTree = ""; }; + 2DB2E9F91BECBE6700D58F6A /* MJRefreshAutoGifFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshAutoGifFooter.h; sourceTree = ""; }; + 2DB2E9FA1BECBE6700D58F6A /* MJRefreshAutoGifFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshAutoGifFooter.m; sourceTree = ""; }; + 2DB2E9FB1BECBE6700D58F6A /* MJRefreshAutoNormalFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshAutoNormalFooter.h; sourceTree = ""; }; + 2DB2E9FC1BECBE6700D58F6A /* MJRefreshAutoNormalFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshAutoNormalFooter.m; sourceTree = ""; }; + 2DB2E9FD1BECBE6700D58F6A /* MJRefreshAutoStateFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshAutoStateFooter.h; sourceTree = ""; }; + 2DB2E9FE1BECBE6700D58F6A /* MJRefreshAutoStateFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshAutoStateFooter.m; sourceTree = ""; }; + 2DB2EA001BECBE6700D58F6A /* MJRefreshBackGifFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshBackGifFooter.h; sourceTree = ""; }; + 2DB2EA011BECBE6700D58F6A /* MJRefreshBackGifFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshBackGifFooter.m; sourceTree = ""; }; + 2DB2EA021BECBE6700D58F6A /* MJRefreshBackNormalFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshBackNormalFooter.h; sourceTree = ""; }; + 2DB2EA031BECBE6700D58F6A /* MJRefreshBackNormalFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshBackNormalFooter.m; sourceTree = ""; }; + 2DB2EA041BECBE6700D58F6A /* MJRefreshBackStateFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshBackStateFooter.h; sourceTree = ""; }; + 2DB2EA051BECBE6700D58F6A /* MJRefreshBackStateFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshBackStateFooter.m; sourceTree = ""; }; + 2DB2EA071BECBE6700D58F6A /* MJRefreshGifHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshGifHeader.h; sourceTree = ""; }; + 2DB2EA081BECBE6700D58F6A /* MJRefreshGifHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshGifHeader.m; sourceTree = ""; }; + 2DB2EA091BECBE6700D58F6A /* MJRefreshNormalHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshNormalHeader.h; sourceTree = ""; }; + 2DB2EA0A1BECBE6700D58F6A /* MJRefreshNormalHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshNormalHeader.m; sourceTree = ""; }; + 2DB2EA0B1BECBE6700D58F6A /* MJRefreshStateHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshStateHeader.h; sourceTree = ""; }; + 2DB2EA0C1BECBE6700D58F6A /* MJRefreshStateHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshStateHeader.m; sourceTree = ""; }; + 2DB2EA0D1BECBE6700D58F6A /* MJRefresh.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = MJRefresh.bundle; sourceTree = ""; }; + 2DB2EA0E1BECBE6700D58F6A /* MJRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefresh.h; sourceTree = ""; }; + 2DB2EA0F1BECBE6700D58F6A /* MJRefreshConst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MJRefreshConst.h; sourceTree = ""; }; + 2DB2EA101BECBE6700D58F6A /* MJRefreshConst.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MJRefreshConst.m; sourceTree = ""; }; + 2DB2EA111BECBE6700D58F6A /* UIScrollView+MJExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+MJExtension.h"; sourceTree = ""; }; + 2DB2EA121BECBE6700D58F6A /* UIScrollView+MJExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+MJExtension.m"; sourceTree = ""; }; + 2DB2EA131BECBE6700D58F6A /* UIScrollView+MJRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+MJRefresh.h"; sourceTree = ""; }; + 2DB2EA141BECBE6700D58F6A /* UIScrollView+MJRefresh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScrollView+MJRefresh.m"; sourceTree = ""; }; + 2DB2EA151BECBE6700D58F6A /* UIView+MJExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+MJExtension.h"; sourceTree = ""; }; + 2DB2EA161BECBE6700D58F6A /* UIView+MJExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+MJExtension.m"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2DA7F9221AA6B4C4005627AB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2DA7F93B1AA6B4C4005627AB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2D9BEADE1BB15F4A00AED473 /* Category */ = { + isa = PBXGroup; + children = ( + 2D9BEADF1BB15F4A00AED473 /* UIViewController+Example.h */, + 2D9BEAE01BB15F4A00AED473 /* UIViewController+Example.m */, + ); + path = Category; + sourceTree = ""; + }; + 2D9BEAE11BB15F4A00AED473 /* DIY */ = { + isa = PBXGroup; + children = ( + 2D9BEAE21BB15F4A00AED473 /* MJChiBaoZiFooter.h */, + 2D9BEAE31BB15F4A00AED473 /* MJChiBaoZiFooter.m */, + 2D9BEAE41BB15F4A00AED473 /* MJChiBaoZiFooter2.h */, + 2D9BEAE51BB15F4A00AED473 /* MJChiBaoZiFooter2.m */, + 2D9BEAE61BB15F4A00AED473 /* MJChiBaoZiHeader.h */, + 2D9BEAE71BB15F4A00AED473 /* MJChiBaoZiHeader.m */, + 2D9BEAE81BB15F4A00AED473 /* MJDIYAutoFooter.h */, + 2D9BEAE91BB15F4A00AED473 /* MJDIYAutoFooter.m */, + 2D9BEAEA1BB15F4A00AED473 /* MJDIYBackFooter.h */, + 2D9BEAEB1BB15F4A00AED473 /* MJDIYBackFooter.m */, + 2D9BEAEC1BB15F4A00AED473 /* MJDIYHeader.h */, + 2D9BEAED1BB15F4A00AED473 /* MJDIYHeader.m */, + ); + path = DIY; + sourceTree = ""; + }; + 2D9BEAEE1BB15F4A00AED473 /* First */ = { + isa = PBXGroup; + children = ( + 2D9BEAEF1BB15F4A00AED473 /* MJExample.h */, + 2D9BEAF01BB15F4A00AED473 /* MJExample.m */, + 2D9BEAF11BB15F4A00AED473 /* MJExampleViewController.h */, + 2D9BEAF21BB15F4A00AED473 /* MJExampleViewController.m */, + 2D9BEAF31BB15F4A00AED473 /* MJExampleWindow.h */, + 2D9BEAF41BB15F4A00AED473 /* MJExampleWindow.m */, + 2D9BEAF51BB15F4A00AED473 /* MJNavigationController.h */, + 2D9BEAF61BB15F4A00AED473 /* MJNavigationController.m */, + 2D9BEAF71BB15F4A00AED473 /* MJSingleViewController.h */, + 2D9BEAF81BB15F4A00AED473 /* MJSingleViewController.m */, + 2D9BEAF91BB15F4A00AED473 /* MJTempViewController.h */, + 2D9BEAFA1BB15F4A00AED473 /* MJTempViewController.m */, + ); + path = First; + sourceTree = ""; + }; + 2D9BEAFB1BB15F4A00AED473 /* Other */ = { + isa = PBXGroup; + children = ( + 2D9BEAFC1BB15F4A00AED473 /* AppDelegate.h */, + 2D9BEAFD1BB15F4A00AED473 /* AppDelegate.m */, + ); + path = Other; + sourceTree = ""; + }; + 2D9BEAFE1BB15F4A00AED473 /* Second */ = { + isa = PBXGroup; + children = ( + 2D9BEAFF1BB15F4A00AED473 /* MJCollectionViewController.h */, + 2D9BEB001BB15F4A00AED473 /* MJCollectionViewController.m */, + 2D9BEB011BB15F4A00AED473 /* MJTableViewController.h */, + 2D9BEB021BB15F4A00AED473 /* MJTableViewController.m */, + 2D9BEB031BB15F4A00AED473 /* MJTestViewController.h */, + 2D9BEB041BB15F4A00AED473 /* MJTestViewController.m */, + 2D9BEB051BB15F4A00AED473 /* MJTestViewController.xib */, + 2D9BEB061BB15F4A00AED473 /* MJWebViewViewController.h */, + 2D9BEB071BB15F4A00AED473 /* MJWebViewViewController.m */, + 2D9BEB081BB15F4A00AED473 /* MJWebViewViewController.xib */, + ); + path = Second; + sourceTree = ""; + }; + 2DA7F91C1AA6B4C4005627AB = { + isa = PBXGroup; + children = ( + 2DA7F9271AA6B4C4005627AB /* MJRefreshExample */, + 2DA7F9411AA6B4C4005627AB /* MJRefreshExampleTests */, + 2DA7F9261AA6B4C4005627AB /* Products */, + ); + sourceTree = ""; + }; + 2DA7F9261AA6B4C4005627AB /* Products */ = { + isa = PBXGroup; + children = ( + 2DA7F9251AA6B4C4005627AB /* MJRefreshExample.app */, + 2DA7F93E1AA6B4C4005627AB /* MJRefreshExampleTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 2DA7F9271AA6B4C4005627AB /* MJRefreshExample */ = { + isa = PBXGroup; + children = ( + 2DB2E9EA1BECBE6700D58F6A /* MJRefresh */, + 2DA7F94E1AA6B51C005627AB /* Classes */, + 2DA7F9281AA6B4C4005627AB /* Supporting Files */, + ); + path = MJRefreshExample; + sourceTree = ""; + }; + 2DA7F9281AA6B4C4005627AB /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 2DA7F9321AA6B4C4005627AB /* Main.storyboard */, + 2DA7F9351AA6B4C4005627AB /* Images.xcassets */, + 2DA7F9371AA6B4C4005627AB /* LaunchScreen.xib */, + 2DA7F9291AA6B4C4005627AB /* Info.plist */, + 2DA7F92A1AA6B4C4005627AB /* main.m */, + 2DAA837B1BB1685300B62152 /* PrefixHeader.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 2DA7F9411AA6B4C4005627AB /* MJRefreshExampleTests */ = { + isa = PBXGroup; + children = ( + 2DA7F9441AA6B4C4005627AB /* MJRefreshExampleTests.m */, + 2DA7F9421AA6B4C4005627AB /* Supporting Files */, + ); + path = MJRefreshExampleTests; + sourceTree = ""; + }; + 2DA7F9421AA6B4C4005627AB /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 2DA7F9431AA6B4C4005627AB /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 2DA7F94E1AA6B51C005627AB /* Classes */ = { + isa = PBXGroup; + children = ( + 2D9BEADE1BB15F4A00AED473 /* Category */, + 2D9BEAFB1BB15F4A00AED473 /* Other */, + 2D9BEAE11BB15F4A00AED473 /* DIY */, + 2D9BEAEE1BB15F4A00AED473 /* First */, + 2D9BEAFE1BB15F4A00AED473 /* Second */, + ); + path = Classes; + sourceTree = ""; + }; + 2DB2E9EA1BECBE6700D58F6A /* MJRefresh */ = { + isa = PBXGroup; + children = ( + 2DB2E9EB1BECBE6700D58F6A /* Base */, + 2DB2E9F61BECBE6700D58F6A /* Custom */, + 2DB2EA0D1BECBE6700D58F6A /* MJRefresh.bundle */, + 2DB2EA0E1BECBE6700D58F6A /* MJRefresh.h */, + 2DB2EA0F1BECBE6700D58F6A /* MJRefreshConst.h */, + 2DB2EA101BECBE6700D58F6A /* MJRefreshConst.m */, + 2DB2EA111BECBE6700D58F6A /* UIScrollView+MJExtension.h */, + 2DB2EA121BECBE6700D58F6A /* UIScrollView+MJExtension.m */, + 2DB2EA131BECBE6700D58F6A /* UIScrollView+MJRefresh.h */, + 2DB2EA141BECBE6700D58F6A /* UIScrollView+MJRefresh.m */, + 2DB2EA151BECBE6700D58F6A /* UIView+MJExtension.h */, + 2DB2EA161BECBE6700D58F6A /* UIView+MJExtension.m */, + 2D4698841D0EE6A400CB8025 /* NSBundle+MJRefresh.h */, + 2D4698851D0EE6A400CB8025 /* NSBundle+MJRefresh.m */, + ); + path = MJRefresh; + sourceTree = SOURCE_ROOT; + }; + 2DB2E9EB1BECBE6700D58F6A /* Base */ = { + isa = PBXGroup; + children = ( + 2DB2E9EC1BECBE6700D58F6A /* MJRefreshAutoFooter.h */, + 2DB2E9ED1BECBE6700D58F6A /* MJRefreshAutoFooter.m */, + 2DB2E9EE1BECBE6700D58F6A /* MJRefreshBackFooter.h */, + 2DB2E9EF1BECBE6700D58F6A /* MJRefreshBackFooter.m */, + 2DB2E9F01BECBE6700D58F6A /* MJRefreshComponent.h */, + 2DB2E9F11BECBE6700D58F6A /* MJRefreshComponent.m */, + 2DB2E9F21BECBE6700D58F6A /* MJRefreshFooter.h */, + 2DB2E9F31BECBE6700D58F6A /* MJRefreshFooter.m */, + 2DB2E9F41BECBE6700D58F6A /* MJRefreshHeader.h */, + 2DB2E9F51BECBE6700D58F6A /* MJRefreshHeader.m */, + ); + path = Base; + sourceTree = ""; + }; + 2DB2E9F61BECBE6700D58F6A /* Custom */ = { + isa = PBXGroup; + children = ( + 2DB2E9F71BECBE6700D58F6A /* Footer */, + 2DB2EA061BECBE6700D58F6A /* Header */, + ); + path = Custom; + sourceTree = ""; + }; + 2DB2E9F71BECBE6700D58F6A /* Footer */ = { + isa = PBXGroup; + children = ( + 2DB2E9F81BECBE6700D58F6A /* Auto */, + 2DB2E9FF1BECBE6700D58F6A /* Back */, + ); + path = Footer; + sourceTree = ""; + }; + 2DB2E9F81BECBE6700D58F6A /* Auto */ = { + isa = PBXGroup; + children = ( + 2DB2E9F91BECBE6700D58F6A /* MJRefreshAutoGifFooter.h */, + 2DB2E9FA1BECBE6700D58F6A /* MJRefreshAutoGifFooter.m */, + 2DB2E9FB1BECBE6700D58F6A /* MJRefreshAutoNormalFooter.h */, + 2DB2E9FC1BECBE6700D58F6A /* MJRefreshAutoNormalFooter.m */, + 2DB2E9FD1BECBE6700D58F6A /* MJRefreshAutoStateFooter.h */, + 2DB2E9FE1BECBE6700D58F6A /* MJRefreshAutoStateFooter.m */, + ); + path = Auto; + sourceTree = ""; + }; + 2DB2E9FF1BECBE6700D58F6A /* Back */ = { + isa = PBXGroup; + children = ( + 2DB2EA001BECBE6700D58F6A /* MJRefreshBackGifFooter.h */, + 2DB2EA011BECBE6700D58F6A /* MJRefreshBackGifFooter.m */, + 2DB2EA021BECBE6700D58F6A /* MJRefreshBackNormalFooter.h */, + 2DB2EA031BECBE6700D58F6A /* MJRefreshBackNormalFooter.m */, + 2DB2EA041BECBE6700D58F6A /* MJRefreshBackStateFooter.h */, + 2DB2EA051BECBE6700D58F6A /* MJRefreshBackStateFooter.m */, + ); + path = Back; + sourceTree = ""; + }; + 2DB2EA061BECBE6700D58F6A /* Header */ = { + isa = PBXGroup; + children = ( + 2DB2EA071BECBE6700D58F6A /* MJRefreshGifHeader.h */, + 2DB2EA081BECBE6700D58F6A /* MJRefreshGifHeader.m */, + 2DB2EA091BECBE6700D58F6A /* MJRefreshNormalHeader.h */, + 2DB2EA0A1BECBE6700D58F6A /* MJRefreshNormalHeader.m */, + 2DB2EA0B1BECBE6700D58F6A /* MJRefreshStateHeader.h */, + 2DB2EA0C1BECBE6700D58F6A /* MJRefreshStateHeader.m */, + ); + path = Header; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2DA7F9241AA6B4C4005627AB /* MJRefreshExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2DA7F9481AA6B4C4005627AB /* Build configuration list for PBXNativeTarget "MJRefreshExample" */; + buildPhases = ( + 2DA7F9211AA6B4C4005627AB /* Sources */, + 2DA7F9221AA6B4C4005627AB /* Frameworks */, + 2DA7F9231AA6B4C4005627AB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MJRefreshExample; + productName = MJRefreshExample; + productReference = 2DA7F9251AA6B4C4005627AB /* MJRefreshExample.app */; + productType = "com.apple.product-type.application"; + }; + 2DA7F93D1AA6B4C4005627AB /* MJRefreshExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2DA7F94B1AA6B4C4005627AB /* Build configuration list for PBXNativeTarget "MJRefreshExampleTests" */; + buildPhases = ( + 2DA7F93A1AA6B4C4005627AB /* Sources */, + 2DA7F93B1AA6B4C4005627AB /* Frameworks */, + 2DA7F93C1AA6B4C4005627AB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2DA7F9401AA6B4C4005627AB /* PBXTargetDependency */, + ); + name = MJRefreshExampleTests; + productName = MJRefreshExampleTests; + productReference = 2DA7F93E1AA6B4C4005627AB /* MJRefreshExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2DA7F91D1AA6B4C4005627AB /* Project object */ = { + isa = PBXProject; + attributes = { + CLASSPREFIX = MJ; + LastUpgradeCheck = 0700; + ORGANIZATIONNAME = "小码哥"; + TargetAttributes = { + 2DA7F9241AA6B4C4005627AB = { + CreatedOnToolsVersion = 6.1; + }; + 2DA7F93D1AA6B4C4005627AB = { + CreatedOnToolsVersion = 6.1; + TestTargetID = 2DA7F9241AA6B4C4005627AB; + }; + }; + }; + buildConfigurationList = 2DA7F9201AA6B4C4005627AB /* Build configuration list for PBXProject "MJRefreshExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 2DA7F91C1AA6B4C4005627AB; + productRefGroup = 2DA7F9261AA6B4C4005627AB /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2DA7F9241AA6B4C4005627AB /* MJRefreshExample */, + 2DA7F93D1AA6B4C4005627AB /* MJRefreshExampleTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2DA7F9231AA6B4C4005627AB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2DA7F9341AA6B4C4005627AB /* Main.storyboard in Resources */, + 2D9BEB1C1BB15F4A00AED473 /* MJWebViewViewController.xib in Resources */, + 2DB2EA251BECBE6700D58F6A /* MJRefresh.bundle in Resources */, + 2DA7F9391AA6B4C4005627AB /* LaunchScreen.xib in Resources */, + 2D9BEB1A1BB15F4A00AED473 /* MJTestViewController.xib in Resources */, + 2DA7F9361AA6B4C4005627AB /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2DA7F93C1AA6B4C4005627AB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2DA7F9211AA6B4C4005627AB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2DB2EA181BECBE6700D58F6A /* MJRefreshBackFooter.m in Sources */, + 2D4698861D0EE6A400CB8025 /* NSBundle+MJRefresh.m in Sources */, + 2DB2EA1A1BECBE6700D58F6A /* MJRefreshFooter.m in Sources */, + 2D9BEB0F1BB15F4A00AED473 /* MJDIYHeader.m in Sources */, + 2D9BEB181BB15F4A00AED473 /* MJTableViewController.m in Sources */, + 2DB2EA261BECBE6700D58F6A /* MJRefreshConst.m in Sources */, + 2D9BEB0A1BB15F4A00AED473 /* MJChiBaoZiFooter.m in Sources */, + 2D9BEB121BB15F4A00AED473 /* MJExampleWindow.m in Sources */, + 2DB2EA221BECBE6700D58F6A /* MJRefreshGifHeader.m in Sources */, + 2D9BEB131BB15F4A00AED473 /* MJNavigationController.m in Sources */, + 2DB2EA271BECBE6700D58F6A /* UIScrollView+MJExtension.m in Sources */, + 2DB2EA1F1BECBE6700D58F6A /* MJRefreshBackGifFooter.m in Sources */, + 2DB2EA1C1BECBE6700D58F6A /* MJRefreshAutoGifFooter.m in Sources */, + 2DB2EA231BECBE6700D58F6A /* MJRefreshNormalHeader.m in Sources */, + 2DB2EA191BECBE6700D58F6A /* MJRefreshComponent.m in Sources */, + 2D9BEB0E1BB15F4A00AED473 /* MJDIYBackFooter.m in Sources */, + 2D9BEB161BB15F4A00AED473 /* AppDelegate.m in Sources */, + 2DB2EA291BECBE6700D58F6A /* UIView+MJExtension.m in Sources */, + 2D9BEB141BB15F4A00AED473 /* MJSingleViewController.m in Sources */, + 2D9BEB0D1BB15F4A00AED473 /* MJDIYAutoFooter.m in Sources */, + 2D9BEB1B1BB15F4A00AED473 /* MJWebViewViewController.m in Sources */, + 2DB2EA171BECBE6700D58F6A /* MJRefreshAutoFooter.m in Sources */, + 2D9BEB101BB15F4A00AED473 /* MJExample.m in Sources */, + 2DB2EA201BECBE6700D58F6A /* MJRefreshBackNormalFooter.m in Sources */, + 2DA7F92B1AA6B4C4005627AB /* main.m in Sources */, + 2DB2EA1E1BECBE6700D58F6A /* MJRefreshAutoStateFooter.m in Sources */, + 2DB2EA241BECBE6700D58F6A /* MJRefreshStateHeader.m in Sources */, + 2D9BEB091BB15F4A00AED473 /* UIViewController+Example.m in Sources */, + 2D9BEB111BB15F4A00AED473 /* MJExampleViewController.m in Sources */, + 2DB2EA1D1BECBE6700D58F6A /* MJRefreshAutoNormalFooter.m in Sources */, + 2D9BEB0C1BB15F4A00AED473 /* MJChiBaoZiHeader.m in Sources */, + 2DB2EA1B1BECBE6700D58F6A /* MJRefreshHeader.m in Sources */, + 2D9BEB191BB15F4A00AED473 /* MJTestViewController.m in Sources */, + 2DB2EA211BECBE6700D58F6A /* MJRefreshBackStateFooter.m in Sources */, + 2DB2EA281BECBE6700D58F6A /* UIScrollView+MJRefresh.m in Sources */, + 2D9BEB151BB15F4A00AED473 /* MJTempViewController.m in Sources */, + 2D9BEB171BB15F4A00AED473 /* MJCollectionViewController.m in Sources */, + 2D9BEB0B1BB15F4A00AED473 /* MJChiBaoZiFooter2.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2DA7F93A1AA6B4C4005627AB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2DA7F9451AA6B4C4005627AB /* MJRefreshExampleTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 2DA7F9401AA6B4C4005627AB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2DA7F9241AA6B4C4005627AB /* MJRefreshExample */; + targetProxy = 2DA7F93F1AA6B4C4005627AB /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 2DA7F9321AA6B4C4005627AB /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 2DA7F9331AA6B4C4005627AB /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 2DA7F9371AA6B4C4005627AB /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 2DA7F9381AA6B4C4005627AB /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 2DA7F9461AA6B4C4005627AB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2DA7F9471AA6B4C4005627AB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 2DA7F9491AA6B4C4005627AB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + GCC_PREFIX_HEADER = MJRefreshExample/PrefixHeader.pch; + INFOPLIST_FILE = MJRefreshExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mj.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 2DA7F94A1AA6B4C4005627AB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + GCC_PREFIX_HEADER = MJRefreshExample/PrefixHeader.pch; + INFOPLIST_FILE = MJRefreshExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mj.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 2DA7F94C1AA6B4C4005627AB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/System/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = MJRefreshExampleTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mj.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MJRefreshExample.app/MJRefreshExample"; + }; + name = Debug; + }; + 2DA7F94D1AA6B4C4005627AB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/System/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = MJRefreshExampleTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mj.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MJRefreshExample.app/MJRefreshExample"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2DA7F9201AA6B4C4005627AB /* Build configuration list for PBXProject "MJRefreshExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2DA7F9461AA6B4C4005627AB /* Debug */, + 2DA7F9471AA6B4C4005627AB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2DA7F9481AA6B4C4005627AB /* Build configuration list for PBXNativeTarget "MJRefreshExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2DA7F9491AA6B4C4005627AB /* Debug */, + 2DA7F94A1AA6B4C4005627AB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2DA7F94B1AA6B4C4005627AB /* Build configuration list for PBXNativeTarget "MJRefreshExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2DA7F94C1AA6B4C4005627AB /* Debug */, + 2DA7F94D1AA6B4C4005627AB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 2DA7F91D1AA6B4C4005627AB /* Project object */; +} diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..1b401f3 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Base.lproj/LaunchScreen.xib @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Base.lproj/Main.storyboard b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Base.lproj/Main.storyboard new file mode 100644 index 0000000..882f7c4 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Base.lproj/Main.storyboard @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Category/UIViewController+Example.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Category/UIViewController+Example.h new file mode 100644 index 0000000..0b50e58 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Category/UIViewController+Example.h @@ -0,0 +1,13 @@ +// +// UIViewController+Example.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/12. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import + +@interface UIViewController (Example) +@property (copy, nonatomic) NSString *method; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Category/UIViewController+Example.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Category/UIViewController+Example.m new file mode 100644 index 0000000..d236cb5 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Category/UIViewController+Example.m @@ -0,0 +1,39 @@ +// +// UIViewController+Example.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/12. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "UIViewController+Example.h" +#import + +@implementation UIViewController (Example) + +#pragma mark - swizzle ++ (void)load +{ + Method method1 = class_getInstanceMethod([self class], NSSelectorFromString(@"dealloc")); + Method method2 = class_getInstanceMethod([self class], @selector(deallocSwizzle)); + method_exchangeImplementations(method1, method2); +} + +- (void)deallocSwizzle +{ + NSLog(@"%@被销毁了", self); + + [self deallocSwizzle]; +} + +static char MethodKey; +- (void)setMethod:(NSString *)method +{ + objc_setAssociatedObject(self, &MethodKey, method, OBJC_ASSOCIATION_COPY_NONATOMIC); +} + +- (NSString *)method +{ + return objc_getAssociatedObject(self, &MethodKey); +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter.h new file mode 100644 index 0000000..fa95f91 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter.h @@ -0,0 +1,13 @@ +// +// MJChiBaoZiFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/6/12. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoGifFooter.h" + +@interface MJChiBaoZiFooter : MJRefreshAutoGifFooter + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter.m new file mode 100644 index 0000000..39ec6a8 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter.m @@ -0,0 +1,26 @@ +// +// MJChiBaoZiFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/6/12. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJChiBaoZiFooter.h" + +@implementation MJChiBaoZiFooter +#pragma mark - 重写方法 +#pragma mark 基本设置 +- (void)prepare +{ + [super prepare]; + + // 设置正在刷新状态的动画图片 + NSMutableArray *refreshingImages = [NSMutableArray array]; + for (NSUInteger i = 1; i<=3; i++) { + UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]]; + [refreshingImages addObject:image]; + } + [self setImages:refreshingImages forState:MJRefreshStateRefreshing]; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter2.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter2.h new file mode 100644 index 0000000..e54da4f --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter2.h @@ -0,0 +1,13 @@ +// +// MJChiBaoZiFooter2.h +// MJRefreshExample +// +// Created by MJ Lee on 15/6/12. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackGifFooter.h" + +@interface MJChiBaoZiFooter2 : MJRefreshBackGifFooter + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter2.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter2.m new file mode 100644 index 0000000..12929ad --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiFooter2.m @@ -0,0 +1,37 @@ +// +// MJChiBaoZiFooter2.m +// MJRefreshExample +// +// Created by MJ Lee on 15/6/12. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJChiBaoZiFooter2.h" + +@implementation MJChiBaoZiFooter2 +#pragma mark - 重写方法 +#pragma mark 基本设置 +- (void)prepare +{ + [super prepare]; + + // 设置普通状态的动画图片 + NSMutableArray *idleImages = [NSMutableArray array]; + for (NSUInteger i = 1; i<=60; i++) { + UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%zd", i]]; + [idleImages addObject:image]; + } + [self setImages:idleImages forState:MJRefreshStateIdle]; + + // 设置即将刷新状态的动画图片(一松开就会刷新的状态) + NSMutableArray *refreshingImages = [NSMutableArray array]; + for (NSUInteger i = 1; i<=3; i++) { + UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]]; + [refreshingImages addObject:image]; + } + [self setImages:refreshingImages forState:MJRefreshStatePulling]; + + // 设置正在刷新状态的动画图片 + [self setImages:refreshingImages forState:MJRefreshStateRefreshing]; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiHeader.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiHeader.h new file mode 100644 index 0000000..6c6b7a3 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiHeader.h @@ -0,0 +1,13 @@ +// +// MJChiBaoZiHeader.h +// MJRefreshExample +// +// Created by MJ Lee on 15/6/12. +// Copyright © 2015年 小码哥. All rights reserved. +// 吃包子效果的头部控件 + +#import "MJRefreshGifHeader.h" + +@interface MJChiBaoZiHeader : MJRefreshGifHeader + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiHeader.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiHeader.m new file mode 100644 index 0000000..9ab6399 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJChiBaoZiHeader.m @@ -0,0 +1,37 @@ +// +// MJChiBaoZiHeader.m +// MJRefreshExample +// +// Created by MJ Lee on 15/6/12. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJChiBaoZiHeader.h" + +@implementation MJChiBaoZiHeader +#pragma mark - 重写方法 +#pragma mark 基本设置 +- (void)prepare +{ + [super prepare]; + + // 设置普通状态的动画图片 + NSMutableArray *idleImages = [NSMutableArray array]; + for (NSUInteger i = 1; i<=60; i++) { + UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%zd", i]]; + [idleImages addObject:image]; + } + [self setImages:idleImages forState:MJRefreshStateIdle]; + + // 设置即将刷新状态的动画图片(一松开就会刷新的状态) + NSMutableArray *refreshingImages = [NSMutableArray array]; + for (NSUInteger i = 1; i<=3; i++) { + UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%zd", i]]; + [refreshingImages addObject:image]; + } + [self setImages:refreshingImages forState:MJRefreshStatePulling]; + + // 设置正在刷新状态的动画图片 + [self setImages:refreshingImages forState:MJRefreshStateRefreshing]; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYAutoFooter.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYAutoFooter.h new file mode 100644 index 0000000..5bec352 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYAutoFooter.h @@ -0,0 +1,13 @@ +// +// MJDIYAutoFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshAutoFooter.h" + +@interface MJDIYAutoFooter : MJRefreshAutoFooter + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYAutoFooter.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYAutoFooter.m new file mode 100644 index 0000000..dfbcee0 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYAutoFooter.m @@ -0,0 +1,104 @@ +// +// MJDIYAutoFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJDIYAutoFooter.h" + +@interface MJDIYAutoFooter() +@property (weak, nonatomic) UILabel *label; +@property (weak, nonatomic) UISwitch *s; +@property (weak, nonatomic) UIActivityIndicatorView *loading; +@end + +@implementation MJDIYAutoFooter +#pragma mark - 重写方法 +#pragma mark 在这里做一些初始化配置(比如添加子控件) +- (void)prepare +{ + [super prepare]; + + // 设置控件的高度 + self.mj_h = 50; + + // 添加label + UILabel *label = [[UILabel alloc] init]; + label.textColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.0 alpha:1.0]; + label.font = [UIFont boldSystemFontOfSize:16]; + label.textAlignment = NSTextAlignmentCenter; + [self addSubview:label]; + self.label = label; + + // 打酱油的开关 + UISwitch *s = [[UISwitch alloc] init]; + [self addSubview:s]; + self.s = s; + + // loading + UIActivityIndicatorView *loading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [self addSubview:loading]; + self.loading = loading; +} + +#pragma mark 在这里设置子控件的位置和尺寸 +- (void)placeSubviews +{ + [super placeSubviews]; + + self.label.frame = self.bounds; + self.s.center = CGPointMake(self.mj_w - 20, self.mj_h - 20); + + self.loading.center = CGPointMake(30, self.mj_h * 0.5); +} + +#pragma mark 监听scrollView的contentOffset改变 +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change +{ + [super scrollViewContentOffsetDidChange:change]; + +} + +#pragma mark 监听scrollView的contentSize改变 +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change +{ + [super scrollViewContentSizeDidChange:change]; + +} + +#pragma mark 监听scrollView的拖拽状态改变 +- (void)scrollViewPanStateDidChange:(NSDictionary *)change +{ + [super scrollViewPanStateDidChange:change]; + +} + +#pragma mark 监听控件的刷新状态 +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState; + + switch (state) { + case MJRefreshStateIdle: + self.label.text = @"赶紧上拉吖(开关是打酱油滴)"; + [self.loading stopAnimating]; + [self.s setOn:NO animated:YES]; + break; + case MJRefreshStateRefreshing: + [self.s setOn:YES animated:YES]; + self.label.text = @"加载数据中(开关是打酱油滴)"; + [self.loading startAnimating]; + break; + case MJRefreshStateNoMoreData: + self.label.text = @"木有数据了(开关是打酱油滴)"; + [self.s setOn:NO animated:YES]; + [self.loading stopAnimating]; + break; + default: + break; + } +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYBackFooter.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYBackFooter.h new file mode 100644 index 0000000..c155cef --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYBackFooter.h @@ -0,0 +1,13 @@ +// +// MJDIYBackFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefreshBackFooter.h" + +@interface MJDIYBackFooter : MJRefreshBackFooter + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYBackFooter.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYBackFooter.m new file mode 100644 index 0000000..d847f63 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYBackFooter.m @@ -0,0 +1,130 @@ +// +// MJDIYBackFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJDIYBackFooter.h" + +@interface MJDIYBackFooter() +@property (weak, nonatomic) UILabel *label; +@property (weak, nonatomic) UISwitch *s; +@property (weak, nonatomic) UIImageView *logo; +@property (weak, nonatomic) UIActivityIndicatorView *loading; +@end + +@implementation MJDIYBackFooter +#pragma mark - 重写方法 +#pragma mark 在这里做一些初始化配置(比如添加子控件) +- (void)prepare +{ + [super prepare]; + + // 设置控件的高度 + self.mj_h = 50; + + // 添加label + UILabel *label = [[UILabel alloc] init]; + label.textColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.0 alpha:1.0]; + label.font = [UIFont boldSystemFontOfSize:16]; + label.textAlignment = NSTextAlignmentCenter; + [self addSubview:label]; + self.label = label; + + // 打酱油的开关 + UISwitch *s = [[UISwitch alloc] init]; + [self addSubview:s]; + self.s = s; + + // logo + UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Logo"]]; + logo.contentMode = UIViewContentModeScaleAspectFit; + [self addSubview:logo]; + self.logo = logo; + + // loading + UIActivityIndicatorView *loading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [self addSubview:loading]; + self.loading = loading; +} + +#pragma mark 在这里设置子控件的位置和尺寸 +- (void)placeSubviews +{ + [super placeSubviews]; + + self.label.frame = self.bounds; + + self.logo.bounds = CGRectMake(0, 0, self.bounds.size.width, 100); + self.logo.center = CGPointMake(self.mj_w * 0.5, self.mj_h + self.logo.mj_h * 0.5); + + self.loading.center = CGPointMake(self.mj_w - 30, self.mj_h * 0.5); +} + +#pragma mark 监听scrollView的contentOffset改变 +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change +{ + [super scrollViewContentOffsetDidChange:change]; + +} + +#pragma mark 监听scrollView的contentSize改变 +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change +{ + [super scrollViewContentSizeDidChange:change]; + +} + +#pragma mark 监听scrollView的拖拽状态改变 +- (void)scrollViewPanStateDidChange:(NSDictionary *)change +{ + [super scrollViewPanStateDidChange:change]; + +} + +#pragma mark 监听控件的刷新状态 +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState; + + switch (state) { + case MJRefreshStateIdle: + [self.loading stopAnimating]; + [self.s setOn:NO animated:YES]; + self.label.text = @"赶紧上拉吖(开关是打酱油滴)"; + break; + case MJRefreshStatePulling: + [self.loading stopAnimating]; + [self.s setOn:YES animated:YES]; + self.label.text = @"赶紧放开我吧(开关是打酱油滴)"; + break; + case MJRefreshStateRefreshing: + [self.loading startAnimating]; + [self.s setOn:YES animated:YES]; + self.label.text = @"加载数据中(开关是打酱油滴)"; + break; + case MJRefreshStateNoMoreData: + [self.loading stopAnimating]; + self.label.text = @"木有数据了(开关是打酱油滴)"; + [self.s setOn:NO animated:YES]; + default: + break; + } +} + +#pragma mark 监听拖拽比例(控件被拖出来的比例) +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + [super setPullingPercent:pullingPercent]; + + // 1.0 0.5 0.0 + // 0.5 0.0 0.5 + CGFloat red = 1.0 - pullingPercent * 0.5; + CGFloat green = 0.5 - 0.5 * pullingPercent; + CGFloat blue = 0.5 * pullingPercent; + self.label.textColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0]; +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYHeader.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYHeader.h new file mode 100644 index 0000000..188d8a6 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYHeader.h @@ -0,0 +1,13 @@ +// +// MJDIYHeader.h +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJRefresh.h" + +@interface MJDIYHeader : MJRefreshHeader + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYHeader.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYHeader.m new file mode 100644 index 0000000..42ad6b6 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/DIY/MJDIYHeader.m @@ -0,0 +1,126 @@ +// +// MJDIYHeader.m +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJDIYHeader.h" + +@interface MJDIYHeader() +@property (weak, nonatomic) UILabel *label; +@property (weak, nonatomic) UISwitch *s; +@property (weak, nonatomic) UIImageView *logo; +@property (weak, nonatomic) UIActivityIndicatorView *loading; +@end + +@implementation MJDIYHeader +#pragma mark - 重写方法 +#pragma mark 在这里做一些初始化配置(比如添加子控件) +- (void)prepare +{ + [super prepare]; + + // 设置控件的高度 + self.mj_h = 50; + + // 添加label + UILabel *label = [[UILabel alloc] init]; + label.textColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.0 alpha:1.0]; + label.font = [UIFont boldSystemFontOfSize:16]; + label.textAlignment = NSTextAlignmentCenter; + [self addSubview:label]; + self.label = label; + + // 打酱油的开关 + UISwitch *s = [[UISwitch alloc] init]; + [self addSubview:s]; + self.s = s; + + // logo + UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Logo"]]; + logo.contentMode = UIViewContentModeScaleAspectFit; + [self addSubview:logo]; + self.logo = logo; + + // loading + UIActivityIndicatorView *loading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [self addSubview:loading]; + self.loading = loading; +} + +#pragma mark 在这里设置子控件的位置和尺寸 +- (void)placeSubviews +{ + [super placeSubviews]; + + self.label.frame = self.bounds; + + self.logo.bounds = CGRectMake(0, 0, self.bounds.size.width, 100); + self.logo.center = CGPointMake(self.mj_w * 0.5, - self.logo.mj_h + 20); + + self.loading.center = CGPointMake(self.mj_w - 30, self.mj_h * 0.5); +} + +#pragma mark 监听scrollView的contentOffset改变 +- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change +{ + [super scrollViewContentOffsetDidChange:change]; + +} + +#pragma mark 监听scrollView的contentSize改变 +- (void)scrollViewContentSizeDidChange:(NSDictionary *)change +{ + [super scrollViewContentSizeDidChange:change]; + +} + +#pragma mark 监听scrollView的拖拽状态改变 +- (void)scrollViewPanStateDidChange:(NSDictionary *)change +{ + [super scrollViewPanStateDidChange:change]; + +} + +#pragma mark 监听控件的刷新状态 +- (void)setState:(MJRefreshState)state +{ + MJRefreshCheckState; + + switch (state) { + case MJRefreshStateIdle: + [self.loading stopAnimating]; + [self.s setOn:NO animated:YES]; + self.label.text = @"赶紧下拉吖(开关是打酱油滴)"; + break; + case MJRefreshStatePulling: + [self.loading stopAnimating]; + [self.s setOn:YES animated:YES]; + self.label.text = @"赶紧放开我吧(开关是打酱油滴)"; + break; + case MJRefreshStateRefreshing: + [self.s setOn:YES animated:YES]; + self.label.text = @"加载数据中(开关是打酱油滴)"; + [self.loading startAnimating]; + break; + default: + break; + } +} + +#pragma mark 监听拖拽比例(控件被拖出来的比例) +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + [super setPullingPercent:pullingPercent]; + + // 1.0 0.5 0.0 + // 0.5 0.0 0.5 + CGFloat red = 1.0 - pullingPercent * 0.5; + CGFloat green = 0.5 - 0.5 * pullingPercent; + CGFloat blue = 0.5 * pullingPercent; + self.label.textColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0]; +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExample.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExample.h new file mode 100644 index 0000000..c296ac6 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExample.h @@ -0,0 +1,17 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJExample.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import + +@interface MJExample : NSObject +@property (copy, nonatomic) NSString *header; +@property (strong, nonatomic) NSArray *titles; +@property (strong, nonatomic) NSArray *methods; +@property (assign, nonatomic) Class vcClass; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExample.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExample.m new file mode 100644 index 0000000..04de76b --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExample.m @@ -0,0 +1,14 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJExample.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJExample.h" + +@implementation MJExample + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleViewController.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleViewController.h new file mode 100644 index 0000000..931c892 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleViewController.h @@ -0,0 +1,14 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJExampleViewController.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import + +@interface MJExampleViewController : UITableViewController + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleViewController.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleViewController.m new file mode 100644 index 0000000..0fd2f81 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleViewController.m @@ -0,0 +1,128 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJExampleViewController.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJExampleViewController.h" +#import "MJTableViewController.h" +#import "MJWebViewViewController.h" +#import "MJCollectionViewController.h" +#import "MJExample.h" +#import "UIViewController+Example.h" +#import "MJRefresh.h" + +static NSString *const MJExample00 = @"UITableView + 下拉刷新"; +static NSString *const MJExample10 = @"UITableView + 上拉刷新"; +static NSString *const MJExample20 = @"UICollectionView"; +static NSString *const MJExample30 = @"UIWebView"; + +@interface MJExampleViewController() +@property (strong, nonatomic) NSArray *examples; +@end + +@implementation MJExampleViewController + +- (NSArray *)examples +{ + if (!_examples) { + MJExample *exam0 = [[MJExample alloc] init]; + exam0.header = MJExample00; + exam0.vcClass = [MJTableViewController class]; + exam0.titles = @[@"默认", @"动画图片", @"隐藏时间", @"隐藏状态和时间", @"自定义文字", @"自定义刷新控件"]; + exam0.methods = @[@"example01", @"example02", @"example03", @"example04", @"example05", @"example06"]; + + MJExample *exam1 = [[MJExample alloc] init]; + exam1.header = MJExample10; + exam1.vcClass = [MJTableViewController class]; + exam1.titles = @[@"默认", @"动画图片", @"隐藏刷新状态的文字", @"全部加载完毕", @"禁止自动加载", @"自定义文字", @"加载后隐藏", @"自动回弹的上拉01", @"自动回弹的上拉02", @"自定义刷新控件(自动刷新)", @"自定义刷新控件(自动回弹)"]; + exam1.methods = @[@"example11", @"example12", @"example13", @"example14", @"example15", @"example16", @"example17", @"example18", @"example19", @"example20", @"example21"]; + + MJExample *exam2 = [[MJExample alloc] init]; + exam2.header = MJExample20; + exam2.vcClass = [MJCollectionViewController class]; + exam2.titles = @[@"上下拉刷新"]; + exam2.methods = @[@"example21"]; + + MJExample *exam3 = [[MJExample alloc] init]; + exam3.header = MJExample30; + exam3.vcClass = [MJWebViewViewController class]; + exam3.titles = @[@"下拉刷新"]; + exam3.methods = @[@"example31"]; + + self.examples = @[exam0, exam1, exam2, exam3]; + } + return _examples; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + __unsafe_unretained UITableView *tableView = self.tableView; + + // 下拉刷新 + tableView.mj_header= [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + // 模拟延迟加载数据,因此2秒后才调用(真实开发中,可以移除这段gcd代码) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // 结束刷新 + [tableView.mj_header endRefreshing]; + }); + }]; + + // 设置自动切换透明度(在导航栏下面自动隐藏) + tableView.mj_header.automaticallyChangeAlpha = YES; + + // 上拉刷新 + tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{ + // 模拟延迟加载数据,因此2秒后才调用(真实开发中,可以移除这段gcd代码) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // 结束刷新 + [tableView.mj_footer endRefreshing]; + }); + }]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return self.examples.count; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + MJExample *exam = self.examples[section]; + return exam.titles.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *ID = @"example"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; + + MJExample *exam = self.examples[indexPath.section]; + cell.textLabel.text = exam.titles[indexPath.row]; + + cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ - %@", exam.vcClass, exam.methods[indexPath.row]]; + + return cell; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + MJExample *exam = self.examples[section]; + return exam.header; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + MJExample *exam = self.examples[indexPath.section]; + UIViewController *vc = [[exam.vcClass alloc] init]; + vc.title = exam.titles[indexPath.row]; + [vc setValue:exam.methods[indexPath.row] forKeyPath:@"method"]; + [self.navigationController pushViewController:vc animated:YES]; +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleWindow.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleWindow.h new file mode 100644 index 0000000..d269b69 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleWindow.h @@ -0,0 +1,13 @@ +// +// MJExampleWindow.h +// MJRefreshExample +// +// Created by MJ Lee on 15/8/17. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import + +@interface MJExampleWindow : UIWindow ++ (void)show; +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleWindow.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleWindow.m new file mode 100644 index 0000000..a646372 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJExampleWindow.m @@ -0,0 +1,27 @@ +// +// MJExampleWindow.m +// MJRefreshExample +// +// Created by MJ Lee on 15/8/17. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJExampleWindow.h" +#import "MJTempViewController.h" + +@implementation MJExampleWindow + +static UIWindow *window_; ++ (void)show +{ + window_ = [[UIWindow alloc] init]; + CGFloat width = 150; + CGFloat x = [UIScreen mainScreen].bounds.size.width - width - 10; + window_.frame = CGRectMake(x, 0, width, 25); + window_.windowLevel = UIWindowLevelAlert; + window_.hidden = NO; + window_.alpha = 0.5; + window_.rootViewController = [[MJTempViewController alloc] init]; + window_.backgroundColor = [UIColor clearColor]; +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJNavigationController.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJNavigationController.h new file mode 100644 index 0000000..0b47b8f --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJNavigationController.h @@ -0,0 +1,14 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJNavigationController.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import + +@interface MJNavigationController : UINavigationController + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJNavigationController.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJNavigationController.m new file mode 100644 index 0000000..ad5a225 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJNavigationController.m @@ -0,0 +1,39 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJNavigationController.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJNavigationController.h" +// 判断是否为iOS7 +#define iOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) + +@implementation MJNavigationController + +#pragma mark 一个类只会调用一次 ++ (void)initialize +{ + // 1.取出设置主题的对象 + UINavigationBar *navBar = [UINavigationBar appearanceWhenContainedIn:[MJNavigationController class], nil]; + + // 2.设置导航栏的背景图片 + NSString *navBarBg = nil; + if (iOS7) { // iOS7 + navBarBg = @"NavBar64"; + navBar.tintColor = [UIColor whiteColor]; + } else { // 非iOS7 + navBarBg = @"NavBar"; + } + [navBar setBackgroundImage:[UIImage imageNamed:navBarBg] forBarMetrics:UIBarMetricsDefault]; + + // 3.标题 +#ifdef __IPHONE_7_0 + [navBar setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]}]; +#else + [navBar setTitleTextAttributes:@{UITextAttributeTextColor : [UIColor whiteColor]}]; +#endif +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJSingleViewController.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJSingleViewController.h new file mode 100644 index 0000000..aab1b4e --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJSingleViewController.h @@ -0,0 +1,13 @@ +// +// MJSingleViewController.h +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import + +@interface MJSingleViewController : UITableViewController + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJSingleViewController.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJSingleViewController.m new file mode 100644 index 0000000..414cecb --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJSingleViewController.m @@ -0,0 +1,78 @@ +// +// MJSingleViewController.m +// MJRefreshExample +// +// Created by MJ Lee on 15/6/13. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJSingleViewController.h" +#import "MJTestViewController.h" +#import "MJRefresh.h" + +@interface MJSingleViewController () +@property (assign, nonatomic) int count; +@end + +@implementation MJSingleViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.count = 0; + + __unsafe_unretained typeof(self) weakSelf = self; + __unsafe_unretained UITableView *tableView = self.tableView; + + tableView.mj_header= [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + weakSelf.count += 12; + [tableView reloadData]; + [tableView.mj_header endRefreshing]; + }); + }]; + tableView.mj_header.automaticallyChangeAlpha = YES; + + MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + weakSelf.count += 5; + [tableView reloadData]; + [tableView.mj_footer endRefreshing]; + }); + }]; + footer.hidden = YES; + tableView.mj_footer = footer; +} + +- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return self.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *ID = @"cell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; + if (cell == nil) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; + } + if (indexPath.row % 2 && self.navigationController) { + cell.textLabel.text = @"push"; + } else { + cell.textLabel.text = @"modal"; + } + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + MJTestViewController *test = [[MJTestViewController alloc] init]; + if (indexPath.row % 2 && self.navigationController) { + test.hidesBottomBarWhenPushed = YES; + [self.navigationController pushViewController:test animated:YES]; + } else { + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:test]; + [self presentViewController:nav animated:YES completion:nil]; + } +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJTempViewController.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJTempViewController.h new file mode 100644 index 0000000..e732ab9 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJTempViewController.h @@ -0,0 +1,18 @@ +// +// MJTempViewController.h +// MJRefreshExample +// +// Created by MJ Lee on 15/9/22. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import + +@interface MJTempViewController : UIViewController + ++ (instancetype)sharedInstance; + +@property (assign, nonatomic) UIStatusBarStyle statusBarStyle; +@property (assign, nonatomic) BOOL statusBarHidden; + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJTempViewController.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJTempViewController.m new file mode 100644 index 0000000..f64ccb9 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/First/MJTempViewController.m @@ -0,0 +1,94 @@ +// +// MJTempViewController.m +// MJRefreshExample +// +// Created by MJ Lee on 15/9/22. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#import "MJTempViewController.h" + +@interface MJTempViewController () + +@end + +@implementation MJTempViewController +#pragma mark - 单例 +static id instance_; + ++ (instancetype)sharedInstance +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance_ = [[self alloc] init]; + }); + return instance_; +} + ++ (instancetype)allocWithZone:(struct _NSZone *)zone +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance_ = [super allocWithZone:zone]; + }); + return instance_; +} + +#pragma mark - 初始化 +- (void)viewDidLoad { + [super viewDidLoad]; + + self.statusBarStyle = UIStatusBarStyleLightContent; + + self.view.backgroundColor = [UIColor clearColor]; + + UISegmentedControl *control = [[UISegmentedControl alloc] initWithItems:@[@"示例1", @"示例2", @"示例3"]]; + control.tintColor = [UIColor orangeColor]; + control.frame = self.view.bounds; + control.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + control.selectedSegmentIndex = 0; + [control addTarget:self action:@selector(contorlSelect:) forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:control]; +} + +- (void)contorlSelect:(UISegmentedControl *)control +{ + UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; + keyWindow.rootViewController = [keyWindow.rootViewController.storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:@"%zd", control.selectedSegmentIndex]]; + + if (control.selectedSegmentIndex == 0) { + self.statusBarStyle = UIStatusBarStyleLightContent; + self.statusBarHidden = NO; + } else if (control.selectedSegmentIndex == 1) { + self.statusBarHidden = YES; + } else if (control.selectedSegmentIndex == 2) { + self.statusBarStyle = UIStatusBarStyleDefault; + self.statusBarHidden = NO; + } +} + +- (UIStatusBarStyle)preferredStatusBarStyle +{ + return self.statusBarStyle; +} + +- (BOOL)prefersStatusBarHidden +{ + return self.statusBarHidden; +} + +- (void)setStatusBarHidden:(BOOL)statusBarHidden +{ + _statusBarHidden = statusBarHidden; + + [self setNeedsStatusBarAppearanceUpdate]; +} + +- (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle +{ + _statusBarStyle = statusBarStyle; + + [self setNeedsStatusBarAppearanceUpdate]; +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Other/AppDelegate.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Other/AppDelegate.h new file mode 100644 index 0000000..d3330e8 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Other/AppDelegate.h @@ -0,0 +1,18 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// AppDelegate.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Other/AppDelegate.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Other/AppDelegate.m new file mode 100644 index 0000000..5428469 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Other/AppDelegate.m @@ -0,0 +1,50 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// AppDelegate.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "AppDelegate.h" +#import "MJExampleWindow.h" + +@interface AppDelegate () +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [MJExampleWindow show]; + }); +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJCollectionViewController.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJCollectionViewController.h new file mode 100644 index 0000000..3ce32ac --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJCollectionViewController.h @@ -0,0 +1,14 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJCollectionViewController.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/6. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import + +@interface MJCollectionViewController : UICollectionViewController + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJCollectionViewController.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJCollectionViewController.m new file mode 100644 index 0000000..82ef370 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJCollectionViewController.m @@ -0,0 +1,132 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJCollectionViewController.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/6. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJCollectionViewController.h" +#import "MJTestViewController.h" +#import "UIViewController+Example.h" +#import "MJRefresh.h" + +static const CGFloat MJDuration = 2.0; +/** + * 随机色 + */ +#define MJRandomColor [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1] + +@interface MJCollectionViewController() +/** 存放假数据 */ +@property (strong, nonatomic) NSMutableArray *colors; +@end + +@implementation MJCollectionViewController +#pragma mark - 示例 +#pragma mark UICollectionView 上下拉刷新 +- (void)example21 +{ + __weak __typeof(self) weakSelf = self; + + // 下拉刷新 + self.collectionView.mj_header= [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + // 增加5条假数据 + for (int i = 0; i<10; i++) { + [weakSelf.colors insertObject:MJRandomColor atIndex:0]; + } + + // 模拟延迟加载数据,因此2秒后才调用(真实开发中,可以移除这段gcd代码) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [weakSelf.collectionView reloadData]; + + // 结束刷新 + [weakSelf.collectionView.mj_header endRefreshing]; + }); + }]; + [self.collectionView.mj_header beginRefreshing]; + + // 上拉刷新 + self.collectionView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{ + // 增加5条假数据 + for (int i = 0; i<5; i++) { + [weakSelf.colors addObject:MJRandomColor]; + } + + // 模拟延迟加载数据,因此2秒后才调用(真实开发中,可以移除这段gcd代码) + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [weakSelf.collectionView reloadData]; + + // 结束刷新 + [weakSelf.collectionView.mj_footer endRefreshing]; + }); + }]; + // 默认先隐藏footer + self.collectionView.mj_footer.hidden = YES; +} + +#pragma mark - 数据相关 +- (NSMutableArray *)colors +{ + if (!_colors) { + self.colors = [NSMutableArray array]; + } + return _colors; +} + +#pragma mark - 其他 + +/** + * 初始化 + */ +- (id)init +{ + // UICollectionViewFlowLayout的初始化(与刷新控件无关) + UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; + layout.itemSize = CGSizeMake(80, 80); + layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20); + layout.minimumInteritemSpacing = 20; + layout.minimumLineSpacing = 20; + return [self initWithCollectionViewLayout:layout]; +} + +static NSString *const MJCollectionViewCellIdentifier = @"color"; +- (void)viewDidLoad +{ + [super viewDidLoad]; + + MJPerformSelectorLeakWarning( + [self performSelector:NSSelectorFromString(self.method) withObject:nil]; + ); + + self.collectionView.backgroundColor = [UIColor whiteColor]; + [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:MJCollectionViewCellIdentifier]; +} + +#pragma mark - collection数据源代理 +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + // 设置尾部控件的显示和隐藏 + self.collectionView.mj_footer.hidden = self.colors.count == 0; + return self.colors.count; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:MJCollectionViewCellIdentifier forIndexPath:indexPath]; + cell.backgroundColor = self.colors[indexPath.row]; + return cell; +} + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + MJTestViewController *test = [[MJTestViewController alloc] init]; + if (indexPath.row % 2) { + [self.navigationController pushViewController:test animated:YES]; + } else { + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:test]; + [self presentViewController:nav animated:YES completion:nil]; + } +} +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTableViewController.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTableViewController.h new file mode 100644 index 0000000..eedd036 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTableViewController.h @@ -0,0 +1,14 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJTableViewController.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import + +@interface MJTableViewController : UITableViewController + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTableViewController.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTableViewController.m new file mode 100644 index 0000000..3be9ed7 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTableViewController.m @@ -0,0 +1,410 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJTableViewController.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJTableViewController.h" +#import "UIView+MJExtension.h" +#import "MJTestViewController.h" +#import "UIViewController+Example.h" +#import "MJRefresh.h" + +// 自定义的header +#import "MJChiBaoZiHeader.h" +#import "MJChiBaoZiFooter.h" +#import "MJChiBaoZiFooter2.h" +#import "MJDIYHeader.h" +#import "MJDIYAutoFooter.h" +#import "MJDIYBackFooter.h" + +static const CGFloat MJDuration = 2.0; +/** + * 随机数据 + */ +#define MJRandomData [NSString stringWithFormat:@"随机数据---%d", arc4random_uniform(1000000)] + +@interface MJTableViewController() +/** 用来显示的假数据 */ +@property (strong, nonatomic) NSMutableArray *data; +@end + +@implementation MJTableViewController +#pragma mark - 示例代码 +#pragma mark UITableView + 下拉刷新 默认 +- (void)example01 +{ + __weak __typeof(self) weakSelf = self; + + // 设置回调(一旦进入刷新状态就会调用这个refreshingBlock) + self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + [weakSelf loadNewData]; + }]; + + // 马上进入刷新状态 + [self.tableView.mj_header beginRefreshing]; +} + +#pragma mark UITableView + 下拉刷新 动画图片 +- (void)example02 +{ + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法) + self.tableView.mj_header = [MJChiBaoZiHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; + + // 马上进入刷新状态 + [self.tableView.mj_header beginRefreshing]; +} + +#pragma mark UITableView + 下拉刷新 隐藏时间 +- (void)example03 +{ + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法) + MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; + + // 设置自动切换透明度(在导航栏下面自动隐藏) + header.automaticallyChangeAlpha = YES; + + // 隐藏时间 + header.lastUpdatedTimeLabel.hidden = YES; + + // 马上进入刷新状态 + [header beginRefreshing]; + + // 设置header + self.tableView.mj_header = header; +} + +#pragma mark UITableView + 下拉刷新 隐藏状态和时间 +- (void)example04 +{ + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法) + MJChiBaoZiHeader *header = [MJChiBaoZiHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; + + // 隐藏时间 + header.lastUpdatedTimeLabel.hidden = YES; + + // 隐藏状态 + header.stateLabel.hidden = YES; + + // 马上进入刷新状态 + [header beginRefreshing]; + + // 设置header + self.tableView.mj_header = header; +} + +#pragma mark UITableView + 下拉刷新 自定义文字 +- (void)example05 +{ + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法) + MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; + + // 设置文字 + [header setTitle:@"Pull down to refresh" forState:MJRefreshStateIdle]; + [header setTitle:@"Release to refresh" forState:MJRefreshStatePulling]; + [header setTitle:@"Loading ..." forState:MJRefreshStateRefreshing]; + + // 设置字体 + header.stateLabel.font = [UIFont systemFontOfSize:15]; + header.lastUpdatedTimeLabel.font = [UIFont systemFontOfSize:14]; + + // 设置颜色 + header.stateLabel.textColor = [UIColor redColor]; + header.lastUpdatedTimeLabel.textColor = [UIColor blueColor]; + + // 马上进入刷新状态 + [header beginRefreshing]; + + // 设置刷新控件 + self.tableView.mj_header = header; +} + +#pragma mark UITableView + 下拉刷新 自定义刷新控件 +- (void)example06 +{ + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法) + self.tableView.mj_header = [MJDIYHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; + [self.tableView.mj_header beginRefreshing]; +} + +#pragma mark UITableView + 上拉刷新 默认 +- (void)example11 +{ + [self example01]; + + __weak __typeof(self) weakSelf = self; + + // 设置回调(一旦进入刷新状态就会调用这个refreshingBlock) + self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ + [weakSelf loadMoreData]; + }]; +} + +#pragma mark UITableView + 上拉刷新 动画图片 +- (void)example12 +{ + [self example01]; + + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法) + self.tableView.mj_footer = [MJChiBaoZiFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +} + +#pragma mark UITableView + 上拉刷新 隐藏刷新状态的文字 +- (void)example13 +{ + [self example01]; + + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法) + MJChiBaoZiFooter *footer = [MJChiBaoZiFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; + + // 当上拉刷新控件出现50%时(出现一半),就会自动刷新。这个值默认是1.0(也就是上拉刷新100%出现时,才会自动刷新) + // footer.triggerAutomaticallyRefreshPercent = 0.5; + + // 隐藏刷新状态的文字 + footer.refreshingTitleHidden = YES; + + // 设置footer + self.tableView.mj_footer = footer; +} + +#pragma mark UITableView + 上拉刷新 全部加载完毕 +- (void)example14 +{ + [self example01]; + + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadLastData方法) + self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadLastData)]; + + // 其他 + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"恢复数据加载" style:UIBarButtonItemStyleDone target:self action:@selector(reset)]; +} + +- (void)reset +{ + [self.tableView.mj_footer setRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +// [self.tableView.mj_footer beginRefreshing]; + [self.tableView.mj_footer resetNoMoreData]; +} + +#pragma mark UITableView + 上拉刷新 禁止自动加载 +- (void)example15 +{ + [self example01]; + + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法) + MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; + + // 禁止自动加载 + footer.automaticallyRefresh = NO; + + // 设置footer + self.tableView.mj_footer = footer; +} + +#pragma mark UITableView + 上拉刷新 自定义文字 +- (void)example16 +{ + [self example01]; + + // 添加默认的上拉刷新 + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法) + MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; + + // 设置文字 + [footer setTitle:@"Click or drag up to refresh" forState:MJRefreshStateIdle]; + [footer setTitle:@"Loading more ..." forState:MJRefreshStateRefreshing]; + [footer setTitle:@"No more data" forState:MJRefreshStateNoMoreData]; + + // 设置字体 + footer.stateLabel.font = [UIFont systemFontOfSize:17]; + + // 设置颜色 + footer.stateLabel.textColor = [UIColor blueColor]; + + // 设置footer + self.tableView.mj_footer = footer; +} + +#pragma mark UITableView + 上拉刷新 加载后隐藏 +- (void)example17 +{ + [self example01]; + + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadOnceData方法) + self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadOnceData)]; +} + +#pragma mark UITableView + 上拉刷新 自动回弹的上拉01 +- (void)example18 +{ + [self example01]; + + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法) + self.tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; + // 设置了底部inset + self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 30, 0); + // 忽略掉底部inset + self.tableView.mj_footer.ignoredScrollViewContentInsetBottom = 30; +} + +#pragma mark UITableView + 上拉刷新 自动回弹的上拉02 +- (void)example19 +{ + [self example01]; + + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadLastData方法) + self.tableView.mj_footer = [MJChiBaoZiFooter2 footerWithRefreshingTarget:self refreshingAction:@selector(loadLastData)]; + self.tableView.mj_footer.automaticallyChangeAlpha = YES; +} + +#pragma mark UITableView + 上拉刷新 自定义刷新控件(自动刷新) +- (void)example20 +{ + [self example01]; + + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法) + self.tableView.mj_footer = [MJDIYAutoFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +} + +#pragma mark UITableView + 上拉刷新 自定义刷新控件(自动回弹) +- (void)example21 +{ + [self example01]; + + // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法) + self.tableView.mj_footer = [MJDIYBackFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +} + +#pragma mark - 数据处理相关 +#pragma mark 下拉刷新数据 +- (void)loadNewData +{ + // 1.添加假数据 + for (int i = 0; i<5; i++) { + [self.data insertObject:MJRandomData atIndex:0]; + } + + // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码) + __weak UITableView *tableView = self.tableView; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // 刷新表格 + [tableView reloadData]; + + // 拿到当前的下拉刷新控件,结束刷新状态 + [tableView.mj_header endRefreshing]; + }); +} + +#pragma mark 上拉加载更多数据 +- (void)loadMoreData +{ + // 1.添加假数据 + for (int i = 0; i<5; i++) { + [self.data addObject:MJRandomData]; + } + + // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码) + __weak UITableView *tableView = self.tableView; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // 刷新表格 + [tableView reloadData]; + + // 拿到当前的上拉刷新控件,结束刷新状态 + [tableView.mj_footer endRefreshing]; + }); +} + +#pragma mark 加载最后一份数据 +- (void)loadLastData +{ + // 1.添加假数据 + for (int i = 0; i<5; i++) { + [self.data addObject:MJRandomData]; + } + + // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码) + __weak UITableView *tableView = self.tableView; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // 刷新表格 + [tableView reloadData]; + + // 拿到当前的上拉刷新控件,变为没有更多数据的状态 + [tableView.mj_footer endRefreshingWithNoMoreData]; + }); +} + +#pragma mark 只加载一次数据 +- (void)loadOnceData +{ + // 1.添加假数据 + for (int i = 0; i<5; i++) { + [self.data addObject:MJRandomData]; + } + + // 2.模拟2秒后刷新表格UI(真实开发中,可以移除这段gcd代码) + __weak UITableView *tableView = self.tableView; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // 刷新表格 + [tableView reloadData]; + + // 隐藏当前的上拉刷新控件 + tableView.mj_footer.hidden = YES; + }); +} + +- (NSMutableArray *)data +{ + if (!_data) { + self.data = [NSMutableArray array]; + for (int i = 0; i<5; i++) { + [self.data addObject:MJRandomData]; + } + } + return _data; +} + +#pragma mark - 其他 +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; + MJPerformSelectorLeakWarning( + [self performSelector:NSSelectorFromString(self.method) withObject:nil]; + ); +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return self.data.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *ID = @"cell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; + if (cell == nil) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; + } + + cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@", indexPath.row % 2?@"push":@"modal", self.data[indexPath.row]]; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + MJTestViewController *test = [[MJTestViewController alloc] init]; + if (indexPath.row % 2) { + [self.navigationController pushViewController:test animated:YES]; + } else { + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:test]; + [self presentViewController:nav animated:YES completion:nil]; + } +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTestViewController.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTestViewController.h new file mode 100644 index 0000000..e6f694c --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTestViewController.h @@ -0,0 +1,22 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJTestViewController.h +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 小码哥. All rights reserved. +// + +#import + +#define MJPerformSelectorLeakWarning(Stuff) \ +do { \ +_Pragma("clang diagnostic push") \ +_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \ +Stuff; \ +_Pragma("clang diagnostic pop") \ +} while (0) + +@interface MJTestViewController : UIViewController + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTestViewController.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTestViewController.m new file mode 100644 index 0000000..e73486a --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTestViewController.m @@ -0,0 +1,36 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJTestViewController.m +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 小码哥. All rights reserved. +// + +#import "MJTestViewController.h" + +@interface MJTestViewController () + +@end + +@implementation MJTestViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.title = @"测试控制器"; + + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStyleDone target:self action:@selector(close)]; +} + +- (void)close +{ + if (self.presentingViewController) { + [self dismissViewControllerAnimated:YES completion:nil]; + } else { + [self.navigationController popViewControllerAnimated:YES]; + } +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTestViewController.xib b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTestViewController.xib new file mode 100644 index 0000000..f95cd19 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJTestViewController.xib @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJWebViewViewController.h b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJWebViewViewController.h new file mode 100644 index 0000000..e6aafab --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJWebViewViewController.h @@ -0,0 +1,13 @@ +// +// MJWebViewViewController.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/12. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import + +@interface MJWebViewViewController : UIViewController + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJWebViewViewController.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJWebViewViewController.m new file mode 100644 index 0000000..06c8506 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJWebViewViewController.m @@ -0,0 +1,78 @@ +// +// MJWebViewViewController.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/12. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import "MJWebViewViewController.h" +#import "UIViewController+Example.h" +#import "MJRefresh.h" + +@interface MJWebViewViewController () +@property (weak, nonatomic) IBOutlet UIWebView *webView; +@end + +@implementation MJWebViewViewController +#pragma mark - 示例 +- (void)example31 +{ + __weak UIWebView *webView = self.webView; + webView.delegate = self; + + __weak UIScrollView *scrollView = self.webView.scrollView; + + // 添加下拉刷新控件 + scrollView.mj_header= [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + [webView reload]; + }]; + + // 如果是上拉刷新,就以此类推 +} + +#pragma mark - webViewDelegate +- (void)webViewDidFinishLoad:(nonnull UIWebView *)webView +{ + [self.webView.scrollView.mj_header endRefreshing]; +} + +#pragma mark - 其他 +- (void)viewDidLoad { + [super viewDidLoad]; + + // 加载页面 + [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://weibo.com/exceptions"]]]; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [self performSelector:NSSelectorFromString(self.method) withObject:nil]; +#pragma clang diagnostic pop +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + [self.navigationController setNavigationBarHidden:YES animated:YES]; + + [self setNeedsStatusBarAppearanceUpdate]; +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; + + [self.navigationController setNavigationBarHidden:NO animated:YES]; +} + +- (BOOL)prefersStatusBarHidden +{ + return YES; +} + +- (IBAction)back { + [self.navigationController popViewControllerAnimated:YES]; +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJWebViewViewController.xib b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJWebViewViewController.xib new file mode 100644 index 0000000..dcc206d --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Classes/Second/MJWebViewViewController.xib @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/AppIcon.appiconset/AppIcon@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/AppIcon.appiconset/AppIcon@2x.png new file mode 100644 index 0000000..0d9e710 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/AppIcon.appiconset/AppIcon@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..7da9604 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,74 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "AppIcon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0001.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0001.imageset/Contents.json new file mode 100644 index 0000000..a358f4a --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0001.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__0001@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0001.imageset/dropdown_anim__0001@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0001.imageset/dropdown_anim__0001@2x.png new file mode 100644 index 0000000..cc7a16d Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0001.imageset/dropdown_anim__0001@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00010.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00010.imageset/Contents.json new file mode 100644 index 0000000..da9d595 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00010.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00010@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00010.imageset/dropdown_anim__00010@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00010.imageset/dropdown_anim__00010@2x.png new file mode 100644 index 0000000..e7998ae Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00010.imageset/dropdown_anim__00010@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00011.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00011.imageset/Contents.json new file mode 100644 index 0000000..6113611 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00011.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00011@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00011.imageset/dropdown_anim__00011@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00011.imageset/dropdown_anim__00011@2x.png new file mode 100644 index 0000000..46c2481 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00011.imageset/dropdown_anim__00011@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00012.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00012.imageset/Contents.json new file mode 100644 index 0000000..795afa7 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00012.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00012@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00012.imageset/dropdown_anim__00012@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00012.imageset/dropdown_anim__00012@2x.png new file mode 100644 index 0000000..1f92793 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00012.imageset/dropdown_anim__00012@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00013.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00013.imageset/Contents.json new file mode 100644 index 0000000..429633d --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00013.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00013@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00013.imageset/dropdown_anim__00013@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00013.imageset/dropdown_anim__00013@2x.png new file mode 100644 index 0000000..fefb656 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00013.imageset/dropdown_anim__00013@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00014.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00014.imageset/Contents.json new file mode 100644 index 0000000..68595e3 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00014.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00014@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00014.imageset/dropdown_anim__00014@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00014.imageset/dropdown_anim__00014@2x.png new file mode 100644 index 0000000..a9424dd Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00014.imageset/dropdown_anim__00014@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00015.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00015.imageset/Contents.json new file mode 100644 index 0000000..6a5aac5 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00015.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00015@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00015.imageset/dropdown_anim__00015@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00015.imageset/dropdown_anim__00015@2x.png new file mode 100644 index 0000000..ffd8c83 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00015.imageset/dropdown_anim__00015@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00016.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00016.imageset/Contents.json new file mode 100644 index 0000000..7080482 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00016.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00016@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00016.imageset/dropdown_anim__00016@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00016.imageset/dropdown_anim__00016@2x.png new file mode 100644 index 0000000..58bfb12 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00016.imageset/dropdown_anim__00016@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00017.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00017.imageset/Contents.json new file mode 100644 index 0000000..63a4a2b --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00017.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00017@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00017.imageset/dropdown_anim__00017@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00017.imageset/dropdown_anim__00017@2x.png new file mode 100644 index 0000000..9f22f4a Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00017.imageset/dropdown_anim__00017@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00018.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00018.imageset/Contents.json new file mode 100644 index 0000000..96bca58 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00018.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00018@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00018.imageset/dropdown_anim__00018@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00018.imageset/dropdown_anim__00018@2x.png new file mode 100644 index 0000000..ff0af84 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00018.imageset/dropdown_anim__00018@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00019.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00019.imageset/Contents.json new file mode 100644 index 0000000..e829a45 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00019.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00019@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00019.imageset/dropdown_anim__00019@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00019.imageset/dropdown_anim__00019@2x.png new file mode 100644 index 0000000..5d45526 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00019.imageset/dropdown_anim__00019@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0002.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0002.imageset/Contents.json new file mode 100644 index 0000000..97b042a --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0002.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__0002@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0002.imageset/dropdown_anim__0002@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0002.imageset/dropdown_anim__0002@2x.png new file mode 100644 index 0000000..5d56e1d Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0002.imageset/dropdown_anim__0002@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00020.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00020.imageset/Contents.json new file mode 100644 index 0000000..170e751 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00020.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00020@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00020.imageset/dropdown_anim__00020@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00020.imageset/dropdown_anim__00020@2x.png new file mode 100644 index 0000000..c053d2e Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00020.imageset/dropdown_anim__00020@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00021.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00021.imageset/Contents.json new file mode 100644 index 0000000..e73094e --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00021.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00021@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00021.imageset/dropdown_anim__00021@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00021.imageset/dropdown_anim__00021@2x.png new file mode 100644 index 0000000..5e0ac30 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00021.imageset/dropdown_anim__00021@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00022.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00022.imageset/Contents.json new file mode 100644 index 0000000..f8e51b6 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00022.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00022@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00022.imageset/dropdown_anim__00022@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00022.imageset/dropdown_anim__00022@2x.png new file mode 100644 index 0000000..85fee2b Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00022.imageset/dropdown_anim__00022@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00023.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00023.imageset/Contents.json new file mode 100644 index 0000000..dc3b91b --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00023.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00023@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00023.imageset/dropdown_anim__00023@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00023.imageset/dropdown_anim__00023@2x.png new file mode 100644 index 0000000..6ed06da Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00023.imageset/dropdown_anim__00023@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00024.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00024.imageset/Contents.json new file mode 100644 index 0000000..b95cce5 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00024.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00024@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00024.imageset/dropdown_anim__00024@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00024.imageset/dropdown_anim__00024@2x.png new file mode 100644 index 0000000..06d8e80 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00024.imageset/dropdown_anim__00024@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00025.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00025.imageset/Contents.json new file mode 100644 index 0000000..8abb4de --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00025.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00025@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00025.imageset/dropdown_anim__00025@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00025.imageset/dropdown_anim__00025@2x.png new file mode 100644 index 0000000..a9fa4de Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00025.imageset/dropdown_anim__00025@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00026.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00026.imageset/Contents.json new file mode 100644 index 0000000..7767564 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00026.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00026@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00026.imageset/dropdown_anim__00026@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00026.imageset/dropdown_anim__00026@2x.png new file mode 100644 index 0000000..c6a629a Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00026.imageset/dropdown_anim__00026@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00027.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00027.imageset/Contents.json new file mode 100644 index 0000000..ed64c01 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00027.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00027@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00027.imageset/dropdown_anim__00027@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00027.imageset/dropdown_anim__00027@2x.png new file mode 100644 index 0000000..774fd66 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00027.imageset/dropdown_anim__00027@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00028.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00028.imageset/Contents.json new file mode 100644 index 0000000..0ca08ce --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00028.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00028@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00028.imageset/dropdown_anim__00028@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00028.imageset/dropdown_anim__00028@2x.png new file mode 100644 index 0000000..38b6652 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00028.imageset/dropdown_anim__00028@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00029.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00029.imageset/Contents.json new file mode 100644 index 0000000..abb0f27 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00029.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00029@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00029.imageset/dropdown_anim__00029@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00029.imageset/dropdown_anim__00029@2x.png new file mode 100644 index 0000000..91d1192 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00029.imageset/dropdown_anim__00029@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0003.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0003.imageset/Contents.json new file mode 100644 index 0000000..cce507c --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0003.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__0003@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0003.imageset/dropdown_anim__0003@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0003.imageset/dropdown_anim__0003@2x.png new file mode 100644 index 0000000..cdc8547 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0003.imageset/dropdown_anim__0003@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00030.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00030.imageset/Contents.json new file mode 100644 index 0000000..d721dd1 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00030.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00030@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00030.imageset/dropdown_anim__00030@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00030.imageset/dropdown_anim__00030@2x.png new file mode 100644 index 0000000..50300ef Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00030.imageset/dropdown_anim__00030@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00031.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00031.imageset/Contents.json new file mode 100644 index 0000000..fa0c613 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00031.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00031@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00031.imageset/dropdown_anim__00031@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00031.imageset/dropdown_anim__00031@2x.png new file mode 100644 index 0000000..0f8fdce Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00031.imageset/dropdown_anim__00031@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00032.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00032.imageset/Contents.json new file mode 100644 index 0000000..e540337 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00032.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00032@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00032.imageset/dropdown_anim__00032@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00032.imageset/dropdown_anim__00032@2x.png new file mode 100644 index 0000000..8b4397c Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00032.imageset/dropdown_anim__00032@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00033.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00033.imageset/Contents.json new file mode 100644 index 0000000..ece83e8 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00033.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00033@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00033.imageset/dropdown_anim__00033@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00033.imageset/dropdown_anim__00033@2x.png new file mode 100644 index 0000000..466d206 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00033.imageset/dropdown_anim__00033@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00034.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00034.imageset/Contents.json new file mode 100644 index 0000000..1d6da6a --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00034.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00034@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00034.imageset/dropdown_anim__00034@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00034.imageset/dropdown_anim__00034@2x.png new file mode 100644 index 0000000..e2a5413 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00034.imageset/dropdown_anim__00034@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00035.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00035.imageset/Contents.json new file mode 100644 index 0000000..f1f5677 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00035.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00035@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00035.imageset/dropdown_anim__00035@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00035.imageset/dropdown_anim__00035@2x.png new file mode 100644 index 0000000..00dcac2 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00035.imageset/dropdown_anim__00035@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00036.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00036.imageset/Contents.json new file mode 100644 index 0000000..f893fbf --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00036.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00036@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00036.imageset/dropdown_anim__00036@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00036.imageset/dropdown_anim__00036@2x.png new file mode 100644 index 0000000..826a1c1 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00036.imageset/dropdown_anim__00036@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00037.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00037.imageset/Contents.json new file mode 100644 index 0000000..18c8588 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00037.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00037@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00037.imageset/dropdown_anim__00037@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00037.imageset/dropdown_anim__00037@2x.png new file mode 100644 index 0000000..b5c50c6 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00037.imageset/dropdown_anim__00037@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00038.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00038.imageset/Contents.json new file mode 100644 index 0000000..9653de4 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00038.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00038@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00038.imageset/dropdown_anim__00038@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00038.imageset/dropdown_anim__00038@2x.png new file mode 100644 index 0000000..b5c50c6 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00038.imageset/dropdown_anim__00038@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00039.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00039.imageset/Contents.json new file mode 100644 index 0000000..48fd8ee --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00039.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00039@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00039.imageset/dropdown_anim__00039@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00039.imageset/dropdown_anim__00039@2x.png new file mode 100644 index 0000000..b5c50c6 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00039.imageset/dropdown_anim__00039@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0004.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0004.imageset/Contents.json new file mode 100644 index 0000000..a7098c3 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0004.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__0004@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0004.imageset/dropdown_anim__0004@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0004.imageset/dropdown_anim__0004@2x.png new file mode 100644 index 0000000..f4531fe Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0004.imageset/dropdown_anim__0004@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00040.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00040.imageset/Contents.json new file mode 100644 index 0000000..e7397fa --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00040.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00040@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00040.imageset/dropdown_anim__00040@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00040.imageset/dropdown_anim__00040@2x.png new file mode 100644 index 0000000..b8d97b5 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00040.imageset/dropdown_anim__00040@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00041.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00041.imageset/Contents.json new file mode 100644 index 0000000..0155974 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00041.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00041@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00041.imageset/dropdown_anim__00041@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00041.imageset/dropdown_anim__00041@2x.png new file mode 100644 index 0000000..b8d97b5 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00041.imageset/dropdown_anim__00041@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00042.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00042.imageset/Contents.json new file mode 100644 index 0000000..ba16961 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00042.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00042@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00042.imageset/dropdown_anim__00042@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00042.imageset/dropdown_anim__00042@2x.png new file mode 100644 index 0000000..b8d97b5 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00042.imageset/dropdown_anim__00042@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00043.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00043.imageset/Contents.json new file mode 100644 index 0000000..fed9512 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00043.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00043@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00043.imageset/dropdown_anim__00043@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00043.imageset/dropdown_anim__00043@2x.png new file mode 100644 index 0000000..04d987a Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00043.imageset/dropdown_anim__00043@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00044.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00044.imageset/Contents.json new file mode 100644 index 0000000..17d4acb --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00044.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00044@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00044.imageset/dropdown_anim__00044@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00044.imageset/dropdown_anim__00044@2x.png new file mode 100644 index 0000000..04d987a Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00044.imageset/dropdown_anim__00044@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00045.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00045.imageset/Contents.json new file mode 100644 index 0000000..3c2a4c2 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00045.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00045@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00045.imageset/dropdown_anim__00045@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00045.imageset/dropdown_anim__00045@2x.png new file mode 100644 index 0000000..29358c8 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00045.imageset/dropdown_anim__00045@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00046.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00046.imageset/Contents.json new file mode 100644 index 0000000..fed97bd --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00046.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00046@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00046.imageset/dropdown_anim__00046@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00046.imageset/dropdown_anim__00046@2x.png new file mode 100644 index 0000000..fa7ee74 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00046.imageset/dropdown_anim__00046@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00047.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00047.imageset/Contents.json new file mode 100644 index 0000000..a91f223 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00047.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00047@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00047.imageset/dropdown_anim__00047@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00047.imageset/dropdown_anim__00047@2x.png new file mode 100644 index 0000000..c9f99c6 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00047.imageset/dropdown_anim__00047@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00048.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00048.imageset/Contents.json new file mode 100644 index 0000000..254ac16 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00048.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00048@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00048.imageset/dropdown_anim__00048@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00048.imageset/dropdown_anim__00048@2x.png new file mode 100644 index 0000000..90863dc Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00048.imageset/dropdown_anim__00048@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00049.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00049.imageset/Contents.json new file mode 100644 index 0000000..4fe45f5 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00049.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00049@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00049.imageset/dropdown_anim__00049@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00049.imageset/dropdown_anim__00049@2x.png new file mode 100644 index 0000000..c20b2cd Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00049.imageset/dropdown_anim__00049@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0005.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0005.imageset/Contents.json new file mode 100644 index 0000000..609a0e1 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0005.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__0005@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0005.imageset/dropdown_anim__0005@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0005.imageset/dropdown_anim__0005@2x.png new file mode 100644 index 0000000..a456aa5 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0005.imageset/dropdown_anim__0005@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00050.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00050.imageset/Contents.json new file mode 100644 index 0000000..97fbe54 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00050.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00050@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00050.imageset/dropdown_anim__00050@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00050.imageset/dropdown_anim__00050@2x.png new file mode 100644 index 0000000..809004f Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00050.imageset/dropdown_anim__00050@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00051.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00051.imageset/Contents.json new file mode 100644 index 0000000..2e40007 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00051.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00051@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00051.imageset/dropdown_anim__00051@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00051.imageset/dropdown_anim__00051@2x.png new file mode 100644 index 0000000..7dade10 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00051.imageset/dropdown_anim__00051@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00052.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00052.imageset/Contents.json new file mode 100644 index 0000000..47b54ed --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00052.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00052@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00052.imageset/dropdown_anim__00052@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00052.imageset/dropdown_anim__00052@2x.png new file mode 100644 index 0000000..7f04981 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00052.imageset/dropdown_anim__00052@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00053.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00053.imageset/Contents.json new file mode 100644 index 0000000..a509220 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00053.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00053@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00053.imageset/dropdown_anim__00053@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00053.imageset/dropdown_anim__00053@2x.png new file mode 100644 index 0000000..790b6b4 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00053.imageset/dropdown_anim__00053@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00054.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00054.imageset/Contents.json new file mode 100644 index 0000000..4173519 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00054.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00054@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00054.imageset/dropdown_anim__00054@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00054.imageset/dropdown_anim__00054@2x.png new file mode 100644 index 0000000..5a95b8a Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00054.imageset/dropdown_anim__00054@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00055.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00055.imageset/Contents.json new file mode 100644 index 0000000..37ceecf --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00055.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00055@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00055.imageset/dropdown_anim__00055@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00055.imageset/dropdown_anim__00055@2x.png new file mode 100644 index 0000000..8a6d835 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00055.imageset/dropdown_anim__00055@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00056.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00056.imageset/Contents.json new file mode 100644 index 0000000..6c84375 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00056.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00056@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00056.imageset/dropdown_anim__00056@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00056.imageset/dropdown_anim__00056@2x.png new file mode 100644 index 0000000..0ece396 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00056.imageset/dropdown_anim__00056@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00057.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00057.imageset/Contents.json new file mode 100644 index 0000000..c17a0b9 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00057.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00057@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00057.imageset/dropdown_anim__00057@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00057.imageset/dropdown_anim__00057@2x.png new file mode 100644 index 0000000..892da58 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00057.imageset/dropdown_anim__00057@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00058.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00058.imageset/Contents.json new file mode 100644 index 0000000..19fe4a2 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00058.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00058@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00058.imageset/dropdown_anim__00058@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00058.imageset/dropdown_anim__00058@2x.png new file mode 100644 index 0000000..46a0f17 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00058.imageset/dropdown_anim__00058@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00059.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00059.imageset/Contents.json new file mode 100644 index 0000000..74d9ccf --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00059.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00059@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00059.imageset/dropdown_anim__00059@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00059.imageset/dropdown_anim__00059@2x.png new file mode 100644 index 0000000..a392880 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00059.imageset/dropdown_anim__00059@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0006.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0006.imageset/Contents.json new file mode 100644 index 0000000..ccea3fa --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0006.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__0006@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0006.imageset/dropdown_anim__0006@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0006.imageset/dropdown_anim__0006@2x.png new file mode 100644 index 0000000..c87e23c Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0006.imageset/dropdown_anim__0006@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00060.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00060.imageset/Contents.json new file mode 100644 index 0000000..a5d6718 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00060.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__00060@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00060.imageset/dropdown_anim__00060@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00060.imageset/dropdown_anim__00060@2x.png new file mode 100644 index 0000000..f0f7741 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__00060.imageset/dropdown_anim__00060@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0007.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0007.imageset/Contents.json new file mode 100644 index 0000000..09ba703 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0007.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__0007@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0007.imageset/dropdown_anim__0007@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0007.imageset/dropdown_anim__0007@2x.png new file mode 100644 index 0000000..e92db0b Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0007.imageset/dropdown_anim__0007@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0008.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0008.imageset/Contents.json new file mode 100644 index 0000000..e1147ba --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0008.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__0008@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0008.imageset/dropdown_anim__0008@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0008.imageset/dropdown_anim__0008@2x.png new file mode 100644 index 0000000..e990743 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0008.imageset/dropdown_anim__0008@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0009.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0009.imageset/Contents.json new file mode 100644 index 0000000..e537e65 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0009.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_anim__0009@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0009.imageset/dropdown_anim__0009@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0009.imageset/dropdown_anim__0009@2x.png new file mode 100644 index 0000000..b23d65d Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_anim__0009.imageset/dropdown_anim__0009@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_01.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_01.imageset/Contents.json new file mode 100644 index 0000000..fa5051b --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_01.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_loading_01@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_01.imageset/dropdown_loading_01@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_01.imageset/dropdown_loading_01@2x.png new file mode 100644 index 0000000..43644ae Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_01.imageset/dropdown_loading_01@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_02.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_02.imageset/Contents.json new file mode 100644 index 0000000..e14a6ab --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_02.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_loading_02@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_02.imageset/dropdown_loading_02@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_02.imageset/dropdown_loading_02@2x.png new file mode 100644 index 0000000..e81616a Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_02.imageset/dropdown_loading_02@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_03.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_03.imageset/Contents.json new file mode 100644 index 0000000..51865a2 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_03.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "dropdown_loading_03@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_03.imageset/dropdown_loading_03@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_03.imageset/dropdown_loading_03@2x.png new file mode 100644 index 0000000..65cd34f Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/DianPing/dropdown_loading_03.imageset/dropdown_loading_03@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/MJRefresh.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/MJRefresh.imageset/Contents.json new file mode 100644 index 0000000..6c276f7 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/MJRefresh.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "MJRefresh.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/MJRefresh.imageset/MJRefresh.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/MJRefresh.imageset/MJRefresh.png new file mode 100644 index 0000000..6cb4ebb Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/MJRefresh.imageset/MJRefresh.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar.imageset/Contents.json new file mode 100644 index 0000000..2430eaa --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "NavBar@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar.imageset/NavBar@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar.imageset/NavBar@2x.png new file mode 100644 index 0000000..c3a3e04 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar.imageset/NavBar@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar64.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar64.imageset/Contents.json new file mode 100644 index 0000000..e53dab6 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar64.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x", + "filename" : "NavBar64@2x.png" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar64.imageset/NavBar64@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar64.imageset/NavBar64@2x.png new file mode 100644 index 0000000..0a5f658 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/NavBar64.imageset/NavBar64@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/logo.imageset/Contents.json b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/logo.imageset/Contents.json new file mode 100644 index 0000000..5126757 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/logo.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logo.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "logo@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/logo.imageset/logo.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/logo.imageset/logo.png new file mode 100644 index 0000000..e935e22 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/logo.imageset/logo.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/logo.imageset/logo@2x.png b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/logo.imageset/logo@2x.png new file mode 100644 index 0000000..73273e1 Binary files /dev/null and b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Images.xcassets/logo.imageset/logo@2x.png differ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/Info.plist b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Info.plist new file mode 100644 index 0000000..50f6078 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/Info.plist @@ -0,0 +1,52 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + MJRefresh + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/PrefixHeader.pch b/Carthage/Checkouts/MJRefresh/MJRefreshExample/PrefixHeader.pch new file mode 100644 index 0000000..37a8d43 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/PrefixHeader.pch @@ -0,0 +1,12 @@ +// +// PrefixHeader.pch +// MJRefreshExample +// +// Created by MJ Lee on 15/9/22. +// Copyright © 2015年 小码哥. All rights reserved. +// + +#ifndef PrefixHeader_pch +#define PrefixHeader_pch +#import "MJTempViewController.h" +#endif /* PrefixHeader_pch */ diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExample/main.m b/Carthage/Checkouts/MJRefresh/MJRefreshExample/main.m new file mode 100644 index 0000000..76ac6a2 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExample/main.m @@ -0,0 +1,16 @@ +// +// main.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExampleTests/Info.plist b/Carthage/Checkouts/MJRefresh/MJRefreshExampleTests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExampleTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/MJRefresh/MJRefreshExampleTests/MJRefreshExampleTests.m b/Carthage/Checkouts/MJRefresh/MJRefreshExampleTests/MJRefreshExampleTests.m new file mode 100644 index 0000000..47e3c3d --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/MJRefreshExampleTests/MJRefreshExampleTests.m @@ -0,0 +1,40 @@ +// +// MJRefreshExampleTests.m +// MJRefreshExampleTests +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 小码哥. All rights reserved. +// + +#import +#import + +@interface MJRefreshExampleTests : XCTestCase + +@end + +@implementation MJRefreshExampleTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + XCTAssert(YES, @"Pass"); +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/Carthage/Checkouts/MJRefresh/README.md b/Carthage/Checkouts/MJRefresh/README.md new file mode 100644 index 0000000..aa40057 --- /dev/null +++ b/Carthage/Checkouts/MJRefresh/README.md @@ -0,0 +1,362 @@ +![(logo)](http://images.cnitblog.com/blog2015/497279/201505/051004492043385.png) +## MJRefresh +* An easy way to use pull-to-refresh + +## Contents +* Getting Started + * [Features【Support what kinds of controls to refresh】](#Support what kinds of controls to refresh) + * [Installation【How to use MJRefresh】](#How to use MJRefresh) + * [Who's using【More than hundreds of Apps are using MJRefresh】](#>More than hundreds of Apps are using MJRefresh) + * [Classes【The Class Structure Chart of MJRefresh】](#The Class Structure Chart of MJRefresh) +* Comment API + * [MJRefreshComponent.h](#MJRefreshComponent.h) + * [MJRefreshHeader.h](#MJRefreshHeader.h) + * [MJRefreshFooter.h](#MJRefreshFooter.h) + * [MJRefreshAutoFooter.h](#MJRefreshAutoFooter.h) +* Examples + * [Reference](#Reference) + * [The drop-down refresh 01-Default](#The drop-down refresh 01-Default) + * [The drop-down refresh 02-Animation image](#The drop-down refresh 02-Animation image) + * [The drop-down refresh 03-Hide the time](#The drop-down refresh 03-Hide the time) + * [The drop-down refresh 04-Hide status and time](#The drop-down refresh 04-Hide status and time) + * [The drop-down refresh 05-DIY title](#The drop-down refresh 05-DIY title) + * [The drop-down refresh 06-DIY the control of refresh](#The drop-down refresh 06-DIY the control of refresh) + * [The pull to refresh 01-Default](#The pull to refresh 01-Default) + * [The pull to refresh 02-Animation image](#The pull to refresh 02-Animation image) + * [The pull to refresh 03-Hide the title of refresh status](#The pull to refresh 03-Hide the title of refresh status) + * [The pull to refresh 04-All loaded](#The pull to refresh 04-All loaded) + * [The pull to refresh 05-DIY title](#The pull to refresh 05-DIY title) + * [The pull to refresh 06-Hidden After loaded](#The pull to refresh 06-Hidden After loaded) + * [The pull to refresh 07-Automatic back of the pull01](#上The pull to refresh 07-Automatic back of the pull01) + * [The pull to refresh 08-Automatic back of the pull02](#The pull to refresh 08-Automatic back of the pull02) + * [The pull to refresh 09-DIY the control of refresh(Automatic refresh)](#The pull to refresh 09-DIY the control of refresh(Automatic refresh)) + * [The pull to refresh 10-DIY the control of refresh(Automatic back)](#The pull to refresh 10-DIY the control of refresh(Automatic back)) + * [UICollectionView01-The pull and drop-down refresh](#UICollectionView01-The pull and drop-down refresh) + * [UIWebView01-The drop-down refresh](#UIWebView01-The drop-down refresh) +* [Hope](#Hope) + +## Support what kinds of controls to refresh +* `UIScrollView`、`UITableView`、`UICollectionView`、`UIWebView` + +## How to use MJRefresh +* Installation with CocoaPods:`pod 'MJRefresh'` +* Manual import: + * Drag All files in the `MJRefresh` folder to project + * Import the main file:`#import "MJRefresh.h"` + +```objc +Base Custom +MJRefresh.bundle MJRefresh.h +MJRefreshConst.h MJRefreshConst.m +UIScrollView+MJExtension.h UIScrollView+MJExtension.m +UIScrollView+MJRefresh.h UIScrollView+MJRefresh.m +UIView+MJExtension.h UIView+MJExtension.m +``` + +## More than hundreds of Apps are using MJRefresh + +* More information of App can focus on:[M了个J-博客园](http://www.cnblogs.com/mjios/p/4409853.html) + +## The Class Structure Chart of MJRefresh +![](http://images0.cnblogs.com/blog2015/497279/201506/132232456139177.png) +- `The class of red text` in the chart:You can use them directly + - The drop-down refresh control types + - Normal:`MJRefreshNormalHeader` + - Gif:`MJRefreshGifHeader` + - The pull to refresh control types + - Auto refresh + - Normal:`MJRefreshAutoNormalFooter` + - Gif:`MJRefreshAutoGifFooter` + - Auto Back + - Normal:`MJRefreshBackNormalFooter` + - Gif:`MJRefreshBackGifFooter` +- `The class of non-red text` in the chart:For inheritance,to use DIY the control of refresh +- About how to DIY the control of refresh,You can refer the Class in below Chart
+ + +## MJRefreshComponent.h +```objc +/** The Base Class of refresh control */ +@interface MJRefreshComponent : UIView +#pragma mark - Control the state of Refresh + +/** BeginRefreshing */ +- (void)beginRefreshing; +/** EndRefreshing */ +- (void)endRefreshing; +/** IsRefreshing */ +- (BOOL)isRefreshing; + +#pragma mark - Other +/** According to the drag ratio to change alpha automatically */ +@property (assign, nonatomic, getter=isAutomaticallyChangeAlpha) BOOL automaticallyChangeAlpha; +@end +``` + +## MJRefreshHeader.h +```objc +@interface MJRefreshHeader : MJRefreshComponent +/** Creat header */ ++ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; +/** Creat header */ ++ (instancetype)headerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** This key is used to storage the time that the last time of drown-down successfully */ +@property (copy, nonatomic) NSString *lastUpdatedTimeKey; +/** The last time of drown-down successfully */ +@property (strong, nonatomic, readonly) NSDate *lastUpdatedTime; + +/** Ignored scrollView contentInset top */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop; +@end +``` + +## MJRefreshFooter.h +```objc +@interface MJRefreshFooter : MJRefreshComponent +/** Creat footer */ ++ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; +/** Creat footer */ ++ (instancetype)footerWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +/** NoticeNoMoreData */ +- (void)noticeNoMoreData; +/** ResetNoMoreData(Clear the status of NoMoreData ) */ +- (void)resetNoMoreData; + +/** Ignored scrollView contentInset bottom */ +@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom; + +/** Automaticlly show or hidden by the count of data(Show-have data,Hidden- no data) */ +@property (assign, nonatomic) BOOL automaticallyHidden; +@end +``` + +## MJRefreshAutoFooter.h +```objc +@interface MJRefreshAutoFooter : MJRefreshFooter +/** Is Automatically Refresh(Default is Yes) */ +@property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; + +/** When there is much at the bottom of the control is automatically refresh(Default is 1.0,Is at the bottom of the control appears in full, will refresh automatically) */ +@property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent; +@end +``` + +## Reference +```objc +* Due to there are more functions of this framework,Don't write specific text describe its usage +* You can directly reference examples MJTableViewController、MJCollectionViewController、MJWebViewController,More intuitive and fast. +``` + + +## The drop-down refresh 01-Default + +```objc +self.tableView.header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; +或 +// Set the callback(Once you enter the refresh status,then call the action of target,that is call [self loadNewData]) +self.tableView.header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; + +// Enter the refresh status immediately +[self.tableView.header beginRefreshing]; +``` +![(下拉刷新01-普通)](http://images0.cnblogs.com/blog2015/497279/201506/141204343486151.gif) + +## The drop-down refresh 02-Animation image +```objc +// Set the callback(一Once you enter the refresh status,then call the action of target,that is call [self loadNewData]) +MJRefreshGifHeader *header = [MJRefreshGifHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; +// Set the ordinary state of animated images +[header setImages:idleImages forState:MJRefreshStateIdle]; +// Set the pulling state of animated images(Enter the status of refreshing as soon as loosen) +[header setImages:pullingImages forState:MJRefreshStatePulling]; +// Set the refreshing state of animated images +[header setImages:refreshingImages forState:MJRefreshStateRefreshing]; +// Set header +self.tableView.mj_header = header; +``` +![(下拉刷新02-动画图片)](http://images0.cnblogs.com/blog2015/497279/201506/141204402238389.gif) + +## The drop-down refresh 03-Hide the time +```objc +// Hide the time +header.lastUpdatedTimeLabel.hidden = YES; +``` +![(下拉刷新03-隐藏时间)](http://images0.cnblogs.com/blog2015/497279/201506/141204456132944.gif) + +## The drop-down refresh 04-Hide status and time +```objc +// Hide the time +header.lastUpdatedTimeLabel.hidden = YES; + +// Hide the status +header.stateLabel.hidden = YES; +``` +![(下拉刷新04-隐藏状态和时间0)](http://images0.cnblogs.com/blog2015/497279/201506/141204508639539.gif) + +## The drop-down refresh 05-DIY title +```objc +// Set title +[header setTitle:@"Pull down to refresh" forState:MJRefreshStateIdle]; +[header setTitle:@"Release to refresh" forState:MJRefreshStatePulling]; +[header setTitle:@"Loading ..." forState:MJRefreshStateRefreshing]; + +// Set font +header.stateLabel.font = [UIFont systemFontOfSize:15]; +header.lastUpdatedTimeLabel.font = [UIFont systemFontOfSize:14]; + +// Set textColor +header.stateLabel.textColor = [UIColor redColor]; +header.lastUpdatedTimeLabel.textColor = [UIColor blueColor]; +``` +![(下拉刷新05-自定义文字)](http://images0.cnblogs.com/blog2015/497279/201506/141204563633593.gif) + +## The drop-down refresh 06-DIY the control of refresh +```objc +self.tableView.mj_header = [MJDIYHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; +// Implementation reference to MJDIYHeader.h和MJDIYHeader.m +``` +![(下拉刷新06-自定义刷新控件)](http://images0.cnblogs.com/blog2015/497279/201506/141205019261159.gif) + +## The pull to refresh 01-Default +```objc +self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; +或 +// Set the callback(Once you enter the refresh status,then call the action of target,that is call [self loadMoreData]) +self.tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +``` +![(上拉刷新01-默认)](http://images0.cnblogs.com/blog2015/497279/201506/141205090047696.gif) + +## The pull to refresh 02-Animation image +```objc +// Set the callback(Once you enter the refresh status,then call the action of target,that is call [self loadMoreData]) +MJRefreshAutoGifFooter *footer = [MJRefreshAutoGifFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; + +// Set the refresh image +[footer setImages:refreshingImages forState:MJRefreshStateRefreshing]; + +// Set footer +self.tableView.mj_footer = footer; +``` +![(上拉刷新02-动画图片)](http://images0.cnblogs.com/blog2015/497279/201506/141205141445793.gif) + +## The pull to refresh 03-Hide the title of refresh status +```objc +// Hide the title of refresh status +footer.refreshingTitleHidden = YES; +// If does have not above method,then use footer.stateLabel.hidden = YES; +``` +![(上拉刷新03-隐藏刷新状态的文字)](http://images0.cnblogs.com/blog2015/497279/201506/141205200985774.gif) + +## The pull to refresh 04-All loaded +```objc +//Become the status of NoMoreData +[footer noticeNoMoreData]; +``` +![(上拉刷新04-全部加载完毕)](http://images0.cnblogs.com/blog2015/497279/201506/141205248634686.gif) + +## The pull to refresh 05-DIY title +```objc +// Set title +[footer setTitle:@"Click or drag up to refresh" forState:MJRefreshStateIdle]; +[footer setTitle:@"Loading more ..." forState:MJRefreshStateRefreshing]; +[footer setTitle:@"No more data" forState:MJRefreshStateNoMoreData]; + +// Set font +footer.stateLabel.font = [UIFont systemFontOfSize:17]; + +// Set textColor +footer.stateLabel.textColor = [UIColor blueColor]; +``` +![(上拉刷新05-自定义文字)](http://images0.cnblogs.com/blog2015/497279/201506/141205295511153.gif) + +## The pull to refresh 06-Hidden After loaded +```objc +//Hidden current control of the pull to refresh +self.tableView.mj_footer.hidden = YES; +``` +![(上拉刷新06-加载后隐藏)](http://images0.cnblogs.com/blog2015/497279/201506/141205343481821.gif) + +## The pull to refresh 07-Automatic back of the pull01 +```objc +self.tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +``` +![(上拉刷新07-自动回弹的上拉01)](http://images0.cnblogs.com/blog2015/497279/201506/141205392239231.gif) + +## The pull to refresh 08-Automatic back of the pull02 +```objc +MJRefreshBackGifFooter *footer = [MJRefreshBackGifFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; + +// Set the normal state of the animated image +[footer setImages:idleImages forState:MJRefreshStateIdle]; +// Set the pulling state of animated images(Enter the status of refreshing as soon as loosen) +[footer setImages:pullingImages forState:MJRefreshStatePulling]; +// Set the refreshing state of animated images +[footer setImages:refreshingImages forState:MJRefreshStateRefreshing]; + +// Set footer +self.tableView.mj_footer = footer; +``` +![(上拉刷新07-自动回弹的上拉02)](http://images0.cnblogs.com/blog2015/497279/201506/141205441443628.gif) + +## The pull to refresh 09-DIY the control of refresh(Automatic refresh) +```objc +self.tableView.mj_footer = [MJDIYAutoFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +// Implementation reference to MJDIYAutoFooter.h和MJDIYAutoFooter.m +``` +![(上拉刷新09-自定义刷新控件(自动刷新))](http://images0.cnblogs.com/blog2015/497279/201506/141205500195866.gif) + +## The pull to refresh 10-DIY the control of refresh(Automatic back) +```objc +self.tableView.mj_footer = [MJDIYBackFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; +// Implementation reference to MJDIYBackFooter.h和MJDIYBackFooter.m +``` +![(上拉刷新10-自定义刷新控件(自动回弹))](http://images0.cnblogs.com/blog2015/497279/201506/141205560666819.gif) + +## UICollectionView01-The pull and drop-down refresh +```objc +// The drop-down refresh +self.collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; + +// The pull to refresh +self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; +``` +![(UICollectionView01-上下拉刷新)](http://images0.cnblogs.com/blog2015/497279/201506/141206021603758.gif) + +## UIWebView01-The drop-down refresh +```objc +//Add the control of The drop-down refresh +self.webView.scrollView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ + //Call this Block When enter the refresh status automatically +}]; +``` +![(UICollectionView01-上下拉刷新)](http://images0.cnblogs.com/blog2015/497279/201506/141206080514524.gif) + +## Remind +* ARC +* iOS>=6.0 +* iPhone \ iPad screen anyway + +## Hope +* If you find bug when used,Hope you can Issues me,Thank you or try to download the latest code of this framework to see the BUG has been fixed or not) +* If you find the function is not enough when used,Hope you can Issues me,I very much to add more useful function to this framework ,Thank you ! +* If you want to contribute code for MJRefresh,please Pull Requests me +* If you use MJRefresh in your develop app,Hope you can go to[CocoaControls](https://www.cocoacontrols.com/controls/mjrefresh)to add the iTunes path + of you app,I Will install your app,and according to the usage of many app,to be a better design and improve to MJRefresh,Thank you ! + * StepO1(WeChat is just an Example,Explore“Your app name itunes”) +![(step01)](http://ww4.sinaimg.cn/mw1024/800cdf9ctw1eq0viiv5rsj20sm0ea41t.jpg) + * StepO2 +![(step02)](http://ww2.sinaimg.cn/mw1024/800cdf9ctw1eq0vilejxlj20tu0me7a0.jpg) + * StepO3 +![(step03)](http://ww1.sinaimg.cn/mw1024/800cdf9ctw1eq0viocpo5j20wc0dc0un.jpg) + * StepO4 +![(step04)](http://ww3.sinaimg.cn/mw1024/800cdf9ctw1eq0vir137xj20si0gewgu.jpg) diff --git a/Carthage/Checkouts/NetworkEye/.gitignore b/Carthage/Checkouts/NetworkEye/.gitignore new file mode 100644 index 0000000..1de2633 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/NetworkEye/Cartfile b/Carthage/Checkouts/NetworkEye/Cartfile new file mode 100644 index 0000000..2ad6ddc --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Cartfile @@ -0,0 +1 @@ +github "zixun/AppSwizzle" >= 1.1.1 \ No newline at end of file diff --git a/Carthage/Checkouts/NetworkEye/Cartfile.resolved b/Carthage/Checkouts/NetworkEye/Cartfile.resolved new file mode 100644 index 0000000..0633dfa --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Cartfile.resolved @@ -0,0 +1 @@ +github "zixun/AppSwizzle" "1.1.1" diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/.gitignore b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/.gitignore new file mode 100644 index 0000000..1de2633 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle.podspec b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle.podspec new file mode 100644 index 0000000..3c9cd6e --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle.podspec @@ -0,0 +1,33 @@ +# +# Be sure to run `pod lib lint AppSwizzle.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'AppSwizzle' + s.version = '1.1.1' + s.summary = 'lightweight and flexible method swizzling wrapped by swift.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +Lightweight and flexible method swizzling wrapped by swift. enjoy it! + DESC + + s.homepage = 'https://github.com/zixun/AppSwizzle' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { '陈奕龙' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/AppSwizzle.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'AppSwizzle/Classes/**/*' +end diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Assets/.gitkeep b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/.gitkeep b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/AppSwizzle.swift b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/AppSwizzle.swift new file mode 100644 index 0000000..5312665 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/AppSwizzle/Classes/AppSwizzle.swift @@ -0,0 +1,99 @@ +// +// AppSwizzle.swift +// Pods +// +// Created by zixun on 2016/11/27. +// +// + +import Foundation + +import ObjectiveC + +public enum SwizzleResult { + case Succeed + case OriginMethodNotFound + case AlternateMethodNotFound +} + +public extension NSObject { + + public class func swizzleInstanceMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: self.classForCoder(), + isClassMethod: false) + } + + public class func swizzleClassMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: self.classForCoder(), + isClassMethod: true) + } + + + public class func swizzleInstanceMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector, + inAlterClass alterClass: AnyClass) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: alterClass, + isClassMethod: false) + } + + public class func swizzleClassMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector, + inAlterClass alterClass: AnyClass) -> SwizzleResult { + return self.swizzleMethod(origSelector: origSelector, + toAlterSelector: alterSelector, + inAlterClass: alterClass, + isClassMethod: true) + } + + + private class func swizzleMethod(origSelector: Selector, + toAlterSelector alterSelector: Selector!, + inAlterClass alterClass: AnyClass!, + isClassMethod:Bool) -> SwizzleResult { + + var alterClass = alterClass + var origClass: AnyClass = self.classForCoder() + if isClassMethod { + alterClass = object_getClass(alterClass) + origClass = object_getClass(self.classForCoder()) + } + + return SwizzleMethod(origClass: origClass, origSelector: origSelector, toAlterSelector: alterSelector, inAlterClass: alterClass) + } +} + + +private func SwizzleMethod(origClass:AnyClass!,origSelector: Selector,toAlterSelector alterSelector: Selector!,inAlterClass alterClass: AnyClass!) -> SwizzleResult{ + + guard let origMethod: Method = class_getInstanceMethod(origClass, origSelector) else { + return SwizzleResult.OriginMethodNotFound + } + + guard let altMethod: Method = class_getInstanceMethod(alterClass, alterSelector) else { + return SwizzleResult.AlternateMethodNotFound + } + + + + let didadd = class_addMethod(origClass, + origSelector,method_getImplementation(origMethod), + method_getTypeEncoding(origMethod)) + + + let didadd2 = class_addMethod(alterClass, + alterSelector,method_getImplementation(altMethod), + method_getTypeEncoding(altMethod)) + + method_exchangeImplementations(origMethod, altMethod) + + return SwizzleResult.Succeed + +} diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.pbxproj b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.pbxproj new file mode 100644 index 0000000..976270e --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.pbxproj @@ -0,0 +1,527 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 607FACEC1AFB9204008FA782 /* AppSwizzleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* AppSwizzleTests.swift */; }; + 9E24F9D91E7FB91A001AD0D7 /* AppSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24F9D71E7FB91A001AD0D7 /* AppSwizzle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24F9E01E7FB92D001AD0D7 /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = 9E24F9DE1E7FB92D001AD0D7 /* .gitkeep */; }; + 9E24F9E11E7FB92D001AD0D7 /* AppSwizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24F9DF1E7FB92D001AD0D7 /* AppSwizzle.swift */; }; + 9EFFB71B24C66DC6A7F031F7 /* Pods_AppSwizzle_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 491CD07646A3DE1A3E69F9D1 /* Pods_AppSwizzle_Tests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2E3BA46813095DB970DC7076 /* Pods-AppSwizzle_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppSwizzle_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests.release.xcconfig"; sourceTree = ""; }; + 491CD07646A3DE1A3E69F9D1 /* Pods_AppSwizzle_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AppSwizzle_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACE51AFB9204008FA782 /* AppSwizzle_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AppSwizzle_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* AppSwizzleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSwizzleTests.swift; sourceTree = ""; }; + 89AFF071BC9E704AA1C37D55 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 9E24F9D51E7FB91A001AD0D7 /* AppSwizzle.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AppSwizzle.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24F9D71E7FB91A001AD0D7 /* AppSwizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppSwizzle.h; sourceTree = ""; }; + 9E24F9D81E7FB91A001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24F9DE1E7FB92D001AD0D7 /* .gitkeep */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + 9E24F9DF1E7FB92D001AD0D7 /* AppSwizzle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppSwizzle.swift; sourceTree = ""; }; + E26F9D2C0E0879A1F36DBA49 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + E2A536F5AEFAB64066837735 /* AppSwizzle.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = AppSwizzle.podspec; path = ../AppSwizzle.podspec; sourceTree = ""; }; + EF9F0C8A4C454C95207FD5A2 /* Pods-AppSwizzle_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppSwizzle_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EFFB71B24C66DC6A7F031F7 /* Pods_AppSwizzle_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9D11E7FB91A001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 148CFF5A86E94370A2FFA6EB /* Frameworks */ = { + isa = PBXGroup; + children = ( + 491CD07646A3DE1A3E69F9D1 /* Pods_AppSwizzle_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24F9D61E7FB91A001AD0D7 /* AppSwizzle */, + 607FACD11AFB9204008FA782 /* Products */, + 95CAC9C1BE74BBFAF93AD32F /* Pods */, + 148CFF5A86E94370A2FFA6EB /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACE51AFB9204008FA782 /* AppSwizzle_Tests.xctest */, + 9E24F9D51E7FB91A001AD0D7 /* AppSwizzle.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* AppSwizzleTests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + E2A536F5AEFAB64066837735 /* AppSwizzle.podspec */, + 89AFF071BC9E704AA1C37D55 /* README.md */, + E26F9D2C0E0879A1F36DBA49 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 95CAC9C1BE74BBFAF93AD32F /* Pods */ = { + isa = PBXGroup; + children = ( + EF9F0C8A4C454C95207FD5A2 /* Pods-AppSwizzle_Tests.debug.xcconfig */, + 2E3BA46813095DB970DC7076 /* Pods-AppSwizzle_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9E24F9D61E7FB91A001AD0D7 /* AppSwizzle */ = { + isa = PBXGroup; + children = ( + 9E24F9DD1E7FB92D001AD0D7 /* Classes */, + 9E24F9D71E7FB91A001AD0D7 /* AppSwizzle.h */, + 9E24F9D81E7FB91A001AD0D7 /* Info.plist */, + ); + path = AppSwizzle; + sourceTree = ""; + }; + 9E24F9DD1E7FB92D001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24F9DE1E7FB92D001AD0D7 /* .gitkeep */, + 9E24F9DF1E7FB92D001AD0D7 /* AppSwizzle.swift */, + ); + name = Classes; + path = ../../AppSwizzle/Classes; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24F9D21E7FB91A001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9D91E7FB91A001AD0D7 /* AppSwizzle.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACE41AFB9204008FA782 /* AppSwizzle_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppSwizzle_Tests" */; + buildPhases = ( + 7A1970CC11A178F2524BAA27 /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + C1AA5E9370E2274451F9FA64 /* [CP] Embed Pods Frameworks */, + F92510766834405DBE333382 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppSwizzle_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* AppSwizzle_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24F9D41E7FB91A001AD0D7 /* AppSwizzle */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24F9DC1E7FB91A001AD0D7 /* Build configuration list for PBXNativeTarget "AppSwizzle" */; + buildPhases = ( + 9E24F9D01E7FB91A001AD0D7 /* Sources */, + 9E24F9D11E7FB91A001AD0D7 /* Frameworks */, + 9E24F9D21E7FB91A001AD0D7 /* Headers */, + 9E24F9D31E7FB91A001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppSwizzle; + productName = AppSwizzle; + productReference = 9E24F9D51E7FB91A001AD0D7 /* AppSwizzle.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0800; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24F9D41E7FB91A001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AppSwizzle" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACE41AFB9204008FA782 /* AppSwizzle_Tests */, + 9E24F9D41E7FB91A001AD0D7 /* AppSwizzle */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9D31E7FB91A001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9E01E7FB92D001AD0D7 /* .gitkeep in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 7A1970CC11A178F2524BAA27 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + C1AA5E9370E2274451F9FA64 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F92510766834405DBE333382 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AppSwizzle_Tests/Pods-AppSwizzle_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* AppSwizzleTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9D01E7FB91A001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9E11E7FB92D001AD0D7 /* AppSwizzle.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EF9F0C8A4C454C95207FD5A2 /* Pods-AppSwizzle_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2E3BA46813095DB970DC7076 /* Pods-AppSwizzle_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24F9DA1E7FB91A001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AppSwizzle/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AppSwizzle; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24F9DB1E7FB91A001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AppSwizzle/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.AppSwizzle; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "AppSwizzle" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "AppSwizzle_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24F9DC1E7FB91A001AD0D7 /* Build configuration list for PBXNativeTarget "AppSwizzle" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24F9DA1E7FB91A001AD0D7 /* Debug */, + 9E24F9DB1E7FB91A001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..79e358c --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/xcshareddata/AppSwizzle.xcscmblueprint b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/xcshareddata/AppSwizzle.xcscmblueprint new file mode 100644 index 0000000..e32fd4c --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/project.xcworkspace/xcshareddata/AppSwizzle.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "0CB12C37-D96F-4E37-99A6-EA1B9BB695B0", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0" : "AppSwizzle\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "AppSwizzle", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/AppSwizzle.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/AppSwizzle.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "5C65E1A0DF07B186C275611DFCB6907F9BD8DAC0" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle-Example.xcscheme b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle-Example.xcscheme new file mode 100644 index 0000000..aae5e32 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle.xcscheme b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle.xcscheme new file mode 100644 index 0000000..233c1b3 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcodeproj/xcshareddata/xcschemes/AppSwizzle.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..bbcb77a --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/AppSwizzle.h b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/AppSwizzle.h new file mode 100644 index 0000000..12be6cf --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/AppSwizzle.h @@ -0,0 +1,19 @@ +// +// AppSwizzle.h +// AppSwizzle +// +// Created by zixun on 2017/3/20. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for AppSwizzle. +FOUNDATION_EXPORT double AppSwizzleVersionNumber; + +//! Project version string for AppSwizzle. +FOUNDATION_EXPORT const unsigned char AppSwizzleVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/Info.plist b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/AppSwizzle/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Podfile b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Podfile new file mode 100644 index 0000000..ce647a9 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Podfile @@ -0,0 +1,6 @@ +use_frameworks! +target 'AppSwizzle_Tests' do + pod 'AppSwizzle', :path => '../' + + +end diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Podfile.lock b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Podfile.lock new file mode 100644 index 0000000..709afd2 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - AppSwizzle (0.1.0) + +DEPENDENCIES: + - AppSwizzle (from `../`) + +EXTERNAL SOURCES: + AppSwizzle: + :path: "../" + +SPEC CHECKSUMS: + AppSwizzle: eddd38c6429de033e115f66862622723274926a0 + +PODFILE CHECKSUM: 939ed1355ec6a0adef5ae3f3b1e627821b2fc52a + +COCOAPODS: 1.1.1 diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Tests/AppSwizzleTests.swift b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Tests/AppSwizzleTests.swift new file mode 100644 index 0000000..d5aabc7 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Tests/AppSwizzleTests.swift @@ -0,0 +1,96 @@ +import UIKit +import XCTest +import AppSwizzle + +class AppSwizzleTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testSwizzleInstanceMethod() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethod) + let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleInstanceMethod) + AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) + + self.origSelector_testSwizzleInstanceMethod() + } + + func testSwizzleClassMethod() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethod) + let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleClassMethod) + AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter) + + AppSwizzleTests.origSelector_testSwizzleClassMethod() + } + + func testSwizzleInstanceMethodToAlterClass() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethodToAlterClass) + let alter = #selector(OtherClass.alterSelector_testSwizzleInstanceMethodToAlterClass) + AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) + self.origSelector_testSwizzleInstanceMethodToAlterClass() + } + + func testSwizzleClassMethodToAlterClass() { + let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethodToAlterClass) + let alter = #selector(OtherClass.alterSelector_testSwizzleClassMethodToAlterClass) + + AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) + + AppSwizzleTests.origSelector_testSwizzleClassMethodToAlterClass() + } + +} + +//MARK: testSwizzleInstanceMethod extension +extension AppSwizzleTests { + + func origSelector_testSwizzleInstanceMethod() { + XCTFail("Failed") + } + + func alterSelector_testSwizzleInstanceMethod() { + XCTAssert(true, "Pass") + } +} + +//MARK: testSwizzleClassMethod extension +extension AppSwizzleTests { + + class func origSelector_testSwizzleClassMethod() { + XCTFail("Failed") + } + + class func alterSelector_testSwizzleClassMethod() { + XCTAssert(true, "Pass") + } +} + +//MARK: testSwizzleInstanceMethodToAlterClass extension +extension AppSwizzleTests { + func origSelector_testSwizzleInstanceMethodToAlterClass() { + XCTFail("Failed") + } +} + +extension AppSwizzleTests { + class func origSelector_testSwizzleClassMethodToAlterClass() { + XCTFail("Failed") + } +} + + +class OtherClass: NSObject { + + func alterSelector_testSwizzleInstanceMethodToAlterClass() { + XCTAssert(true, "Pass") + } + + class func alterSelector_testSwizzleClassMethodToAlterClass() { + XCTAssert(true, "Pass") + } +} diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Tests/Info.plist b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/LICENSE b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/README.md b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/README.md new file mode 100644 index 0000000..9933d6d --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Carthage/Checkouts/AppSwizzle/README.md @@ -0,0 +1,72 @@ +# AppSwizzle + +[![Swift 3.0+](https://img.shields.io/badge/Swift-3.0%2B-orange.svg)](https://github.com/zixun/AppBaseKit) +[![Platform](https://img.shields.io/badge/Platform-iOS-lightgrey.svg)](https://github.com/zixun/AppBaseKit) +[![MIT](https://img.shields.io/badge/License-MIT-red.svg)](https://opensource.org/licenses/MIT) + +## Context +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly disply Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Example + +To run the example project, clone the repo, and run `pod install` from the Example directory first. + +## Requirements + +## Installation + +AppSwizzle is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "AppSwizzle" +``` +## Usage + +### Swizzle Instance Method + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethod) +let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleInstanceMethod) +AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) +``` + +### Swizzle Class Method + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethod) +let alter = #selector(AppSwizzleTests.alterSelector_testSwizzleClassMethod) +AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter) +``` + +### Swizzle Instance Method To Alter Class + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleInstanceMethodToAlterClass) +let alter = #selector(OtherClass.alterSelector_testSwizzleInstanceMethodToAlterClass) +AppSwizzleTests.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) +``` + +### Swizzle Class Method To Alter Class + +```swift +let orig = #selector(AppSwizzleTests.origSelector_testSwizzleClassMethodToAlterClass) +let alter = #selector(OtherClass.alterSelector_testSwizzleClassMethodToAlterClass) +AppSwizzleTests.swizzleClassMethod(origSelector: orig, toAlterSelector: alter, inAlterClass: OtherClass.classForCoder()) +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + +## License + +AppSwizzle is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/project.pbxproj b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/project.pbxproj new file mode 100644 index 0000000..89b6900 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/project.pbxproj @@ -0,0 +1,789 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 356CB9B31BBAB922655390FB /* Pods_NetworkEye_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 57B16F4A02777F243934C8BE /* Pods_NetworkEye_Example.framework */; }; + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 607FACEC1AFB9204008FA782 /* NetworkEyeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* NetworkEyeTests.swift */; }; + 9E24F9FE1E7FC46C001AD0D7 /* NetworkEye.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24F9FC1E7FC46C001AD0D7 /* NetworkEye.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FA081E7FC47E001AD0D7 /* EyeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA051E7FC47E001AD0D7 /* EyeProtocol.swift */; }; + 9E24FA091E7FC47E001AD0D7 /* NetworkEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA061E7FC47E001AD0D7 /* NetworkEye.swift */; }; + 9E24FA0A1E7FC47E001AD0D7 /* URLSession+Eye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FA071E7FC47E001AD0D7 /* URLSession+Eye.swift */; }; + 9E24FA0B1E7FC498001AD0D7 /* AppSwizzle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E24F9E21E7FBA0E001AD0D7 /* AppSwizzle.framework */; }; + 9E24FAF31E817F68001AD0D7 /* NetworkEye.swift.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 9E24FAF21E817F68001AD0D7 /* NetworkEye.swift.podspec */; }; + AAEA25B20B7FF6B23C52F683 /* Pods_NetworkEye_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F765BDD2DBAAE07BE313E70F /* Pods_NetworkEye_Tests.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = NetworkEye; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3DFD45BBB9133D6E496FDA52 /* Pods-NetworkEye_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NetworkEye_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NetworkEye_Tests/Pods-NetworkEye_Tests.debug.xcconfig"; sourceTree = ""; }; + 531A0E864ADD71D18060EE17 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + 57B16F4A02777F243934C8BE /* Pods_NetworkEye_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NetworkEye_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD01AFB9204008FA782 /* NetworkEye_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetworkEye_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 607FACE51AFB9204008FA782 /* NetworkEye_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NetworkEye_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* NetworkEyeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkEyeTests.swift; sourceTree = ""; }; + 8F3D12B008DCACFB88CF31AC /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 9E24F9CE1E7FB8D3001AD0D7 /* AppBaseKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppBaseKit.framework; path = ../Carthage/Build/iOS/AppBaseKit.framework; sourceTree = ""; }; + 9E24F9E21E7FBA0E001AD0D7 /* AppSwizzle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppSwizzle.framework; path = ../Carthage/Build/iOS/AppSwizzle.framework; sourceTree = ""; }; + 9E24F9FA1E7FC46C001AD0D7 /* NetworkEye.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NetworkEye.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24F9FC1E7FC46C001AD0D7 /* NetworkEye.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NetworkEye.h; sourceTree = ""; }; + 9E24F9FD1E7FC46C001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24FA051E7FC47E001AD0D7 /* EyeProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EyeProtocol.swift; sourceTree = ""; }; + 9E24FA061E7FC47E001AD0D7 /* NetworkEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkEye.swift; sourceTree = ""; }; + 9E24FA071E7FC47E001AD0D7 /* URLSession+Eye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "URLSession+Eye.swift"; sourceTree = ""; }; + 9E24FAF21E817F68001AD0D7 /* NetworkEye.swift.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = NetworkEye.swift.podspec; path = ../NetworkEye.swift.podspec; sourceTree = ""; }; + B44E08D635539770D577545B /* Pods-NetworkEye_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NetworkEye_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-NetworkEye_Tests/Pods-NetworkEye_Tests.release.xcconfig"; sourceTree = ""; }; + F50399156AE7AD82AA49298B /* Pods-NetworkEye_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NetworkEye_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-NetworkEye_Example/Pods-NetworkEye_Example.release.xcconfig"; sourceTree = ""; }; + F765BDD2DBAAE07BE313E70F /* Pods_NetworkEye_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NetworkEye_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F882F7C00A27B2F7998755D6 /* Pods-NetworkEye_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NetworkEye_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NetworkEye_Example/Pods-NetworkEye_Example.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 356CB9B31BBAB922655390FB /* Pods_NetworkEye_Example.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AAEA25B20B7FF6B23C52F683 /* Pods_NetworkEye_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9F61E7FC46C001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA0B1E7FC498001AD0D7 /* AppSwizzle.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for NetworkEye */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24F9FB1E7FC46C001AD0D7 /* NetworkEye */, + 607FACD11AFB9204008FA782 /* Products */, + 7D8DC146EB5F6A6B7CF10CBF /* Pods */, + CB5F7003653478F03A948BBC /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* NetworkEye_Example.app */, + 607FACE51AFB9204008FA782 /* NetworkEye_Tests.xctest */, + 9E24F9FA1E7FC46C001AD0D7 /* NetworkEye.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for NetworkEye */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 607FACD91AFB9204008FA782 /* Main.storyboard */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for NetworkEye"; + path = NetworkEye; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* NetworkEyeTests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + 9E24FAF21E817F68001AD0D7 /* NetworkEye.swift.podspec */, + 8F3D12B008DCACFB88CF31AC /* README.md */, + 531A0E864ADD71D18060EE17 /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 7D8DC146EB5F6A6B7CF10CBF /* Pods */ = { + isa = PBXGroup; + children = ( + F882F7C00A27B2F7998755D6 /* Pods-NetworkEye_Example.debug.xcconfig */, + F50399156AE7AD82AA49298B /* Pods-NetworkEye_Example.release.xcconfig */, + 3DFD45BBB9133D6E496FDA52 /* Pods-NetworkEye_Tests.debug.xcconfig */, + B44E08D635539770D577545B /* Pods-NetworkEye_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9E24F9FB1E7FC46C001AD0D7 /* NetworkEye */ = { + isa = PBXGroup; + children = ( + 9E24FA021E7FC47E001AD0D7 /* NetworkEye */, + 9E24F9FC1E7FC46C001AD0D7 /* NetworkEye.h */, + 9E24F9FD1E7FC46C001AD0D7 /* Info.plist */, + ); + path = NetworkEye; + sourceTree = ""; + }; + 9E24FA021E7FC47E001AD0D7 /* NetworkEye */ = { + isa = PBXGroup; + children = ( + 9E24FA031E7FC47E001AD0D7 /* Assets */, + 9E24FA041E7FC47E001AD0D7 /* Classes */, + ); + name = NetworkEye; + path = ../../NetworkEye; + sourceTree = ""; + }; + 9E24FA031E7FC47E001AD0D7 /* Assets */ = { + isa = PBXGroup; + children = ( + ); + path = Assets; + sourceTree = ""; + }; + 9E24FA041E7FC47E001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24FA051E7FC47E001AD0D7 /* EyeProtocol.swift */, + 9E24FA061E7FC47E001AD0D7 /* NetworkEye.swift */, + 9E24FA071E7FC47E001AD0D7 /* URLSession+Eye.swift */, + ); + path = Classes; + sourceTree = ""; + }; + CB5F7003653478F03A948BBC /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9E24F9E21E7FBA0E001AD0D7 /* AppSwizzle.framework */, + 9E24F9CE1E7FB8D3001AD0D7 /* AppBaseKit.framework */, + 57B16F4A02777F243934C8BE /* Pods_NetworkEye_Example.framework */, + F765BDD2DBAAE07BE313E70F /* Pods_NetworkEye_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24F9F71E7FC46C001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24F9FE1E7FC46C001AD0D7 /* NetworkEye.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* NetworkEye_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "NetworkEye_Example" */; + buildPhases = ( + 57524D40493C1A9DE16452BC /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + 099BB149E9B1B9A91BCB6709 /* [CP] Embed Pods Frameworks */, + 3C7DC233D3E7D64C8216E7B8 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NetworkEye_Example; + productName = NetworkEye; + productReference = 607FACD01AFB9204008FA782 /* NetworkEye_Example.app */; + productType = "com.apple.product-type.application"; + }; + 607FACE41AFB9204008FA782 /* NetworkEye_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "NetworkEye_Tests" */; + buildPhases = ( + 7EDF56C3F5DEA3BAE339D2C7 /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + 19CB2DC199F8946AB21E8DE2 /* [CP] Embed Pods Frameworks */, + 7C03552F8DE7EEA14C17767A /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 607FACE71AFB9204008FA782 /* PBXTargetDependency */, + ); + name = NetworkEye_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* NetworkEye_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24F9F91E7FC46C001AD0D7 /* NetworkEye */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24F9FF1E7FC46C001AD0D7 /* Build configuration list for PBXNativeTarget "NetworkEye" */; + buildPhases = ( + 9E24F9F51E7FC46C001AD0D7 /* Sources */, + 9E24F9F61E7FC46C001AD0D7 /* Frameworks */, + 9E24F9F71E7FC46C001AD0D7 /* Headers */, + 9E24F9F81E7FC46C001AD0D7 /* Resources */, + 9E24FA0C1E7FC49F001AD0D7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NetworkEye; + productName = NetworkEye; + productReference = 9E24F9FA1E7FC46C001AD0D7 /* NetworkEye.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + }; + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24F9F91E7FC46C001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "NetworkEye" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* NetworkEye_Example */, + 607FACE41AFB9204008FA782 /* NetworkEye_Tests */, + 9E24F9F91E7FC46C001AD0D7 /* NetworkEye */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FAF31E817F68001AD0D7 /* NetworkEye.swift.podspec in Resources */, + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9F81E7FC46C001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 099BB149E9B1B9A91BCB6709 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NetworkEye_Example/Pods-NetworkEye_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 19CB2DC199F8946AB21E8DE2 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NetworkEye_Tests/Pods-NetworkEye_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 3C7DC233D3E7D64C8216E7B8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NetworkEye_Example/Pods-NetworkEye_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 57524D40493C1A9DE16452BC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 7C03552F8DE7EEA14C17767A /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NetworkEye_Tests/Pods-NetworkEye_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 7EDF56C3F5DEA3BAE339D2C7 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 9E24FA0C1E7FC49F001AD0D7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/../Carthage/Build/iOS/AppSwizzle.framework", + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = "/bin/sh "; + shellScript = "/usr/local/bin/carthage copy-frameworks"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* NetworkEyeTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24F9F51E7FC46C001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FA0A1E7FC47E001AD0D7 /* URLSession+Eye.swift in Sources */, + 9E24FA091E7FC47E001AD0D7 /* NetworkEye.swift in Sources */, + 9E24FA081E7FC47E001AD0D7 /* EyeProtocol.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* NetworkEye_Example */; + targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 607FACD91AFB9204008FA782 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 607FACDA1AFB9204008FA782 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F882F7C00A27B2F7998755D6 /* Pods-NetworkEye_Example.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = NetworkEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F50399156AE7AD82AA49298B /* Pods-NetworkEye_Example.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = NetworkEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3DFD45BBB9133D6E496FDA52 /* Pods-NetworkEye_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B44E08D635539770D577545B /* Pods-NetworkEye_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24FA001E7FC46C001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../Carthage/Build/iOS/**"; + INFOPLIST_FILE = NetworkEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.NetworkEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24FA011E7FC46C001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../Carthage/Build/iOS/**"; + INFOPLIST_FILE = NetworkEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.NetworkEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "NetworkEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "NetworkEye_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "NetworkEye_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24F9FF1E7FC46C001AD0D7 /* Build configuration list for PBXNativeTarget "NetworkEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24FA001E7FC46C001AD0D7 /* Debug */, + 9E24FA011E7FC46C001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..0495dc2 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/project.xcworkspace/xcshareddata/NetworkEye.xcscmblueprint b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/project.xcworkspace/xcshareddata/NetworkEye.xcscmblueprint new file mode 100644 index 0000000..c9c5752 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/project.xcworkspace/xcshareddata/NetworkEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "D59A67FE6CA170C15FD7BFC20A431E042F4DA650", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "D59A67FE6CA170C15FD7BFC20A431E042F4DA650" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "4A406088-E56E-46E9-AADA-9C8F4B62E982", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "D59A67FE6CA170C15FD7BFC20A431E042F4DA650" : "NetworkEye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "NetworkEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/NetworkEye.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/NetworkEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "D59A67FE6CA170C15FD7BFC20A431E042F4DA650" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/xcshareddata/xcschemes/NetworkEye-Example.xcscheme b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/xcshareddata/xcschemes/NetworkEye-Example.xcscheme new file mode 100644 index 0000000..52572f8 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/xcshareddata/xcschemes/NetworkEye-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/xcshareddata/xcschemes/NetworkEye.xcscheme b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/xcshareddata/xcschemes/NetworkEye.xcscheme new file mode 100644 index 0000000..f5bbfe7 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcodeproj/xcshareddata/xcschemes/NetworkEye.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..5c8ae3b --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcworkspace/xcshareddata/NetworkEye.xcscmblueprint b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcworkspace/xcshareddata/NetworkEye.xcscmblueprint new file mode 100644 index 0000000..ebee233 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye.xcworkspace/xcshareddata/NetworkEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "D59A67FE6CA170C15FD7BFC20A431E042F4DA650", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "D59A67FE6CA170C15FD7BFC20A431E042F4DA650" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "ED28BAF9-68A9-49D5-B497-F7E8651AA86D", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "D59A67FE6CA170C15FD7BFC20A431E042F4DA650" : "NetworkEye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "NetworkEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/NetworkEye.xcworkspace", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/NetworkEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "D59A67FE6CA170C15FD7BFC20A431E042F4DA650" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye/AppDelegate.swift b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/AppDelegate.swift new file mode 100644 index 0000000..3b32a5a --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// NetworkEye +// +// Created by zixun on 12/25/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..b6a98b7 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Base.lproj/LaunchScreen.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Base.lproj/Main.storyboard b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Base.lproj/Main.storyboard new file mode 100644 index 0000000..52ea29e --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d3942e9 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Info.plist b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye/NetworkEye.h b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/NetworkEye.h new file mode 100644 index 0000000..fc8083e --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/NetworkEye.h @@ -0,0 +1,19 @@ +// +// NetworkEye.h +// NetworkEye +// +// Created by zixun on 2017/3/20. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for NetworkEye. +FOUNDATION_EXPORT double NetworkEyeVersionNumber; + +//! Project version string for NetworkEye. +FOUNDATION_EXPORT const unsigned char NetworkEyeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/NetworkEye/Example/NetworkEye/ViewController.swift b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/ViewController.swift new file mode 100644 index 0000000..0a14ab0 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/NetworkEye/ViewController.swift @@ -0,0 +1,25 @@ +// +// ViewController.swift +// NetworkEye +// +// Created by zixun on 12/25/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit +import NetworkEye + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + +} + diff --git a/Carthage/Checkouts/NetworkEye/Example/Podfile b/Carthage/Checkouts/NetworkEye/Example/Podfile new file mode 100644 index 0000000..d6313ba --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/Podfile @@ -0,0 +1,11 @@ +use_frameworks! + +target 'NetworkEye_Example' do + pod 'NetworkEye.swift', :path => '../' + + target 'NetworkEye_Tests' do + inherit! :search_paths + + + end +end diff --git a/Carthage/Checkouts/NetworkEye/Example/Podfile.lock b/Carthage/Checkouts/NetworkEye/Example/Podfile.lock new file mode 100644 index 0000000..953dd05 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/Podfile.lock @@ -0,0 +1,19 @@ +PODS: + - AppSwizzle (1.1.1) + - NetworkEye.swift (1.1.0): + - AppSwizzle (~> 1.1.1) + +DEPENDENCIES: + - NetworkEye.swift (from `../`) + +EXTERNAL SOURCES: + NetworkEye.swift: + :path: "../" + +SPEC CHECKSUMS: + AppSwizzle: ff4ae6735b6e2bab9991d5b660357beae2fa6e68 + NetworkEye.swift: c99e8f04bd0c31abd7a67cb2dd0bc853684c1c8c + +PODFILE CHECKSUM: fb21f5492104a96e2a848f861b53aa7335fe9ded + +COCOAPODS: 1.2.0 diff --git a/Carthage/Checkouts/NetworkEye/Example/Tests/Info.plist b/Carthage/Checkouts/NetworkEye/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/NetworkEye/Example/Tests/NetworkEyeTests.swift b/Carthage/Checkouts/NetworkEye/Example/Tests/NetworkEyeTests.swift new file mode 100644 index 0000000..c1d24a6 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/Example/Tests/NetworkEyeTests.swift @@ -0,0 +1,81 @@ +import UIKit +import XCTest +import NetworkEye + +class NetworkEyeTests: XCTestCase, NetworkEyeDelegate { + + override func setUp() { + super.setUp() + NetworkEye.add(observer: self) + } + + override func tearDown() { + NetworkEye.remove(observer: self) + super.tearDown() + } + + //MARK: Test Case + func testConnection() { + self.expectation = self.expectation(description: "testConnection") + + let data = try! NSURLConnection.sendSynchronousRequest(request, returning: nil) + print(data) + + self.waitForExpectations(timeout: 4) { (error:Error?) in + if (error != nil) { + XCTFail("Expectation Failed with error: \(error)") + } + } + } + + func testSession() { + self.expectation = self.expectation(description: "testConfigurationSession") + + let session = URLSession.shared + URLSession.shared.dataTask(with: self.request) + let task = session.dataTask(with: self.request) { (data:Data?, response:URLResponse?, error:Error?) in + print(response) + } + task.resume() + + self.waitForExpectations(timeout: 4) { (error:Error?) in + if (error != nil) { + XCTFail("Expectation Failed with error: \(error)") + } + } + } + + func testConfigurationSession() { + self.expectation = self.expectation(description: "testConfigurationSession") + + let configure = URLSessionConfiguration.default + let session = URLSession(configuration: configure, + delegate: nil, + delegateQueue: OperationQueue.current) + let task = session.dataTask(with: self.request) { (data:Data?, response:URLResponse?, error:Error?) in + print(response) + } + task.resume() + + self.waitForExpectations(timeout: 4) { (error:Error?) in + if (error != nil) { + XCTFail("Expectation Failed with error: \(error)") + } + } + } + + func networkEyeDidCatch(with request:URLRequest?,response:URLResponse?,data:Data?) { + XCTAssert(true, "Pass") + self.expectation?.fulfill() + } + + //MARK: Private var + private lazy var request: URLRequest = { + let urlString = "https://api.github.com/search/users?q=language:objective-c&sort=followers&order=desc" + let url = URL(string: urlString) + return URLRequest(url: url!) + }() + + private var expectation:XCTestExpectation? + +} diff --git a/Carthage/Checkouts/NetworkEye/LICENSE b/Carthage/Checkouts/NetworkEye/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/NetworkEye/NetworkEye.swift.podspec b/Carthage/Checkouts/NetworkEye/NetworkEye.swift.podspec new file mode 100644 index 0000000..fd8f62e --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/NetworkEye.swift.podspec @@ -0,0 +1,35 @@ +# +# Be sure to run `pod lib lint NetworkEye.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'NetworkEye.swift' + s.version = '1.1.1' + s.summary = 'NetworkEye is a network monitor,automatic catch the request and response infomation of all kinds of request send.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +NetworkEye is a network monitor,automatic catch the request and response infomation of all kinds of request send.. + DESC + + s.module_name = 'NetworkEye' + s.homepage = 'https://github.com/zixun/NetworkEye' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'zixun' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/NetworkEye.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'NetworkEye/Classes/**/*' + s.dependency 'AppSwizzle', '~> 1.1.1' +end diff --git a/Carthage/Checkouts/NetworkEye/NetworkEye/Classes/EyeProtocol.swift b/Carthage/Checkouts/NetworkEye/NetworkEye/Classes/EyeProtocol.swift new file mode 100644 index 0000000..6305817 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/NetworkEye/Classes/EyeProtocol.swift @@ -0,0 +1,152 @@ +// +// EyeProtocol.swift +// Pods +// +// Created by zixun on 16/12/25. +// +// + +import Foundation + + + +class EyeProtocol: URLProtocol { + + class func open() { + URLProtocol.registerClass(self.classForCoder()) + } + + class func close() { + URLProtocol.unregisterClass(self.classForCoder()) + } + + open class func add(delegate:NetworkEyeDelegate) { + // delete null week delegate + self.delegates = self.delegates.filter { + return $0.delegate != nil + } + + // judge if contains the delegate from parameter + let contains = self.delegates.contains { + return $0.delegate?.hash == delegate.hash + } + // if not contains, append it with weak wrapped + if contains == false { + let week = WeakNetworkEyeDelegate(delegate: delegate) + + self.delegates.append(week) + } + } + + open class func remove(delegate:NetworkEyeDelegate) { + self.delegates = self.delegates.filter { + // filter null weak delegate + return $0.delegate != nil + }.filter { + // filter the delegate from parameter + return $0.delegate?.hash != delegate.hash + } + } + + fileprivate var connection: NSURLConnection? + + fileprivate var ca_request: URLRequest? + fileprivate var ca_response: URLResponse? + fileprivate var ca_data:Data? + + fileprivate static let AppNetworkGreenCard = "AppNetworkGreenCard" + + private(set) static var delegates = [WeakNetworkEyeDelegate]() + +} + +extension EyeProtocol { + override class func canInit(with request: URLRequest) -> Bool { + + guard let scheme = request.url?.scheme else { + return false + } + + guard scheme == "http" || scheme == "https" else { + return false + } + + guard URLProtocol.property(forKey: AppNetworkGreenCard, in: request) == nil else { + return false + } + + return true + } + + override class func canonicalRequest(for request: URLRequest) -> URLRequest { + + let req = (request as NSURLRequest).mutableCopy() as! NSMutableURLRequest + URLProtocol.setProperty(true, forKey: AppNetworkGreenCard, in: req) + return req.copy() as! URLRequest + } + + override func startLoading() { + let request = EyeProtocol.canonicalRequest(for: self.request) + self.connection = NSURLConnection(request: request, delegate: self, startImmediately: true) + + self.ca_request = self.request + } + + override func stopLoading() { + self.connection?.cancel() + for element in EyeProtocol.delegates { + element.delegate?.networkEyeDidCatch(with: self.ca_request, response: self.ca_response, data: self.ca_data) + } + } +} + +extension EyeProtocol: NSURLConnectionDelegate { + func connection(_ connection: NSURLConnection, didFailWithError error: Error) { + self.client?.urlProtocol(self, didFailWithError: error) + } + + func connectionShouldUseCredentialStorage(_ connection: NSURLConnection) -> Bool { + return true + } + + func connection(_ connection: NSURLConnection, didReceive challenge: URLAuthenticationChallenge) { + self.client?.urlProtocol(self, didReceive: challenge) + } + + func connection(_ connection: NSURLConnection, didCancel challenge: URLAuthenticationChallenge) { + self.client?.urlProtocol(self, didCancel: challenge) + } +} + +extension EyeProtocol: NSURLConnectionDataDelegate { + + func connection(_ connection: NSURLConnection, willSend request: URLRequest, redirectResponse response: URLResponse?) -> URLRequest? { + if response != nil { + self.ca_response = response + self.client?.urlProtocol(self, wasRedirectedTo: request, redirectResponse: response!) + } + return request + } + + func connection(_ connection: NSURLConnection, didReceive response: URLResponse) { + self.client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: URLCache.StoragePolicy.allowed) + self.ca_response = response + } + + func connection(_ connection: NSURLConnection, didReceive data: Data) { + self.client?.urlProtocol(self, didLoad: data) + if self.ca_data == nil { + self.ca_data = data + }else { + self.ca_data!.append(data) + } + } + + func connection(_ connection: NSURLConnection, willCacheResponse cachedResponse: CachedURLResponse) -> CachedURLResponse? { + return cachedResponse + } + + func connectionDidFinishLoading(_ connection: NSURLConnection) { + self.client?.urlProtocolDidFinishLoading(self) + } +} diff --git a/Carthage/Checkouts/NetworkEye/NetworkEye/Classes/NetworkEye.swift b/Carthage/Checkouts/NetworkEye/NetworkEye/Classes/NetworkEye.swift new file mode 100644 index 0000000..5e73733 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/NetworkEye/Classes/NetworkEye.swift @@ -0,0 +1,48 @@ +// +// NetworkEye.swift +// Pods +// +// Created by zixun on 16/12/26. +// +// + +import Foundation + +public protocol NetworkEyeDelegate: NSObjectProtocol { + func networkEyeDidCatch(with request:URLRequest?,response:URLResponse?,data:Data?) +} + +class WeakNetworkEyeDelegate: NSObject { + weak var delegate : NetworkEyeDelegate? + init (delegate: NetworkEyeDelegate) { + super.init() + self.delegate = delegate + } +} + + +open class NetworkEye: NSObject { + + open static var isWatching: Bool { + get { + return EyeProtocol.delegates.count > 0 + } + } + + open class func add(observer:NetworkEyeDelegate) { + if EyeProtocol.delegates.count == 0 { + EyeProtocol.open() + URLSession.open() + } + EyeProtocol.add(delegate: observer) + } + + open class func remove(observer:NetworkEyeDelegate) { + EyeProtocol.remove(delegate: observer) + if EyeProtocol.delegates.count == 0 { + EyeProtocol.close() + URLSession.close() + } + } + +} diff --git a/Carthage/Checkouts/NetworkEye/NetworkEye/Classes/URLSession+Eye.swift b/Carthage/Checkouts/NetworkEye/NetworkEye/Classes/URLSession+Eye.swift new file mode 100644 index 0000000..0b36c65 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/NetworkEye/Classes/URLSession+Eye.swift @@ -0,0 +1,69 @@ +// +// URLSession+Eye.swift +// Pods +// +// Created by zixun on 16/12/26. +// +// + +import Foundation +import AppSwizzle + +extension URLSession { + convenience init(configurationMonitor: URLSessionConfiguration, delegate: URLSessionDelegate?, delegateQueue queue: OperationQueue?) { + + if configurationMonitor.protocolClasses != nil { + configurationMonitor.protocolClasses!.insert(EyeProtocol.classForCoder(), at: 0) + }else { + configurationMonitor.protocolClasses = [EyeProtocol.classForCoder()] + } + + self.init(configurationMonitor: configurationMonitor, delegate: delegate, delegateQueue: queue) + } + + class func open() { + if self.isSwizzled == false && self.hook() == .Succeed { + self.isSwizzled = true + }else { + print("[NetworkEye] already started or hook failure") + } + } + + class func close() { + if self.isSwizzled == true && self.hook() == .Succeed { + self.isSwizzled = false + }else { + print("[NetworkEye] already stoped or hook failure") + } + } + + + private class func hook() -> SwizzleResult { + // let orig = #selector(URLSession.init(configuration:delegate:delegateQueue:)) + // the result is sessionWithConfiguration:delegate:delegateQueue: which runtime can't find it + + let orig = Selector("initWithConfiguration:delegate:delegateQueue:") + let alter = #selector(URLSession.init(configurationMonitor:delegate:delegateQueue:)) + let result = URLSession.swizzleInstanceMethod(origSelector: orig, toAlterSelector: alter) + return result + } + + + + private static var isSwizzled:Bool { + set{ + objc_setAssociatedObject(self, &key.isSwizzled, isSwizzled, .OBJC_ASSOCIATION_ASSIGN); + } + get{ + let result = objc_getAssociatedObject(self, &key.isSwizzled) as? Bool + if result == nil { + return false + } + return result! + } + } + + private struct key { + static var isSwizzled: Character = "c" + } +} diff --git a/Carthage/Checkouts/NetworkEye/README.md b/Carthage/Checkouts/NetworkEye/README.md new file mode 100644 index 0000000..0a16bed --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/README.md @@ -0,0 +1,67 @@ +# NetworkEye + +[![License](https://img.shields.io/cocoapods/l/NetworkEye.svg?style=flat)](http://cocoapods.org/pods/NetworkEye) +[![Platform](https://img.shields.io/cocoapods/p/NetworkEye.svg?style=flat)](http://cocoapods.org/pods/NetworkEye) +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) + +NetworkEye is a network monitor,automatic catch the request and response infomation of all kinds of request send + +## Family +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Book & Principle + +**I has wrote a book named [《iOS监控编程》](https://www.qingdan.us/product/25),each chapter records the course function of the implementation details and the way to explore.sorry for english friends,this book wrote by chineses.** + +## Example + +To run the example project, clone the repo, and run `pod install` from the Example directory first. + +## Usage + +add observer: + +```swift +NetworkEye.add(observer: self) +``` +implement the observer delegate: + +```swift +func networkEyeDidCatch(with request:URLRequest?,response:URLResponse?,data:Data?) { + XCTAssert(true, "Pass") +} +``` + + + +## Installation + +### CocoaPods +NetworkEye is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "NetworkEye" +``` +### Carthage +Or, if you’re using [Carthage](https://github.com/Carthage/Carthage), add SwViewCapture to your Cartfile: + +``` +github "zixun/NetworkEye" +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + +## License + +NetworkEye is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/NetworkEye/_Pods.xcodeproj b/Carthage/Checkouts/NetworkEye/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/NetworkEye/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/SQLite.swift/.cocoadocs.yml b/Carthage/Checkouts/SQLite.swift/.cocoadocs.yml new file mode 100644 index 0000000..2784003 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/.cocoadocs.yml @@ -0,0 +1,2 @@ +additional_guides: + - Documentation/Index.md diff --git a/Carthage/Checkouts/SQLite.swift/.gitignore b/Carthage/Checkouts/SQLite.swift/.gitignore new file mode 100644 index 0000000..5882e0c --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/.gitignore @@ -0,0 +1,27 @@ +# OS X +.DS_Store + +# Xcode +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate + +# Carthage +/Carthage/ + +# Swift Package Manager +.build +Packages/ diff --git a/Carthage/Checkouts/SQLite.swift/.gitmodules b/Carthage/Checkouts/SQLite.swift/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/Carthage/Checkouts/SQLite.swift/.swift-version b/Carthage/Checkouts/SQLite.swift/.swift-version new file mode 100644 index 0000000..9f55b2c --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/.swift-version @@ -0,0 +1 @@ +3.0 diff --git a/Carthage/Checkouts/SQLite.swift/.travis.yml b/Carthage/Checkouts/SQLite.swift/.travis.yml new file mode 100644 index 0000000..3747ac7 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/.travis.yml @@ -0,0 +1,26 @@ +language: objective-c +rvm: 2.2 +osx_image: xcode8.2 +env: + global: + - IOS_SIMULATOR="iPhone 6s" +matrix: + include: + - env: BUILD_SCHEME="SQLite iOS" + - env: BUILD_SCHEME="SQLite Mac" + - env: VALIDATOR_SUBSPEC="none" + - env: VALIDATOR_SUBSPEC="standard" + - env: VALIDATOR_SUBSPEC="standalone" + - env: VALIDATOR_SUBSPEC="SQLCipher" + - env: CARTHAGE_PLATFORM="iOS" + - env: CARTHAGE_PLATFORM="Mac" + - env: CARTHAGE_PLATFORM="watchOS" + - env: CARTHAGE_PLATFORM="tvOS" + - env: PACKAGE_MANAGER_COMMAND="test -Xlinker -lsqlite3" +before_install: + - gem update bundler + - gem install xcpretty --no-document + - brew update + - brew outdated carthage || brew upgrade carthage +script: + - ./run-tests.sh diff --git a/Carthage/Checkouts/SQLite.swift/CHANGELOG.md b/Carthage/Checkouts/SQLite.swift/CHANGELOG.md new file mode 100644 index 0000000..f3298d6 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CHANGELOG.md @@ -0,0 +1,34 @@ +0.11.2 (25-12-2016), [diff][diff-0.11.2] +======================================== + +* Fixed SQLCipher integration with read-only databases ([#559][]) +* Preliminary Swift Package Manager support ([#548][], [#560][]) +* Fixed null pointer when fetching an empty BLOB ([#561][]) +* Allow `where` as alias for `filter` ([#571][]) + +0.11.1 (06-12-2016), [diff][diff-0.11.1] +======================================== + +* Integrate SQLCipher via CocoaPods ([#546][], [#553][]) +* Made lastInsertRowid consistent with other SQLite wrappers ([#532][]) +* Fix for ~= operator used with Double ranges +* Various documentation updates + +0.11.0 (19-10-2016) +=================== + +* Swift3 migration ([diff][diff-0.11.0]) + + +[diff-0.11.0]: https://github.com/stephencelis/SQLite.swift/compare/0.10.1...0.11.0 +[diff-0.11.1]: https://github.com/stephencelis/SQLite.swift/compare/0.11.0...0.11.1 +[diff-0.11.2]: https://github.com/stephencelis/SQLite.swift/compare/0.11.1...0.11.2 + +[#532]: https://github.com/stephencelis/SQLite.swift/issues/532 +[#546]: https://github.com/stephencelis/SQLite.swift/issues/546 +[#548]: https://github.com/stephencelis/SQLite.swift/pull/548 +[#553]: https://github.com/stephencelis/SQLite.swift/pull/553 +[#559]: https://github.com/stephencelis/SQLite.swift/pull/559 +[#560]: https://github.com/stephencelis/SQLite.swift/pull/560 +[#561]: https://github.com/stephencelis/SQLite.swift/issues/561 +[#571]: https://github.com/stephencelis/SQLite.swift/issues/571 diff --git a/Carthage/Checkouts/SQLite.swift/CONTRIBUTING.md b/Carthage/Checkouts/SQLite.swift/CONTRIBUTING.md new file mode 100644 index 0000000..60c1837 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CONTRIBUTING.md @@ -0,0 +1,108 @@ +# Contributing + +The where and when to open an [issue](#issues) or [pull +request](#pull-requests). + + +## Issues + +Issues are used to track **bugs** and **feature requests**. Need **help** or +have a **general question**? [Ask on Stack Overflow][] (tag `sqlite.swift`). + +Before reporting a bug or requesting a feature, [run a few searches][Search] to +see if a similar issue has already been opened and ensure you’re not submitting +a duplicate. + +If you find a similar issue, read the existing conversation and see if it +addresses everything. If it doesn’t, continue the conversation there. + +If your searches return empty, see the [bug](#bugs) or [feature +request](#feature-requests) guidelines below. + +[Ask on Stack Overflow]: http://stackoverflow.com/questions/tagged/sqlite.swift +[Search]: https://github.com/stephencelis/SQLite.swift/search?type=Issues + + +### Bugs + +Think you’ve discovered a new **bug**? Let’s try troubleshooting a few things +first. + + - **Is it an installation issue?** + + If this is your first time building SQLite.swift in your project, you may + encounter a build error, _e.g._: + + No such module 'SQLite' + + Please carefully re-read the [installation instructions][] to make sure + everything is in order. + + - **Have you read the documentation?** + + If you can’t seem to get something working, check + [the documentation][See Documentation] to see if the solution is there. + + - **Are you up-to-date?** + + If you’re perusing [the documentation][See Documentation] online and find + that an example is just not working, please upgrade to the latest version + of SQLite.swift and try again before continuing. + + - **Is it an unhelpful build error?** + + While Swift error messaging is improving with each release, complex + expressions still lend themselves to misleading errors. If you encounter an + error on a complex line, breaking it down into smaller pieces generally + yields a more understandable error. + + - **Is it an _even more_ unhelpful build error?** + + Have you updated Xcode recently? Did your project stop building out of the + blue? + + Hold down the **option** key and select **Clean Build Folder…** from the + **Product** menu (⌥⇧⌘K). + +Made it through everything above and still having trouble? Sorry! +[Open an issue][]! And _please_: + + - Be as descriptive as possible. + - Provide as much information needed to _reliably reproduce_ the issue. + - Attach screenshots if possible. + - Better yet: attach GIFs or link to video. + - Even better: link to a sample project exhibiting the issue. + - Include the SQLite.swift commit or branch experiencing the issue. + - Include devices and operating systems affected. + - Include build information: the Xcode and OS X versions affected. + +[installation instructions]: Documentation/Index.md#installation +[See Documentation]: Documentation/Index.md#sqliteswift-documentation +[Open an issue]: https://github.com/stephencelis/SQLite.swift/issues/new + + +### Feature Requests + +Have an innovative **feature request**? [Open an issue][]! Be thorough! Provide +context and examples. Be open to discussion. + + +## Pull Requests + +Interested in contributing but don’t know where to start? Try the [`help +wanted`][help wanted] label. + +Ready to submit a fix or a feature? [Submit a pull request][]! And _please_: + + - If code changes, run the tests and make sure everything still works. + - Write new tests for new functionality. + - Update documentation comments where applicable. + - Maintain the existing style. + - Don’t forget to have fun. + +While we cannot guarantee a merge to every pull request, we do read each one +and love your input. + + +[help wanted]: https://github.com/stephencelis/SQLite.swift/labels/help%20wanted +[Submit a pull request]: https://github.com/stephencelis/SQLite.swift/fork diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/appletvos/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/appletvos/module.modulemap new file mode 100644 index 0000000..637d993 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/appletvos/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/appletvsimulator/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/appletvsimulator/module.modulemap new file mode 100644 index 0000000..f8b9b67 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/appletvsimulator/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/iphoneos-10.0/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/iphoneos-10.0/module.modulemap new file mode 100644 index 0000000..67a6c20 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/iphoneos-10.0/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/iphoneos/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/iphoneos/module.modulemap new file mode 100644 index 0000000..043db6c --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/iphoneos/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/iphonesimulator-10.0/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/iphonesimulator-10.0/module.modulemap new file mode 100644 index 0000000..c8b84ab --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/iphonesimulator-10.0/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.0.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/iphonesimulator/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/iphonesimulator/module.modulemap new file mode 100644 index 0000000..a7b14cb --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/iphonesimulator/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/macosx-10.11/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/macosx-10.11/module.modulemap new file mode 100644 index 0000000..9e09129 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/macosx-10.11/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/macosx-10.12/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/macosx-10.12/module.modulemap new file mode 100644 index 0000000..8fc958e --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/macosx-10.12/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/macosx/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/macosx/module.modulemap new file mode 100644 index 0000000..cc8370e --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/macosx/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/watchos/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/watchos/module.modulemap new file mode 100644 index 0000000..62a6c4e --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/watchos/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/CocoaPods/watchsimulator/module.modulemap b/Carthage/Checkouts/SQLite.swift/CocoaPods/watchsimulator/module.modulemap new file mode 100644 index 0000000..086fbab --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/CocoaPods/watchsimulator/module.modulemap @@ -0,0 +1,4 @@ +module CSQLite [system] { + header "/Applications/Xcode.app/Contents/Developer/Platforms/WatchSimulator.platform/Developer/SDKs/WatchSimulator.sdk/usr/include/sqlite3.h" + export * +} diff --git a/Carthage/Checkouts/SQLite.swift/Documentation/Index.md b/Carthage/Checkouts/SQLite.swift/Documentation/Index.md new file mode 100644 index 0000000..3e13ad4 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Documentation/Index.md @@ -0,0 +1,1587 @@ +# SQLite.swift Documentation + + - [Installation](#installation) + - [Carthage](#carthage) + - [CocoaPods](#cocoapods) + - [Swift Package Manager](#swift-package-manager) + - [Manual](#manual) + - [Getting Started](#getting-started) + - [Connecting to a Database](#connecting-to-a-database) + - [Read-Write Databases](#read-write-databases) + - [Read-Only Databases](#read-only-databases) + - [In-Memory Databases](#in-memory-databases) + - [Thread-Safety](#thread-safety) + - [Building Type-Safe SQL](#building-type-safe-sql) + - [Expressions](#expressions) + - [Compound Expressions](#compound-expressions) + - [Queries](#queries) + - [Creating a Table](#creating-a-table) + - [Create Table Options](#create-table-options) + - [Column Constraints](#column-constraints) + - [Table Constraints](#table-constraints) + - [Inserting Rows](#inserting-rows) + - [Setters](#setters) + - [Selecting Rows](#selecting-rows) + - [Iterating and Accessing Values](#iterating-and-accessing-values) + - [Plucking Rows](#plucking-rows) + - [Building Complex Queries](#building-complex-queries) + - [Selecting Columns](#selecting-columns) + - [Joining Other Tables](#joining-other-tables) + - [Column Namespacing](#column-namespacing) + - [Table Aliasing](#table-aliasing) + - [Filtering Rows](#filtering-rows) + - [Filter Operators and Functions](#filter-operators-and-functions) + - [Sorting Rows](#sorting-rows) + - [Limiting and Paging Results](#limiting-and-paging-results) + - [Aggregation](#aggregation) + - [Updating Rows](#updating-rows) + - [Deleting Rows](#deleting-rows) + - [Transactions and Savepoints](#transactions-and-savepoints) + - [Altering the Schema](#altering-the-schema) + - [Renaming Tables](#renaming-tables) + - [Adding Columns](#adding-columns) + - [Added Column Constraints](#added-column-constraints) + - [Indexes](#indexes) + - [Creating Indexes](#creating-indexes) + - [Dropping Indexes](#dropping-indexes) + - [Dropping Tables](#dropping-tables) + - [Migrations and Schema Versioning](#migrations-and-schema-versioning) + - [Custom Types](#custom-types) + - [Date-Time Values](#date-time-values) + - [Binary Data](#binary-data) + - [Custom Type Caveats](#custom-type-caveats) + - [Other Operators](#other-operators) + - [Core SQLite Functions](#core-sqlite-functions) + - [Aggregate SQLite Functions](#aggregate-sqlite-functions) + - [Custom SQL Functions](#custom-sql-functions) + - [Custom Collations](#custom-collations) + - [Full-text Search](#full-text-search) + - [Executing Arbitrary SQL](#executing-arbitrary-sql) + - [Logging](#logging) + + +[↩]: #sqliteswift-documentation + + +## Installation + +> _Note:_ SQLite.swift requires Swift 3 (and [Xcode 8](https://developer.apple.com/xcode/downloads/)) or greater. + + +### Carthage + +[Carthage][] is a simple, decentralized dependency manager for Cocoa. To +install SQLite.swift with Carthage: + + 1. Make sure Carthage is [installed][Carthage Installation]. + + 2. Update your Cartfile to include the following: + + ``` + github "stephencelis/SQLite.swift" ~> 0.11.2 + ``` + + 3. Run `carthage update` and [add the appropriate framework][Carthage Usage]. + + +[Carthage]: https://github.com/Carthage/Carthage +[Carthage Installation]: https://github.com/Carthage/Carthage#installing-carthage +[Carthage Usage]: https://github.com/Carthage/Carthage#adding-frameworks-to-an-application + + +### CocoaPods + +[CocoaPods][] is a dependency manager for Cocoa projects. To install SQLite.swift with CocoaPods: + + 1. Verify that your copy of Xcode is installed and active in the default location (`/Applications/Xcode.app`). + + ```sh + sudo xcode-select --switch /Applications/Xcode.app + ``` + + 2. Make sure CocoaPods is [installed][CocoaPods Installation] (SQLite.swift requires version 1.0.0 or greater). + + ``` sh + # Using the default Ruby install will require you to use sudo when + # installing and updating gems. + [sudo] gem install cocoapods + ``` + + 3. Update your Podfile to include the following: + + ``` ruby + use_frameworks! + + target 'YourAppTargetName' do + pod 'SQLite.swift', '~> 0.11.2' + end + ``` + + 4. Run `pod install --repo-update`. + + +#### Requiring a specific version of SQLite + + If you want to use a more recent version of SQLite than what is provided with the OS you can require the `standalone` subspec: + +``` ruby +target 'YourAppTargetName' do + pod 'SQLite.swift/standalone', '~> 0.11.2' +end +``` + +By default this will use the most recent version of SQLite without any extras. If you want you can further customize this by adding another dependency to sqlite3 or one of its subspecs: + +``` ruby +target 'YourAppTargetName' do + pod 'SQLite.swift/standalone', '~> 0.11.2' + pod 'sqlite3/fts5', '= 3.15.0' # SQLite 3.15.0 with FTS5 enabled +end +``` + +See the [sqlite3 podspec][sqlite3pod] for more details. + +#### Using SQLite.swift with SQLCipher + +If you want to use [SQLCipher][] with SQLite.swift you can require the `SQLCipher` +subspec in your Podfile: + +``` ruby +target 'YourAppTargetName' do + pod 'SQLite.swift/SQLCipher', '~> 0.11.2' +end +``` + +This will automatically add a dependency to the SQLCipher pod as well as extend +`Connection` with methods to change the database key: + +``` swift +import SQLite + +let db = try Connection("path/to/db.sqlite3") +try db.key("secret") +try db.rekey("another secret") +``` + +[CocoaPods]: https://cocoapods.org +[CocoaPods Installation]: https://guides.cocoapods.org/using/getting-started.html#getting-started +[sqlite3pod]: https://github.com/clemensg/sqlite3pod +[SQLCipher]: https://www.zetetic.net/sqlcipher/ + +### Swift Package Manager + +The [Swift Package Manager][] is a tool for managing the distribution of Swift code. +It’s integrated with the Swift build system to automate the process of +downloading, compiling, and linking dependencies. + +It is the recommended approach for using SQLite.swift in OSX CLI applications. + + 1. Add the following to your `Package.swift` file: + + ``` swift + dependencies: [ + .Package(url: "https://github.com/stephencelis/SQLite.swift.git", majorVersion: 0, minor: 11) + ] + ``` + + 2. Build your project: + + ``` sh + $ swift build -Xlinker -lsqlite3 + ``` + +[Swift Package Manager]: https://swift.org/package-manager + +### Manual + +To install SQLite.swift as an Xcode sub-project: + + 1. Drag the **SQLite.xcodeproj** file into your own project. ([Submodule](http://git-scm.com/book/en/Git-Tools-Submodules), clone, or [download](https://github.com/stephencelis/SQLite.swift/archive/master.zip) the project first.) + + ![Installation Screen Shot](Resources/installation@2x.png) + + 2. In your target’s **General** tab, click the **+** button under **Linked Frameworks and Libraries**. + + 3. Select the appropriate **SQLite.framework** for your platform. + + 4. **Add**. + +You should now be able to `import SQLite` from any of your target’s source files and begin using SQLite.swift. + +Some additional steps are required to install the application on an actual device: + + 5. In the **General** tab, click the **+** button under **Embedded Binaries**. + + 6. Select the appropriate **SQLite.framework** for your platform. + + 7. **Add**. + +## Getting Started + +To use SQLite.swift classes or structures in your target’s source file, first import the `SQLite` module. + +``` swift +import SQLite +``` + + +### Connecting to a Database + +Database connections are established using the `Connection` class. A connection is initialized with a path to a database. SQLite will attempt to create the database file if it does not already exist. + +``` swift +let db = try Connection("path/to/db.sqlite3") +``` + + +#### Read-Write Databases + +On iOS, you can create a writable database in your app’s **Documents** directory. + +``` swift +let path = NSSearchPathForDirectoriesInDomains( + .documentDirectory, .userDomainMask, true +).first! + +let db = try Connection("\(path)/db.sqlite3") +``` + +On OS X, you can use your app’s **Application Support** directory: + +``` swift +var path = NSSearchPathForDirectoriesInDomains( + .applicationSupportDirectory, .userDomainMask, true +).first! + Bundle.main.bundleIdentifier! + +// create parent directory iff it doesn’t exist +try FileManager.default.createDirectoryAtPath( + path, withIntermediateDirectories: true, attributes: nil +) + +let db = try Connection("\(path)/db.sqlite3") +``` + + +#### Read-Only Databases + +If you bundle a database with your app (_i.e._, you’ve copied a database file into your Xcode project and added it to your application target), you can establish a _read-only_ connection to it. + +``` swift +let path = Bundle.main.pathForResource("db", ofType: "sqlite3")! + +let db = try Connection(path, readonly: true) +``` + +> _Note:_ Signed applications cannot modify their bundle resources. If you bundle a database file with your app for the purpose of bootstrapping, copy it to a writable location _before_ establishing a connection (see [Read-Write Databases](#read-write-databases), above, for typical, writable locations). +> +> See these two Stack Overflow questions for more information about iOS apps with SQLite databases: [1](https://stackoverflow.com/questions/34609746/what-different-between-store-database-in-different-locations-in-ios), [2](https://stackoverflow.com/questions/34614968/ios-how-to-copy-pre-seeded-database-at-the-first-running-app-with-sqlite-swift). We welcome sample code to show how to successfully copy and use a bundled "seed" database for writing in an app. + +#### In-Memory Databases + +If you omit the path, SQLite.swift will provision an [in-memory database](https://www.sqlite.org/inmemorydb.html). + +``` swift +let db = try Connection() // equivalent to `Connection(.inMemory)` +``` + +To create a temporary, disk-backed database, pass an empty file name. + +``` swift +let db = try Connection(.temporary) +``` + +In-memory databases are automatically deleted when the database connection is closed. + + +#### Thread-Safety + +Every Connection comes equipped with its own serial queue for statement execution and can be safely accessed across threads. Threads that open transactions and savepoints will block other threads from executing statements while the transaction is open. + +If you maintain multiple connections for a single database, consider setting a timeout (in seconds) and/or a busy handler: + +```swift +db.busyTimeout = 5 + +db.busyHandler({ tries in + if tries >= 3 { + return false + } + return true +}) +``` + +> _Note:_ The default timeout is 0, so if you see `database is locked` errors, you may be trying to access the same database simultaneously from multiple connections. + + +## Building Type-Safe SQL + +SQLite.swift comes with a typed expression layer that directly maps [Swift types](https://developer.apple.com/library/prerelease/ios/documentation/General/Reference/SwiftStandardLibraryReference/) to their [SQLite counterparts](https://www.sqlite.org/datatype3.html). + +| Swift Type | SQLite Type | +| --------------- | ----------- | +| `Int64`* | `INTEGER` | +| `Double` | `REAL` | +| `String` | `TEXT` | +| `nil` | `NULL` | +| `SQLite.Blob`† | `BLOB` | + +> *While `Int64` is the basic, raw type (to preserve 64-bit integers on 32-bit platforms), `Int` and `Bool` work transparently. +> +> †SQLite.swift defines its own `Blob` structure, which safely wraps the underlying bytes. +> +> See [Custom Types](#custom-types) for more information about extending other classes and structures to work with SQLite.swift. +> +> See [Executing Arbitrary SQL](#executing-arbitrary-sql) to forego the typed layer and execute raw SQL, instead. + +These expressions (in the form of the structure, [`Expression`](#expressions)) build on one another and, with a query ([`QueryType`](#queries)), can create and execute SQL statements. + + +### Expressions + +Expressions are generic structures associated with a type ([built-in](#building-type-safe-sql) or [custom](#custom-types)), raw SQL, and (optionally) values to bind to that SQL. Typically, you will only explicitly create expressions to describe your columns, and typically only once per column. + +``` swift +let id = Expression("id") +let email = Expression("email") +let balance = Expression("balance") +let verified = Expression("verified") +``` + +Use optional generics for expressions that can evaluate to `NULL`. + +``` swift +let name = Expression("name") +``` + +> _Note:_ The default `Expression` initializer is for [quoted identifiers](https://www.sqlite.org/lang_keywords.html) (_i.e._, column names). To build a literal SQL expression, use `init(literal:)`. + + +### Compound Expressions + +Expressions can be combined with other expressions and types using [filter operators and functions](#filter-operators-and-functions) (as well as other [non-filter operators](#other-operators) and [functions](#core-sqlite-functions)). These building blocks can create complex SQLite statements. + + +### Queries + +Queries are structures that reference a database and table name, and can be used to build a variety of statements using expressions. We can create a query by initializing a `Table`, `View`, or `VirtualTable`. + +``` swift +let users = Table("users") +``` + +Assuming [the table exists](#creating-a-table), we can immediately [insert](#inserting-rows), [select](#selecting-rows), [update](#updating-rows), and [delete](#deleting-rows) rows. + + +## Creating a Table + +We can build [`CREATE TABLE` statements](https://www.sqlite.org/lang_createtable.html) by calling the `create` function on a `Table`. The following is a basic example of SQLite.swift code (using the [expressions](#expressions) and [query](#queries) above) and the corresponding SQL it generates. + +``` swift +try db.run(users.create { t in // CREATE TABLE "users" ( + t.column(id, primaryKey: true) // "id" INTEGER PRIMARY KEY NOT NULL, + t.column(email, unique: true) // "email" TEXT UNIQUE NOT NULL, + t.column(name) // "name" TEXT +}) // ) +``` + +> _Note:_ `Expression` structures (in this case, the `id` and `email` columns), generate `NOT NULL` constraints automatically, while `Expression` structures (`name`) do not. + + +### Create Table Options + +The `Table.create` function has several default parameters we can override. + + - `temporary` adds a `TEMPORARY` clause to the `CREATE TABLE` statement (to create a temporary table that will automatically drop when the database connection closes). Default: `false`. + + ``` swift + try db.run(users.create(temporary: true) { t in /* ... */ }) + // CREATE TEMPORARY TABLE "users" -- ... + ``` + + - `ifNotExists` adds an `IF NOT EXISTS` clause to the `CREATE TABLE` statement (which will bail out gracefully if the table already exists). Default: `false`. + + ``` swift + try db.run(users.create(ifNotExists: true) { t in /* ... */ }) + // CREATE TABLE "users" IF NOT EXISTS -- ... + ``` + +### Column Constraints + +The `column` function is used for a single column definition. It takes an [expression](#expressions) describing the column name and type, and accepts several parameters that map to various column constraints and clauses. + + - `primaryKey` adds a `PRIMARY KEY` constraint to a single column. + + ``` swift + t.column(id, primaryKey: true) + // "id" INTEGER PRIMARY KEY NOT NULL + + t.column(id, primaryKey: .autoincrement) + // "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL + ``` + + > _Note:_ The `primaryKey` parameter cannot be used alongside `references`. If you need to create a column that has a default value and is also a primary and/or foreign key, use the `primaryKey` and `foreignKey` functions mentioned under [Table Constraints](#table-constraints). + > + > Primary keys cannot be optional (_e.g._, `Expression`). + > + > Only an `INTEGER PRIMARY KEY` can take `.autoincrement`. + + - `unique` adds a `UNIQUE` constraint to the column. (See the `unique` function under [Table Constraints](#table-constraints) for uniqueness over multiple columns). + + ``` swift + t.column(email, unique: true) + // "email" TEXT UNIQUE NOT NULL + ``` + + - `check` attaches a `CHECK` constraint to a column definition in the form of a boolean expression (`Expression`). Boolean expressions can be easily built using [filter operators and functions](#filter-operators-and-functions). (See also the `check` function under [Table Constraints](#table-constraints).) + + ``` swift + t.column(email, check: email.like("%@%")) + // "email" TEXT NOT NULL CHECK ("email" LIKE '%@%') + ``` + + - `defaultValue` adds a `DEFAULT` clause to a column definition and _only_ accepts a value (or expression) matching the column’s type. This value is used if none is explicitly provided during [an `INSERT`](#inserting-rows). + + ``` swift + t.column(name, defaultValue: "Anonymous") + // "name" TEXT DEFAULT 'Anonymous' + ``` + + > _Note:_ The `defaultValue` parameter cannot be used alongside `primaryKey` and `references`. If you need to create a column that has a default value and is also a primary and/or foreign key, use the `primaryKey` and `foreignKey` functions mentioned under [Table Constraints](#table-constraints). + + - `collate` adds a `COLLATE` clause to `Expression` (and `Expression`) column definitions with [a collating sequence](https://www.sqlite.org/datatype3.html#collation) defined in the `Collation` enumeration. + + ``` swift + t.column(email, collate: .nocase) + // "email" TEXT NOT NULL COLLATE "NOCASE" + + t.column(name, collate: .rtrim) + // "name" TEXT COLLATE "RTRIM" + ``` + + - `references` adds a `REFERENCES` clause to `Expression` (and `Expression`) column definitions and accepts a table (`SchemaType`) or namespaced column expression. (See the `foreignKey` function under [Table Constraints](#table-constraints) for non-integer foreign key support.) + + ``` swift + t.column(user_id, references: users, id) + // "user_id" INTEGER REFERENCES "users" ("id") + + + + > _Note:_ The `references` parameter cannot be used alongside `primaryKey` and `defaultValue`. If you need to create a column that has a default value and is also a primary and/or foreign key, use the `primaryKey` and `foreignKey` functions mentioned under [Table Constraints](#table-constraints). + + +### Table Constraints + +Additional constraints may be provided outside the scope of a single column using the following functions. + + - `primaryKey` adds a `PRIMARY KEY` constraint to the table. Unlike [the column constraint, above](#column-constraints), it supports all SQLite types, [ascending and descending orders](#sorting-rows), and composite (multiple column) keys. + + ``` swift + t.primaryKey(email.asc, name) + // PRIMARY KEY("email" ASC, "name") + ``` + + - `unique` adds a `UNIQUE` constraint to the table. Unlike [the column constraint, above](#column-constraints), it supports composite (multiple column) constraints. + + ``` swift + t.unique(local, domain) + // UNIQUE("local", "domain") + ``` + + - `check` adds a `CHECK` constraint to the table in the form of a boolean expression (`Expression`). Boolean expressions can be easily built using [filter operators and functions](#filter-operators-and-functions). (See also the `check` parameter under [Column Constraints](#column-constraints).) + + ``` swift + t.check(balance >= 0) + // CHECK ("balance" >= 0.0) + ``` + + - `foreignKey` adds a `FOREIGN KEY` constraint to the table. Unlike [the `references` constraint, above](#column-constraints), it supports all SQLite types, both [`ON UPDATE` and `ON DELETE` actions](https://www.sqlite.org/foreignkeys.html#fk_actions), and composite (multiple column) keys. + + ``` swift + t.foreignKey(user_id, references: users, id, delete: .setNull) + // FOREIGN KEY("user_id") REFERENCES "users"("id") ON DELETE SET NULL + ``` + + + + +## Inserting Rows + +We can insert rows into a table by calling a [query’s](#queries) `insert` function with a list of [setters](#setters)—typically [typed column expressions](#expressions) and values (which can also be expressions)—each joined by the `<-` operator. + +``` swift +try db.run(users.insert(email <- "alice@mac.com", name <- "Alice")) +// INSERT INTO "users" ("email", "name") VALUES ('alice@mac.com', 'Alice') + +try db.run(users.insert(or: .replace, email <- "alice@mac.com", name <- "Alice B.")) +// INSERT OR REPLACE INTO "users" ("email", "name") VALUES ('alice@mac.com', 'Alice B.') +``` + +The `insert` function, when run successfully, returns an `Int64` representing the inserted row’s [`ROWID`][ROWID]. + +``` swift +do { + let rowid = try db.run(users.insert(email <- "alice@mac.com")) + print("inserted id: \(rowid)") +} catch { + print("insertion failed: \(error)") +} +``` + +The [`update`](#updating-rows) and [`delete`](#deleting-rows) functions follow similar patterns. + +> _Note:_ If `insert` is called without any arguments, the statement will run with a `DEFAULT VALUES` clause. The table must not have any constraints that aren’t fulfilled by default values. +> +> ``` swift +> try db.run(timestamps.insert()) +> // INSERT INTO "timestamps" DEFAULT VALUES +> ``` + + +### Setters + +SQLite.swift typically uses the `<-` operator to set values during [inserts](#inserting-rows) and [updates](#updating-rows). + +``` swift +try db.run(counter.update(count <- 0)) +// UPDATE "counters" SET "count" = 0 WHERE ("id" = 1) +``` + +There are also a number of convenience setters that take the existing value into account using native Swift operators. + +For example, to atomically increment a column, we can use `++`: + +``` swift +try db.run(counter.update(count++)) // equivalent to `counter.update(count -> count + 1)` +// UPDATE "counters" SET "count" = "count" + 1 WHERE ("id" = 1) +``` + +To take an amount and “move” it via transaction, we can use `-=` and `+=`: + +``` swift +let amount = 100.0 +try db.transaction { + try db.run(alice.update(balance -= amount)) + try db.run(betty.update(balance += amount)) +} +// BEGIN DEFERRED TRANSACTION +// UPDATE "users" SET "balance" = "balance" - 100.0 WHERE ("id" = 1) +// UPDATE "users" SET "balance" = "balance" + 100.0 WHERE ("id" = 2) +// COMMIT TRANSACTION +``` + + +###### Infix Setters + +| Operator | Types | +| -------- | ------------------ | +| `<-` | `Value -> Value` | +| `+=` | `Number -> Number` | +| `-=` | `Number -> Number` | +| `*=` | `Number -> Number` | +| `/=` | `Number -> Number` | +| `%=` | `Int -> Int` | +| `<<=` | `Int -> Int` | +| `>>=` | `Int -> Int` | +| `&=` | `Int -> Int` | +| `||=` | `Int -> Int` | +| `^=` | `Int -> Int` | +| `+=` | `String -> String` | + + +###### Postfix Setters + +| Operator | Types | +| -------- | ------------ | +| `++` | `Int -> Int` | +| `--` | `Int -> Int` | + + +## Selecting Rows + +[Query structures](#queries) are `SELECT` statements waiting to happen. They execute via [iteration](#iterating-and-accessing-values) and [other means](#plucking-values) of sequence access. + + +### Iterating and Accessing Values + +Prepared [queries](#queries) execute lazily upon iteration. Each row is returned as a `Row` object, which can be subscripted with a [column expression](#expressions) matching one of the columns returned. + +``` swift +for user in try db.prepare(users) { + print("id: \(user[id]), email: \(user[email]), name: \(user[name])") + // id: 1, email: alice@mac.com, name: Optional("Alice") +} +// SELECT * FROM "users" +``` + +`Expression` column values are _automatically unwrapped_ (we’ve made a promise to the compiler that they’ll never be `NULL`), while `Expression` values remain wrapped. + + +### Plucking Rows + +We can pluck the first row by passing a query to the `pluck` function on a database connection. + +``` swift +if let user = try db.pluck(users) { /* ... */ } // Row +// SELECT * FROM "users" LIMIT 1 +``` + +To collect all rows into an array, we can simply wrap the sequence (though this is not always the most memory-efficient idea). + +``` swift +let all = Array(try db.prepare(users)) +// SELECT * FROM "users" +``` + + +### Building Complex Queries + +[Queries](#queries) have a number of chainable functions that can be used (with [expressions](#expressions)) to add and modify [a number of clauses](https://www.sqlite.org/lang_select.html) to the underlying statement. + +``` swift +let query = users.select(email) // SELECT "email" FROM "users" + .filter(name != nil) // WHERE "name" IS NOT NULL + .order(email.desc, name) // ORDER BY "email" DESC, "name" + .limit(5, offset: 1) // LIMIT 5 OFFSET 1 +``` + + +#### Selecting Columns + +By default, [queries](#queries) select every column of the result set (using `SELECT *`). We can use the `select` function with a list of [expressions](#expressions) to return specific columns instead. + +``` swift +for user in try db.prepare(users.select(id, email)) { + print("id: \(user[id]), email: \(user[email])") + // id: 1, email: alice@mac.com +} +// SELECT "id", "email" FROM "users" +``` + +We can access the results of more complex expressions by holding onto a reference of the expression itself. + +``` swift +let sentence = name + " is " + cast(age) as Expression + " years old!" +for user in users.select(sentence) { + print(user[sentence]) + // Optional("Alice is 30 years old!") +} +// SELECT ((("name" || ' is ') || CAST ("age" AS TEXT)) || ' years old!') FROM "users" +``` + + +#### Joining Other Tables + +We can join tables using a [query’s](#queries) `join` function. + +``` swift +users.join(posts, on: user_id == users[id]) +// SELECT * FROM "users" INNER JOIN "posts" ON ("user_id" = "users"."id") +``` + +The `join` function takes a [query](#queries) object (for the table being joined on), a join condition (`on`), and is prefixed with an optional join type (default: `.inner`). Join conditions can be built using [filter operators and functions](#filter-operators-and-functions), generally require [namespacing](#column-namespacing), and sometimes require [aliasing](#table-aliasing). + + +##### Column Namespacing + +When joining tables, column names can become ambiguous. _E.g._, both tables may have an `id` column. + +``` swift +let query = users.join(posts, on: user_id == id) +// assertion failure: ambiguous column 'id' +``` + +We can disambiguate by namespacing `id`. + +``` swift +let query = users.join(posts, on: user_id == users[id]) +// SELECT * FROM "users" INNER JOIN "posts" ON ("user_id" = "users"."id") +``` + +Namespacing is achieved by subscripting a [query](#queries) with a [column expression](#expressions) (_e.g._, `users[id]` above becomes `users.id`). + +> _Note:_ We can namespace all of a table’s columns using `*`. +> +> ``` swift +> let query = users.select(users[*]) +> // SELECT "users".* FROM "users" +> ``` + + +##### Table Aliasing + +Occasionally, we need to join a table to itself, in which case we must alias the table with another name. We can achieve this using the [query’s](#queries) `alias` function. + +``` swift +let managers = users.alias("managers") + +let query = users.join(managers, on: managers[id] == users[managerId]) +// SELECT * FROM "users" +// INNER JOIN ("users") AS "managers" ON ("managers"."id" = "users"."manager_id") +``` + +If query results can have ambiguous column names, row values should be accessed with namespaced [column expressions](#expressions). In the above case, `SELECT *` immediately namespaces all columns of the result set. + +``` swift +let user = try db.pluck(query) +user[id] // fatal error: ambiguous column 'id' + // (please disambiguate: ["users"."id", "managers"."id"]) + +user[users[id]] // returns "users"."id" +user[managers[id]] // returns "managers"."id" +``` + + +#### Filtering Rows + +SQLite.swift filters rows using a [query’s](#queries) `filter` function with a boolean [expression](#expressions) (`Expression`). + +``` swift +users.filter(id == 1) +// SELECT * FROM "users" WHERE ("id" = 1) + +users.filter([1, 2, 3, 4, 5].contains(id)) +// SELECT * FROM "users" WHERE ("id" IN (1, 2, 3, 4, 5)) + +users.filter(email.like("%@mac.com")) +// SELECT * FROM "users" WHERE ("email" LIKE '%@mac.com') + +users.filter(verified && name.lowercaseString == "alice") +// SELECT * FROM "users" WHERE ("verified" AND (lower("name") == 'alice')) + +users.filter(verified || balance >= 10_000) +// SELECT * FROM "users" WHERE ("verified" OR ("balance" >= 10000.0)) +``` + +We can build our own boolean expressions by using one of the many [filter operators and functions](#filter-operators-and-functions). + +Instead of `filter` we can also use the `where` function which is an alias: + +``` swift +users.where(id == 1) +// SELECT * FROM "users" WHERE ("id" = 1) +``` + +##### Filter Operators and Functions + +SQLite.swift defines a number of operators for building filtering predicates. Operators and functions work together in a type-safe manner, so attempting to equate or compare different types will prevent compilation. + + +###### Infix Filter Operators + +| Swift | Types | SQLite | +| ----- | -------------------------------- | -------------- | +| `==` | `Equatable -> Bool` | `=`/`IS`* | +| `!=` | `Equatable -> Bool` | `!=`/`IS NOT`* | +| `>` | `Comparable -> Bool` | `>` | +| `>=` | `Comparable -> Bool` | `>=` | +| `<` | `Comparable -> Bool` | `<` | +| `<=` | `Comparable -> Bool` | `<=` | +| `~=` | `(Interval, Comparable) -> Bool` | `BETWEEN` | +| `&&` | `Bool -> Bool` | `AND` | +| `||` | `Bool -> Bool` | `OR` | + +> *When comparing against `nil`, SQLite.swift will use `IS` and `IS NOT` accordingly. + + +###### Prefix Filter Operators + +| Swift | Types | SQLite | +| ----- | ------------------ | ------ | +| `!` | `Bool -> Bool` | `NOT` | + + +###### Filtering Functions + +| Swift | Types | SQLite | +| ---------- | ----------------------- | ------- | +| `like` | `String -> Bool` | `LIKE` | +| `glob` | `String -> Bool` | `GLOB` | +| `match` | `String -> Bool` | `MATCH` | +| `contains` | `(Array, T) -> Bool` | `IN` | + + + + + +#### Sorting Rows + +We can pre-sort returned rows using the [query’s](#queries) `order` function. + +_E.g._, to return users sorted by `email`, then `name`, in ascending order: + +``` swift +users.order(email, name) +// SELECT * FROM "users" ORDER BY "email", "name" +``` + +The `order` function takes a list of [column expressions](#expressions). + +`Expression` objects have two computed properties to assist sorting: `asc` and `desc`. These properties append the expression with `ASC` and `DESC` to mark ascending and descending order respectively. + +``` swift +users.order(email.desc, name.asc) +// SELECT * FROM "users" ORDER BY "email" DESC, "name" ASC +``` + + +#### Limiting and Paging Results + +We can limit and skip returned rows using a [query’s](#queries) `limit` function (and its optional `offset` parameter). + +``` swift +users.limit(5) +// SELECT * FROM "users" LIMIT 5 + +users.limit(5, offset: 5) +// SELECT * FROM "users" LIMIT 5 OFFSET 5 +``` + + +#### Aggregation + +[Queries](#queries) come with a number of functions that quickly return aggregate scalar values from the table. These mirror the [core aggregate functions](#aggregate-sqlite-functions) and are executed immediately against the query. + +``` swift +let count = try db.scalar(users.count) +// SELECT count(*) FROM "users" +``` + +Filtered queries will appropriately filter aggregate values. + +``` swift +let count = try db.scalar(users.filter(name != nil).count) +// SELECT count(*) FROM "users" WHERE "name" IS NOT NULL +``` + + - `count` as a computed property on a query (see examples above) returns the total number of rows matching the query. + + `count` as a computed property on a column expression returns the total number of rows where that column is not `NULL`. + + ``` swift + let count = try db.scalar(users.select(name.count)) // -> Int + // SELECT count("name") FROM "users" + ``` + + - `max` takes a comparable column expression and returns the largest value if any exists. + + ``` swift + let max = try db.scalar(users.select(id.max)) // -> Int64? + // SELECT max("id") FROM "users" + ``` + + - `min` takes a comparable column expression and returns the smallest value if any exists. + + ``` swift + let min = try db.scalar(users.select(id.min)) // -> Int64? + // SELECT min("id") FROM "users" + ``` + + - `average` takes a numeric column expression and returns the average row value (as a `Double`) if any exists. + + ``` swift + let average = try db.scalar(users.select(balance.average)) // -> Double? + // SELECT avg("balance") FROM "users" + ``` + + - `sum` takes a numeric column expression and returns the sum total of all rows if any exist. + + ``` swift + let sum = try db.scalar(users.select(balance.sum)) // -> Double? + // SELECT sum("balance") FROM "users" + ``` + + - `total`, like `sum`, takes a numeric column expression and returns the sum total of all rows, but in this case always returns a `Double`, and returns `0.0` for an empty query. + + ``` swift + let total = try db.scalar(users.select(balance.total)) // -> Double + // SELECT total("balance") FROM "users" + ``` + +> _Note:_ Expressions can be prefixed with a `DISTINCT` clause by calling the `distinct` computed property. +> +> ``` swift +> let count = try db.scalar(users.select(name.distinct.count) // -> Int +> // SELECT count(DISTINCT "name") FROM "users" +> ``` + + +## Updating Rows + +We can update a table’s rows by calling a [query’s](#queries) `update` function with a list of [setters](#setters)—typically [typed column expressions](#expressions) and values (which can also be expressions)—each joined by the `<-` operator. + +When an unscoped query calls `update`, it will update _every_ row in the table. + +``` swift +try db.run(users.update(email <- "alice@me.com")) +// UPDATE "users" SET "email" = 'alice@me.com' +``` + +Be sure to scope `UPDATE` statements beforehand using [the `filter` function](#filtering-rows). + +``` swift +let alice = users.filter(id == 1) +try db.run(alice.update(email <- "alice@me.com")) +// UPDATE "users" SET "email" = 'alice@me.com' WHERE ("id" = 1) +``` + +The `update` function returns an `Int` representing the number of updated rows. + +``` swift +do { + if try db.run(alice.update(email <- "alice@me.com")) > 0 { + print("updated alice") + } else { + print("alice not found") + } +} catch { + print("update failed: \(error)") +} +``` + + +## Deleting Rows + +We can delete rows from a table by calling a [query’s](#queries) `delete` function. + +When an unscoped query calls `delete`, it will delete _every_ row in the table. + +``` swift +try db.run(users.delete()) +// DELETE FROM "users" +``` + +Be sure to scope `DELETE` statements beforehand using [the `filter` function](#filtering-rows). + +``` swift +let alice = users.filter(id == 1) +try db.run(alice.delete()) +// DELETE FROM "users" WHERE ("id" = 1) +``` + +The `delete` function returns an `Int` representing the number of deleted rows. + +``` swift +do { + if try db.run(alice.delete()) > 0 { + print("deleted alice") + } else { + print("alice not found") + } +} catch { + print("delete failed: \(error)") +} +``` + + +## Transactions and Savepoints + +Using the `transaction` and `savepoint` functions, we can run a series of statements in a transaction. If a single statement fails or the block throws an error, the changes will be rolled back. + +``` swift +try db.transaction { + let rowid = try db.run(users.insert(email <- "betty@icloud.com")) + try db.run(users.insert(email <- "cathy@icloud.com", managerId <- rowid)) +} +// BEGIN DEFERRED TRANSACTION +// INSERT INTO "users" ("email") VALUES ('betty@icloud.com') +// INSERT INTO "users" ("email", "manager_id") VALUES ('cathy@icloud.com', 2) +// COMMIT TRANSACTION +``` + +> _Note:_ Transactions run in a serial queue. + + +## Altering the Schema + +SQLite.swift comes with several functions (in addition to `Table.create`) for altering a database schema in a type-safe manner. + + +### Renaming Tables + +We can build an `ALTER TABLE … RENAME TO` statement by calling the `rename` function on a `Table` or `VirtualTable`. + +``` swift +try db.run(users.rename(Table("users_old")) +// ALTER TABLE "users" RENAME TO "users_old" +``` + + +### Adding Columns + +We can add columns to a table by calling `addColumn` function on a `Table`. SQLite.swift enforces [the same limited subset](https://www.sqlite.org/lang_altertable.html) of `ALTER TABLE` that SQLite supports. + +``` swift +try db.run(users.addColumn(suffix)) +// ALTER TABLE "users" ADD COLUMN "suffix" TEXT +``` + + +#### Added Column Constraints + +The `addColumn` function shares several of the same [`column` function parameters](#column-constraints) used when [creating tables](#creating-a-table). + + - `check` attaches a `CHECK` constraint to a column definition in the form of a boolean expression (`Expression`). (See also the `check` function under [Table Constraints](#table-constraints).) + + ``` swift + try db.run(users.addColumn(suffix, check: ["JR", "SR"].contains(suffix))) + // ALTER TABLE "users" ADD COLUMN "suffix" TEXT CHECK ("suffix" IN ('JR', 'SR')) + ``` + + - `defaultValue` adds a `DEFAULT` clause to a column definition and _only_ accepts a value matching the column’s type. This value is used if none is explicitly provided during [an `INSERT`](#inserting-rows). + + ``` swift + try db.run(users.addColumn(suffix, defaultValue: "SR")) + // ALTER TABLE "users" ADD COLUMN "suffix" TEXT DEFAULT 'SR' + ``` + + > _Note:_ Unlike the [`CREATE TABLE` constraint](#table-constraints), default values may not be expression structures (including `CURRENT_TIME`, `CURRENT_DATE`, or `CURRENT_TIMESTAMP`). + + - `collate` adds a `COLLATE` clause to `Expression` (and `Expression`) column definitions with [a collating sequence](https://www.sqlite.org/datatype3.html#collation) defined in the `Collation` enumeration. + + ``` swift + try db.run(users.addColumn(email, collate: .nocase)) + // ALTER TABLE "users" ADD COLUMN "email" TEXT NOT NULL COLLATE "NOCASE" + + try db.run(users.addColumn(name, collate: .rtrim)) + // ALTER TABLE "users" ADD COLUMN "name" TEXT COLLATE "RTRIM" + ``` + + - `references` adds a `REFERENCES` clause to `Int64` (and `Int64?`) column definitions and accepts a table or namespaced column expression. (See the `foreignKey` function under [Table Constraints](#table-constraints) for non-integer foreign key support.) + + ``` swift + try db.run(posts.addColumn(userId, references: users, id) + // ALTER TABLE "posts" ADD COLUMN "user_id" INTEGER REFERENCES "users" ("id") + ``` + + +### Indexes + + +#### Creating Indexes + +We can build [`CREATE INDEX` statements](https://www.sqlite.org/lang_createindex.html) by calling the `createIndex` function on a `SchemaType`. + +``` swift +try db.run(users.createIndex(email)) +// CREATE INDEX "index_users_on_email" ON "users" ("email") +``` + +The index name is generated automatically based on the table and column names. + +The `createIndex` function has a couple default parameters we can override. + + - `unique` adds a `UNIQUE` constraint to the index. Default: `false`. + + ``` swift + try db.run(users.createIndex(email, unique: true)) + // CREATE UNIQUE INDEX "index_users_on_email" ON "users" ("email") + ``` + + - `ifNotExists` adds an `IF NOT EXISTS` clause to the `CREATE TABLE` statement (which will bail out gracefully if the table already exists). Default: `false`. + + ``` swift + try db.run(users.createIndex(email, ifNotExists: true)) + // CREATE INDEX IF NOT EXISTS "index_users_on_email" ON "users" ("email") + ``` + + +#### Dropping Indexes + +We can build [`DROP INDEX` statements](https://www.sqlite.org/lang_dropindex.html) by calling the `dropIndex` function on a `SchemaType`. + +``` swift +try db.run(users.dropIndex(email)) +// DROP INDEX "index_users_on_email" +``` + +The `dropIndex` function has one additional parameter, `ifExists`, which (when `true`) adds an `IF EXISTS` clause to the statement. + +``` swift +try db.run(users.dropIndex(email, ifExists: true)) +// DROP INDEX IF EXISTS "index_users_on_email" +``` + + +### Dropping Tables + +We can build [`DROP TABLE` statements](https://www.sqlite.org/lang_droptable.html) by calling the `dropTable` function on a `SchemaType`. + +``` swift +try db.run(users.drop()) +// DROP TABLE "users" +``` + +The `drop` function has one additional parameter, `ifExists`, which (when `true`) adds an `IF EXISTS` clause to the statement. + +``` swift +try db.run(users.drop(ifExists: true)) +// DROP TABLE IF EXISTS "users" +``` + + +### Migrations and Schema Versioning + +You can add a convenience property on `Connection` to query and set the [`PRAGMA user_version`](https://sqlite.org/pragma.html#pragma_user_version). + +This is a great way to manage your schema’s version over migrations. + +``` swift +extension Connection { + public var userVersion: Int32 { + get { return Int32(try! scalar("PRAGMA user_version") as! Int64)} + set { try! run("PRAGMA user_version = \(newValue)") } + } +} +``` + +Then you can conditionally run your migrations along the lines of: + +```swift +if db.userVersion == 0 { + // handle first migration + db.userVersion = 1 +} +if db.userVersion == 1 { + // handle second migration + db.userVersion = 2 +} +``` + +For more complex migration requirements check out the schema management system +[SQLiteMigrationManager.swift][]. + +## Custom Types + +SQLite.swift supports serializing and deserializing any custom type as long as it conforms to the `Value` protocol. + +> ``` swift +> protocol Value { +> typealias Datatype: Binding +> class var declaredDatatype: String { get } +> class func fromDatatypeValue(datatypeValue: Datatype) -> Self +> var datatypeValue: Datatype { get } +> } +> ``` + +The `Datatype` must be one of the basic Swift types that values are bridged through before serialization and deserialization (see [Building Type-Safe SQL](#building-type-safe-sql) for a list of types). + +> _Note:_ `Binding` is a protocol that SQLite.swift uses internally to directly map SQLite types to Swift types. **Do _not_** conform custom types to the `Binding` protocol. + +Once extended, the type can be used [_almost_](#custom-type-caveats) wherever typed expressions can be. + + +### Date-Time Values + +In SQLite, `DATETIME` columns can be treated as strings or numbers, so we can transparently bridge `Date` objects through Swift’s `String` or `Int` types. + +To serialize `Date` objects as `TEXT` values (in ISO 8601), we’ll use `String`. + +``` swift +extension Date: Value { + class var declaredDatatype: String { + return String.declaredDatatype + } + class func fromDatatypeValue(stringValue: String) -> Date { + return SQLDateFormatter.dateFromString(stringValue)! + } + var datatypeValue: String { + return SQLDateFormatter.stringFromDate(self) + } +} + +let SQLDateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS" + formatter.locale = Locale(localeIdentifier: "en_US_POSIX") + formatter.timeZone = TimeZone(forSecondsFromGMT: 0) + return formatter +}() +``` + +We can also treat them as `INTEGER` values using `Int`. + +``` swift +extension Date: Value { + class var declaredDatatype: String { + return Int.declaredDatatype + } + class func fromDatatypeValue(intValue: Int) -> Self { + return self(timeIntervalSince1970: TimeInterval(intValue)) + } + var datatypeValue: Int { + return Int(timeIntervalSince1970) + } +} +``` + +> _Note:_ SQLite’s `CURRENT_DATE`, `CURRENT_TIME`, and `CURRENT_TIMESTAMP` helpers return `TEXT` values. Because of this (and the fact that Unix time is far less human-readable when we’re faced with the raw data), we recommend using the `TEXT` extension. + +Once defined, we can use these types directly in SQLite statements. + +``` swift +let published_at = Expression("published_at") + +let published = posts.filter(published_at <= Date()) +// extension where Datatype == String: +// SELECT * FROM "posts" WHERE "published_at" <= '2014-11-18 12:45:30' +// extension where Datatype == Int: +// SELECT * FROM "posts" WHERE "published_at" <= 1416314730 +``` + + +### Binary Data + +We can bridge any type that can be initialized from and encoded to `Data`. + +``` swift +extension UIImage: Value { + public class var declaredDatatype: String { + return Blob.declaredDatatype + } + public class func fromDatatypeValue(blobValue: Blob) -> UIImage { + return UIImage(data: Data.fromDatatypeValue(blobValue))! + } + public var datatypeValue: Blob { + return UIImagePNGRepresentation(self)!.datatypeValue + } + +} +``` + +> _Note:_ See the [Archives and Serializations Programming Guide](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Archiving/Archiving.html#//apple_ref/doc/uid/10000047i) for more information on encoding and decoding custom types. + + +### Custom Type Caveats + +Swift does _not_ currently support generic subscripting, which means we cannot, by default, subscript Expressions with custom types to: + + 1. **Namespace expressions**. Use the `namespace` function, instead: + + ``` swift + let avatar = Expression("avatar") + users[avatar] // fails to compile + users.namespace(avatar) // "users"."avatar" + ``` + + 2. **Access column data**. Use the `get` function, instead: + + ``` swift + let user = users.first! + user[avatar] // fails to compile + user.get(avatar) // UIImage? + ``` + +We can, of course, write extensions, but they’re rather wordy. + +``` swift +extension Query { + subscript(column: Expression) -> Expression { + return namespace(column) + } + subscript(column: Expression) -> Expression { + return namespace(column) + } +} + +extension Row { + subscript(column: Expression) -> UIImage { + return get(column) + } + subscript(column: Expression) -> UIImage? { + return get(column) + } +} +``` + + +## Other Operators + +In addition to [filter operators](#filtering-infix-operators), SQLite.swift defines a number of operators that can modify expression values with arithmetic, bitwise operations, and concatenation. + + +###### Other Infix Operators + +| Swift | Types | SQLite | +| ----- | -------------------------------- | -------- | +| `+` | `Number -> Number` | `+` | +| `-` | `Number -> Number` | `-` | +| `*` | `Number -> Number` | `*` | +| `/` | `Number -> Number` | `/` | +| `%` | `Int -> Int` | `%` | +| `<<` | `Int -> Int` | `<<` | +| `>>` | `Int -> Int` | `>>` | +| `&` | `Int -> Int` | `&` | +| `|` | `Int -> Int` | `|` | +| `+` | `String -> String` | `||` | + +> _Note:_ SQLite.swift also defines a bitwise XOR operator, `^`, which expands the expression `lhs ^ rhs` to `~(lhs & rhs) & (lhs | rhs)`. + + +###### Other Prefix Operators + +| Swift | Types | SQLite | +| ----- | ------------------ | ------ | +| `~` | `Int -> Int` | `~` | +| `-` | `Number -> Number` | `-` | + + +## Core SQLite Functions + +Many of SQLite’s [core functions](https://www.sqlite.org/lang_corefunc.html) have been surfaced in and type-audited for SQLite.swift. + +> _Note:_ SQLite.swift aliases the `??` operator to the `ifnull` function. +> +> ``` swift +> name ?? email // ifnull("name", "email") +> ``` + + +## Aggregate SQLite Functions + +Most of SQLite’s [aggregate functions](https://www.sqlite.org/lang_aggfunc.html) have been surfaced in and type-audited for SQLite.swift. + + +## Custom SQL Functions + +We can create custom SQL functions by calling `createFunction` on a database connection. + +For example, to give queries access to [`MobileCoreServices.UTTypeConformsTo`](https://developer.apple.com/library/ios/documentation/MobileCoreServices/Reference/UTTypeRef/index.html#//apple_ref/c/func/UTTypeConformsTo), we can write the following: + +``` swift +import MobileCoreServices + +let typeConformsTo: (Expression, String) -> Expression = ( + try db.createFunction("typeConformsTo", deterministic: true) { UTI, conformsToUTI in + return UTTypeConformsTo(UTI, conformsToUTI) + } +) +``` + +> _Note:_ The optional `deterministic` parameter is an optimization that causes the function to be created with [`SQLITE_DETERMINISTIC`](https://www.sqlite.org/c3ref/create_function.html). + +Note `typeConformsTo`’s signature: + +``` swift +(Expression, String) -> Expression +``` + +Because of this, `createFunction` expects a block with the following signature: + +``` swift +(String, String) -> Bool +``` + +Once assigned, the closure can be called wherever boolean expressions are accepted. + +``` swift +let attachments = Table("attachments") +let UTI = Expression("UTI") + +let images = attachments.filter(typeConformsTo(UTI, kUTTypeImage)) +// SELECT * FROM "attachments" WHERE "typeConformsTo"("UTI", 'public.image') +``` + +> _Note:_ The return type of a function must be [a core SQL type](#building-type-safe-sql) or [conform to `Value`](#custom-types). + +We can create loosely-typed functions by handling an array of raw arguments, instead. + +``` swift +db.createFunction("typeConformsTo", deterministic: true) { args in + guard let UTI = args[0] as? String, conformsToUTI = args[1] as? String else { return nil } + return UTTypeConformsTo(UTI, conformsToUTI) +} +``` + +Creating a loosely-typed function cannot return a closure and instead must be wrapped manually or executed [using raw SQL](#executing-arbitrary-sql). + +``` swift +let stmt = try db.prepare("SELECT * FROM attachments WHERE typeConformsTo(UTI, ?)") +for row in stmt.bind(kUTTypeImage) { /* ... */ } +``` + + +## Custom Collations + +We can create custom collating sequences by calling `createCollation` on a database connection. + +``` swift +try db.createCollation("NODIACRITIC") { lhs, rhs in + return lhs.compare(rhs, options: .diacriticInsensitiveSearch) +} +``` + +We can reference a custom collation using the `Custom` member of the `Collation` enumeration. + +``` swift +restaurants.order(collate(.custom("NODIACRITIC"), name)) +// SELECT * FROM "restaurants" ORDER BY "name" COLLATE "NODIACRITIC" +``` + + +## Full-text Search + +We can create a virtual table using the [FTS4 module](http://www.sqlite.org/fts3.html) by calling `create` on a `VirtualTable`. + +``` swift +let emails = VirtualTable("emails") +let subject = Expression("subject") +let body = Expression("body") + +try db.run(emails.create(.FTS4(subject, body))) +// CREATE VIRTUAL TABLE "emails" USING fts4("subject", "body") +``` + +We can specify a [tokenizer](http://www.sqlite.org/fts3.html#tokenizer) using the `tokenize` parameter. + +``` swift +try db.run(emails.create(.FTS4([subject, body], tokenize: .Porter))) +// CREATE VIRTUAL TABLE "emails" USING fts4("subject", "body", tokenize=porter) +``` + +We can set the full range of parameters by creating a `FTS4Config` object. + +``` swift +let emails = VirtualTable("emails") +let subject = Expression("subject") +let body = Expression("body") +let config = FTS4Config() + .column(subject) + .column(body, [.unindexed]) + .languageId("lid") + .order(.desc) + +try db.run(emails.create(.FTS4(config)) +// CREATE VIRTUAL TABLE "emails" USING fts4("subject", "body", notindexed="body", languageid="lid", order="desc") +``` + +Once we insert a few rows, we can search using the `match` function, which takes a table or column as its first argument and a query string as its second. + +``` swift +try db.run(emails.insert( + subject <- "Just Checking In", + body <- "Hey, I was just wondering...did you get my last email?" +)) + +let wonderfulEmails = emails.match("wonder*") +// SELECT * FROM "emails" WHERE "emails" MATCH 'wonder*' + +let replies = emails.filter(subject.match("Re:*")) +// SELECT * FROM "emails" WHERE "subject" MATCH 'Re:*' +``` + +### FTS5 + +When linking against a version of SQLite with [FTS5](http://www.sqlite.org/fts5.html) enabled we can create the virtual table +in a similar fashion. + +```swift +let emails = VirtualTable("emails") +let subject = Expression("subject") +let body = Expression("body") +let config = FTS5Config() + .column(subject) + .column(body, [.unindexed]) + +try db.run(emails.create(.FTS5(config)) +// CREATE VIRTUAL TABLE "emails" USING fts5("subject", "body" UNINDEXED) + +// Note that FTS5 uses a different syntax to select columns, so we need to rewrite +// the last FTS4 query above as: +let replies = emails.filter(emails.match("subject:\"Re:\"*)) +// SELECT * FROM "emails" WHERE "emails" MATCH 'subject:"Re:"*' + +// https://www.sqlite.org/fts5.html#_changes_to_select_statements_ +``` + +## Executing Arbitrary SQL + +Though we recommend you stick with SQLite.swift’s [type-safe system](#building-type-safe-sql) whenever possible, it is possible to simply and safely prepare and execute raw SQL statements via a `Database` connection using the following functions. + + - `execute` runs an arbitrary number of SQL statements as a convenience. + + ``` swift + try db.execute( + "BEGIN TRANSACTION;" + + "CREATE TABLE users (" + + "id INTEGER PRIMARY KEY NOT NULL," + + "email TEXT UNIQUE NOT NULL," + + "name TEXT" + + ");" + + "CREATE TABLE posts (" + + "id INTEGER PRIMARY KEY NOT NULL," + + "title TEXT NOT NULL," + + "body TEXT NOT NULL," + + "published_at DATETIME" + + ");" + + "PRAGMA user_version = 1;" + + "COMMIT TRANSACTION;" + ) + ``` + + - `prepare` prepares a single `Statement` object from a SQL string, optionally binds values to it (using the statement’s `bind` function), and returns the statement for deferred execution. + + ``` swift + let stmt = try db.prepare("INSERT INTO users (email) VALUES (?)") + ``` + + Once prepared, statements may be executed using `run`, binding any unbound parameters. + + ``` swift + try stmt.run("alice@mac.com") + db.changes // -> {Some 1} + ``` + + Statements with results may be iterated over, using the columnNames if useful. + + ``` swift + let stmt = try db.prepare("SELECT id, email FROM users") + for row in stmt { + for (index, name) in stmt.columnNames.enumerate() { + print ("\(name)=\(row[index]!)") + // id: Optional(1), email: Optional("alice@mac.com") + } + } + ``` + + - `run` prepares a single `Statement` object from a SQL string, optionally binds values to it (using the statement’s `bind` function), executes, and returns the statement. + + ``` swift + try db.run("INSERT INTO users (email) VALUES (?)", "alice@mac.com") + ``` + + - `scalar` prepares a single `Statement` object from a SQL string, optionally binds values to it (using the statement’s `bind` function), executes, and returns the first value of the first row. + + ``` swift + let count = try db.scalar("SELECT count(*) FROM users") as! Int64 + ``` + + Statements also have a `scalar` function, which can optionally re-bind values at execution. + + ``` swift + let stmt = try db.prepare("SELECT count (*) FROM users") + let count = try stmt.scalar() as! Int64 + ``` + + +## Logging + +We can log SQL using the database’s `trace` function. + +``` swift +#if DEBUG + db.trace(print) +#endif +``` + + +[ROWID]: https://sqlite.org/lang_createtable.html#rowid +[SQLiteMigrationManager.swift]: https://github.com/garriguv/SQLiteMigrationManager.swift diff --git a/Carthage/Checkouts/SQLite.swift/Documentation/Planning.md b/Carthage/Checkouts/SQLite.swift/Documentation/Planning.md new file mode 100644 index 0000000..d814d26 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Documentation/Planning.md @@ -0,0 +1,24 @@ +# SQLite.swift Planning + +This document captures both near term steps (aka Roadmap) and feature requests. +The goal is to add some visibility and guidance for future additions and Pull Requests, as well as to keep the Issues list clear of enhancement requests so that bugs are more visible. + +## Roadmap + +_Lists agreed upon next steps in approximate priority order._ + +## Feature Requests + +_A gathering point for ideas for new features. In general, the corresponding issue will be closed once it is added here, with the assumption that it will be referred to when it comes time to add the corresponding feature._ + +### Features + + * encapsulate ATTACH DATABASE / DETACH DATABASE as methods, per [#30](https://github.com/stephencelis/SQLite.swift/issues/30) + * provide separate threads for update vs read, so updates don't block reads, per [#236](https://github.com/stephencelis/SQLite.swift/issues/236) + * expose triggers, per [#164](https://github.com/stephencelis/SQLite.swift/issues/164) + +## Suspended Feature Requests + +_Features that are not actively being considered, perhaps because of no clean type-safe way to implement them with the current Swift, or bugs, or just general uncertainty._ + + * provide a mechanism for INSERT INTO multiple values, per [#168](https://github.com/stephencelis/SQLite.swift/issues/168) diff --git a/Carthage/Checkouts/SQLite.swift/Documentation/Resources/installation@2x.png b/Carthage/Checkouts/SQLite.swift/Documentation/Resources/installation@2x.png new file mode 100644 index 0000000..6b31f45 Binary files /dev/null and b/Carthage/Checkouts/SQLite.swift/Documentation/Resources/installation@2x.png differ diff --git a/Carthage/Checkouts/SQLite.swift/Documentation/Resources/playground@2x.png b/Carthage/Checkouts/SQLite.swift/Documentation/Resources/playground@2x.png new file mode 100644 index 0000000..32646d6 Binary files /dev/null and b/Carthage/Checkouts/SQLite.swift/Documentation/Resources/playground@2x.png differ diff --git a/Carthage/Checkouts/SQLite.swift/LICENSE.txt b/Carthage/Checkouts/SQLite.swift/LICENSE.txt new file mode 100644 index 0000000..13303c1 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/LICENSE.txt @@ -0,0 +1,21 @@ +(The MIT License) + +Copyright (c) 2014-2015 Stephen Celis () + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/SQLite.swift/Makefile b/Carthage/Checkouts/SQLite.swift/Makefile new file mode 100644 index 0000000..d4f51d5 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Makefile @@ -0,0 +1,60 @@ +BUILD_TOOL = xcodebuild +BUILD_SCHEME = SQLite Mac +IOS_SIMULATOR = iPhone 6s +IOS_VERSION = 9.3 +ifeq ($(BUILD_SCHEME),SQLite iOS) + BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" -destination "platform=iOS Simulator,name=$(IOS_SIMULATOR),OS=$(IOS_VERSION)" +else + BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" +endif + +XCPRETTY := $(shell command -v xcpretty) +SWIFTCOV := $(shell command -v swiftcov) +GCOVR := $(shell command -v gcovr) +TEST_ACTIONS := clean build build-for-testing test-without-building + +default: test + +build: + $(BUILD_TOOL) $(BUILD_ARGUMENTS) + +test: +ifdef XCPRETTY + @set -o pipefail && $(BUILD_TOOL) $(BUILD_ARGUMENTS) $(TEST_ACTIONS) | $(XCPRETTY) -c +else + $(BUILD_TOOL) $(BUILD_ARGUMENTS) $(TEST_ACTIONS) +endif + +coverage: +ifdef SWIFTCOV + $(SWIFTCOV) generate --output coverage \ + $(BUILD_TOOL) $(BUILD_ARGUMENTS) -configuration Release test \ + -- ./SQLite/*.swift +ifdef GCOVR + $(GCOVR) \ + --root . \ + --use-gcov-files \ + --html \ + --html-details \ + --output coverage/index.html \ + --keep +else + @echo gcovr must be installed for HTML output: https://github.com/gcovr/gcovr +endif +else + @echo swiftcov must be installed for coverage: https://github.com/realm/SwiftCov + @exit 1 +endif + +clean: + $(BUILD_TOOL) $(BUILD_ARGUMENTS) clean + rm -r coverage + +repl: + @$(BUILD_TOOL) $(BUILD_ARGUMENTS) -derivedDataPath $(TMPDIR)/SQLite.swift > /dev/null && \ + swift -F '$(TMPDIR)/SQLite.swift/Build/Products/Debug' + +sloc: + @zsh -c "grep -vE '^ *//|^$$' SQLite/*/*.{swift,h,m} | wc -l" + +.PHONY: test coverage clean repl sloc diff --git a/Carthage/Checkouts/SQLite.swift/Package.swift b/Carthage/Checkouts/SQLite.swift/Package.swift new file mode 100644 index 0000000..fc7c5a0 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Package.swift @@ -0,0 +1,17 @@ +import PackageDescription + +let package = Package( + name: "SQLite", + targets: [ + Target( + name: "SQLite", + dependencies: [ + .Target(name: "SQLiteObjc") + ]), + Target(name: "SQLiteObjc") + ], + dependencies: [ + .Package(url: "https://github.com/stephencelis/CSQLite.git", majorVersion: 0) + ], + exclude: ["Tests/CocoaPods", "Tests/Carthage"] +) diff --git a/Carthage/Checkouts/SQLite.swift/README.md b/Carthage/Checkouts/SQLite.swift/README.md new file mode 100644 index 0000000..89917b3 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/README.md @@ -0,0 +1,263 @@ +# SQLite.swift + +[![Build Status][Badge]][Travis] [![CocoaPods Version](https://cocoapod-badges.herokuapp.com/v/SQLite.swift/badge.png)](http://cocoadocs.org/docsets/SQLite.swift) [![Swift](https://img.shields.io/badge/swift-3-orange.svg?style=flat)](https://developer.apple.com/swift/) [![Platform](https://cocoapod-badges.herokuapp.com/p/SQLite.swift/badge.png)](http://cocoadocs.org/docsets/SQLite.swift) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Join the chat at https://gitter.im/stephencelis/SQLite.swift](https://badges.gitter.im/stephencelis/SQLite.swift.svg)](https://gitter.im/stephencelis/SQLite.swift) + +A type-safe, [Swift][]-language layer over [SQLite3][]. + +[SQLite.swift][] provides compile-time confidence in SQL statement +syntax _and_ intent. + +[Badge]: https://img.shields.io/travis/stephencelis/SQLite.swift/master.svg?style=flat +[Travis]: https://travis-ci.org/stephencelis/SQLite.swift +[Swift]: https://developer.apple.com/swift/ +[SQLite3]: http://www.sqlite.org +[SQLite.swift]: https://github.com/stephencelis/SQLite.swift + + +## Features + + - A pure-Swift interface + - A type-safe, optional-aware SQL expression builder + - A flexible, chainable, lazy-executing query layer + - Automatically-typed data access + - A lightweight, uncomplicated query and parameter binding interface + - Developer-friendly error handling and debugging + - [Full-text search][] support + - [Well-documented][See Documentation] + - Extensively tested + - SQLCipher support via CocoaPods + - Active support at [StackOverflow](http://stackoverflow.com/questions/tagged/sqlite.swift), and [Gitter Chat Room](https://gitter.im/stephencelis/SQLite.swift) (_experimental_) + +[Full-text search]: Documentation/Index.md#full-text-search +[See Documentation]: Documentation/Index.md#sqliteswift-documentation + + +## Usage + +``` swift +import SQLite + +let db = try Connection("path/to/db.sqlite3") + +let users = Table("users") +let id = Expression("id") +let name = Expression("name") +let email = Expression("email") + +try db.run(users.create { t in + t.column(id, primaryKey: true) + t.column(name) + t.column(email, unique: true) +}) +// CREATE TABLE "users" ( +// "id" INTEGER PRIMARY KEY NOT NULL, +// "name" TEXT, +// "email" TEXT NOT NULL UNIQUE +// ) + +let insert = users.insert(name <- "Alice", email <- "alice@mac.com") +let rowid = try db.run(insert) +// INSERT INTO "users" ("name", "email") VALUES ('Alice', 'alice@mac.com') + +for user in try db.prepare(users) { + print("id: \(user[id]), name: \(user[name]), email: \(user[email])") + // id: 1, name: Optional("Alice"), email: alice@mac.com +} +// SELECT * FROM "users" + +let alice = users.filter(id == rowid) + +try db.run(alice.update(email <- email.replace("mac.com", with: "me.com"))) +// UPDATE "users" SET "email" = replace("email", 'mac.com', 'me.com') +// WHERE ("id" = 1) + +try db.run(alice.delete()) +// DELETE FROM "users" WHERE ("id" = 1) + +db.scalar(users.count) // 0 +// SELECT count(*) FROM "users" +``` + +SQLite.swift also works as a lightweight, Swift-friendly wrapper over the C +API. + +``` swift +let stmt = try db.prepare("INSERT INTO users (email) VALUES (?)") +for email in ["betty@icloud.com", "cathy@icloud.com"] { + try stmt.run(email) +} + +db.totalChanges // 3 +db.changes // 1 +db.lastInsertRowid // 3 + +for row in try db.prepare("SELECT id, email FROM users") { + print("id: \(row[0]), email: \(row[1])") + // id: Optional(2), email: Optional("betty@icloud.com") + // id: Optional(3), email: Optional("cathy@icloud.com") +} + +db.scalar("SELECT count(*) FROM users") // 2 +``` + +[Read the documentation][See Documentation] or explore more, +interactively, from the Xcode project’s playground. + +![SQLite.playground Screen Shot](Documentation/Resources/playground@2x.png) + +For a more comprehensive example, see [this article](http://masteringswift.blogspot.com/2015/09/create-data-access-layer-with.html) and the [companion repository](https://github.com/hoffmanjon/SQLiteDataAccessLayer2/tree/master). + +## Installation + +> _Note:_ SQLite.swift requires Swift 3 (and [Xcode][] 8) or greater. If you absolutely +> need compatibility with Swift 2.3 you can use the [swift-2.3][] branch or older +> released versions. New development will happen exclusively on the master/Swift 3 branch. + +### Carthage + +[Carthage][] is a simple, decentralized dependency manager for Cocoa. To +install SQLite.swift with Carthage: + + 1. Make sure Carthage is [installed][Carthage Installation]. + + 2. Update your Cartfile to include the following: + + ``` + github "stephencelis/SQLite.swift" ~> 0.11.2 + ``` + + 3. Run `carthage update` and [add the appropriate framework][Carthage Usage]. + + +[Carthage]: https://github.com/Carthage/Carthage +[Carthage Installation]: https://github.com/Carthage/Carthage#installing-carthage +[Carthage Usage]: https://github.com/Carthage/Carthage#adding-frameworks-to-an-application + + +### CocoaPods + +[CocoaPods][] is a dependency manager for Cocoa projects. To install +SQLite.swift with CocoaPods: + + 1. Verify that your copy of Xcode is installed and active in the default location (`/Applications/Xcode.app`). + + ```sh + sudo xcode-select --switch /Applications/Xcode.app + ``` + + 2. Make sure CocoaPods is [installed][CocoaPods Installation]. (SQLite.swift requires version 1.0.0 or greater.) + + ``` sh + # Using the default Ruby install will require you to use sudo when + # installing and updating gems. + [sudo] gem install cocoapods + ``` + + 3. Update your Podfile to include the following: + + ``` ruby + use_frameworks! + + target 'YourAppTargetName' do + pod 'SQLite.swift', '~> 0.11.2' + end + ``` + + 4. Run `pod install --repo-update`. + +[CocoaPods]: https://cocoapods.org +[CocoaPods Installation]: https://guides.cocoapods.org/using/getting-started.html#getting-started + +### Swift Package Manager + +The [Swift Package Manager][] is a tool for managing the distribution of Swift code. + +1. Add the following to your `Package.swift` file: + +```swift +dependencies: [ + .Package(url: "https://github.com/stephencelis/SQLite.swift.git", majorVersion: 0, minor: 11) +] +``` + +[Swift Package Manager]: https://swift.org/package-manager + +### Manual + +To install SQLite.swift as an Xcode sub-project: + + 1. Drag the **SQLite.xcodeproj** file into your own project. + ([Submodule][], clone, or [download][] the project first.) + + ![Installation Screen Shot](Documentation/Resources/installation@2x.png) + + 2. In your target’s **General** tab, click the **+** button under **Linked + Frameworks and Libraries**. + + 3. Select the appropriate **SQLite.framework** for your platform. + + 4. **Add**. + +Some additional steps are required to install the application on an actual device: + + 5. In the **General** tab, click the **+** button under **Embedded Binaries**. + + 6. Select the appropriate **SQLite.framework** for your platform. + + 7. **Add**. + + +[Xcode]: https://developer.apple.com/xcode/downloads/ +[Submodule]: http://git-scm.com/book/en/Git-Tools-Submodules +[download]: https://github.com/stephencelis/SQLite.swift/archive/master.zip + + +## Communication + +[See the planning document] for a roadmap and existing feature requests. + +[Read the contributing guidelines][]. The _TL;DR_ (but please; _R_): + + - Need **help** or have a **general question**? [Ask on Stack + Overflow][] (tag `sqlite.swift`). + - Found a **bug** or have a **feature request**? [Open an issue][]. + - Want to **contribute**? [Submit a pull request][]. + +[See the planning document]: /Documentation/Planning.md +[Read the contributing guidelines]: ./CONTRIBUTING.md#contributing +[Ask on Stack Overflow]: http://stackoverflow.com/questions/tagged/sqlite.swift +[Open an issue]: https://github.com/stephencelis/SQLite.swift/issues/new +[Submit a pull request]: https://github.com/stephencelis/SQLite.swift/fork + + +## Author + + - [Stephen Celis](mailto:stephen@stephencelis.com) + ([@stephencelis](https://twitter.com/stephencelis)) + + +## License + +SQLite.swift is available under the MIT license. See [the LICENSE +file](./LICENSE.txt) for more information. + +## Related + +These projects enhance or use SQLite.swift: + + - [SQLiteMigrationManager.swift](https://github.com/garriguv/SQLiteMigrationManager.swift) (inspired by [FMDBMigrationManager](https://github.com/layerhq/FMDBMigrationManager)) + + +## Alternatives + +Looking for something else? Try another Swift wrapper (or [FMDB][]): + + - [Camembert](https://github.com/remirobert/Camembert) + - [GRDB](https://github.com/groue/GRDB.swift) + - [SQLiteDB](https://github.com/FahimF/SQLiteDB) + - [Squeal](https://github.com/nerdyc/Squeal) + - [SwiftData](https://github.com/ryanfowler/SwiftData) + - [SwiftSQLite](https://github.com/chrismsimpson/SwiftSQLite) + +[FMDB]: https://github.com/ccgus/fmdb +[swift-2.3]: https://github.com/stephencelis/SQLite.swift/tree/swift-2.3 diff --git a/Carthage/Checkouts/SQLite.swift/SQLite.playground/Contents.swift b/Carthage/Checkouts/SQLite.swift/SQLite.playground/Contents.swift new file mode 100644 index 0000000..11e1313 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/SQLite.playground/Contents.swift @@ -0,0 +1,43 @@ +import SQLite + +let db = try! Connection() + +db.trace { print($0) } + +let users = Table("users") + +let id = Expression("id") +let email = Expression("email") +let name = Expression("name") + +try! db.run(users.create { t in + t.column(id, primaryKey: true) + t.column(email, unique: true, check: email.like("%@%")) + t.column(name) +}) + +let rowid = try! db.run(users.insert(email <- "alice@mac.com")) +let alice = users.filter(id == rowid) + +for user in try! db.prepare(users) { + print("id: \(user[id]), email: \(user[email])") +} + +let emails = VirtualTable("emails") + +let subject = Expression("subject") +let body = Expression("body") + +try! db.run(emails.create(.FTS4(subject, body))) + +try! db.run(emails.insert( + subject <- "Hello, world!", + body <- "This is a hello world message." +)) + +let row = try! db.pluck(emails.match("hello")) + +let query = try! db.prepare(emails.match("hello")) +for row in query { + print(row[subject]) +} diff --git a/Carthage/Checkouts/SQLite.swift/SQLite.playground/contents.xcplayground b/Carthage/Checkouts/SQLite.swift/SQLite.playground/contents.xcplayground new file mode 100644 index 0000000..fd676d5 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/SQLite.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Carthage/Checkouts/SQLite.swift/SQLite.swift.podspec b/Carthage/Checkouts/SQLite.swift/SQLite.swift.podspec new file mode 100644 index 0000000..3c61aa1 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/SQLite.swift.podspec @@ -0,0 +1,70 @@ +Pod::Spec.new do |s| + s.name = "SQLite.swift" + s.version = "0.11.2" + s.summary = "A type-safe, Swift-language layer over SQLite3 for iOS and OS X." + + s.description = <<-DESC + SQLite.swift provides compile-time confidence in SQL statement syntax and + intent. + DESC + + s.homepage = "https://github.com/stephencelis/SQLite.swift" + s.license = 'MIT' + s.author = { "Stephen Celis" => "stephen@stephencelis.com" } + s.source = { :git => "https://github.com/stephencelis/SQLite.swift.git", :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/stephencelis' + + s.module_name = 'SQLite' + s.ios.deployment_target = "8.0" + s.tvos.deployment_target = "9.0" + s.osx.deployment_target = "10.9" + s.watchos.deployment_target = "2.0" + s.default_subspec = 'standard' + s.pod_target_xcconfig = { + 'SWIFT_VERSION' => '3.0', + } + + s.subspec 'standard' do |ss| + ss.source_files = 'Sources/{SQLite,SQLiteObjc}/**/*.{c,h,m,swift}' + ss.exclude_files = 'Sources/**/Cipher.swift' + ss.private_header_files = 'Sources/SQLiteObjc/*.h' + + ss.library = 'sqlite3' + ss.preserve_paths = 'CocoaPods/**/*' + ss.pod_target_xcconfig = { + 'SWIFT_INCLUDE_PATHS[sdk=macosx*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/macosx', + 'SWIFT_INCLUDE_PATHS[sdk=macosx10.11]' => '$(SRCROOT)/SQLite.swift/CocoaPods/macosx-10.11', + 'SWIFT_INCLUDE_PATHS[sdk=macosx10.12]' => '$(SRCROOT)/SQLite.swift/CocoaPods/macosx-10.12', + 'SWIFT_INCLUDE_PATHS[sdk=iphoneos*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphoneos', + 'SWIFT_INCLUDE_PATHS[sdk=iphoneos10.0]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphoneos-10.0', + 'SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphonesimulator', + 'SWIFT_INCLUDE_PATHS[sdk=iphonesimulator10.0]' => '$(SRCROOT)/SQLite.swift/CocoaPods/iphonesimulator-10.0', + 'SWIFT_INCLUDE_PATHS[sdk=appletvos*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/appletvos', + 'SWIFT_INCLUDE_PATHS[sdk=appletvsimulator*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/appletvsimulator', + 'SWIFT_INCLUDE_PATHS[sdk=watchos*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/watchos', + 'SWIFT_INCLUDE_PATHS[sdk=watchsimulator*]' => '$(SRCROOT)/SQLite.swift/CocoaPods/watchsimulator' + } + end + + s.subspec 'standalone' do |ss| + ss.source_files = 'Sources/{SQLite,SQLiteObjc}/**/*.{c,h,m,swift}' + ss.exclude_files = 'Sources/**/Cipher.swift' + ss.private_header_files = 'Sources/SQLiteObjc/*.h' + ss.xcconfig = { + 'OTHER_SWIFT_FLAGS' => '$(inherited) -DSQLITE_SWIFT_STANDALONE' + } + + ss.dependency 'sqlite3', '>= 3.14.0' + end + + s.subspec 'SQLCipher' do |ss| + ss.source_files = 'Sources/{SQLite,SQLiteObjc}/**/*.{c,h,m,swift}' + ss.private_header_files = 'Sources/SQLiteObjc/*.h' + ss.xcconfig = { + 'OTHER_SWIFT_FLAGS' => '$(inherited) -DSQLITE_SWIFT_SQLCIPHER', + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SQLITE_HAS_CODEC=1' + } + + ss.dependency 'SQLCipher', '>= 3.4.0' + end +end diff --git a/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/project.pbxproj b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/project.pbxproj new file mode 100644 index 0000000..153295c --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/project.pbxproj @@ -0,0 +1,1513 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 03A65E641C6BB0F60062603F /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E5A1C6BB0F50062603F /* SQLite.framework */; }; + 03A65E711C6BB2CD0062603F /* usr/include/sqlite3.h in Headers */ = {isa = PBXBuildFile; fileRef = EE91808B1C46E34A0038162A /* usr/include/sqlite3.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 03A65E721C6BB2D30062603F /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 03A65E731C6BB2D80062603F /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; }; + 03A65E741C6BB2DA0062603F /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; }; + 03A65E751C6BB2DF0062603F /* SQLite-Bridging.h in Headers */ = {isa = PBXBuildFile; fileRef = EE91808D1C46E5230038162A /* SQLite-Bridging.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 03A65E761C6BB2E60062603F /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; + 03A65E771C6BB2E60062603F /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; }; + 03A65E781C6BB2EA0062603F /* fts3_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AF01C3F06E900AE3E12 /* fts3_tokenizer.h */; }; + 03A65E791C6BB2EF0062603F /* SQLite-Bridging.m in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF11C3F06E900AE3E12 /* SQLite-Bridging.m */; }; + 03A65E7A1C6BB2F70062603F /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; }; + 03A65E7B1C6BB2F70062603F /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; }; + 03A65E7C1C6BB2F70062603F /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; }; + 03A65E7D1C6BB2F70062603F /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; }; + 03A65E7E1C6BB2FB0062603F /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; }; + 03A65E7F1C6BB2FB0062603F /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; }; + 03A65E801C6BB2FB0062603F /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; }; + 03A65E811C6BB2FB0062603F /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; }; + 03A65E821C6BB2FB0062603F /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; }; + 03A65E831C6BB2FB0062603F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; }; + 03A65E841C6BB2FB0062603F /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; }; + 03A65E851C6BB2FB0062603F /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; }; + 03A65E861C6BB2FB0062603F /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; }; + 03A65E871C6BB3030062603F /* AggregateFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1A1C3F137700AE3E12 /* AggregateFunctionsTests.swift */; }; + 03A65E881C6BB3030062603F /* BlobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1B1C3F137700AE3E12 /* BlobTests.swift */; }; + 03A65E891C6BB3030062603F /* ConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1D1C3F137700AE3E12 /* ConnectionTests.swift */; }; + 03A65E8A1C6BB3030062603F /* CoreFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1E1C3F137700AE3E12 /* CoreFunctionsTests.swift */; }; + 03A65E8B1C6BB3030062603F /* CustomFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1F1C3F137700AE3E12 /* CustomFunctionsTests.swift */; }; + 03A65E8C1C6BB3030062603F /* ExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B201C3F137700AE3E12 /* ExpressionTests.swift */; }; + 03A65E8D1C6BB3030062603F /* FTS4Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B211C3F137700AE3E12 /* FTS4Tests.swift */; }; + 03A65E8E1C6BB3030062603F /* OperatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2A1C3F141E00AE3E12 /* OperatorsTests.swift */; }; + 03A65E8F1C6BB3030062603F /* QueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2B1C3F141E00AE3E12 /* QueryTests.swift */; }; + 03A65E901C6BB3030062603F /* RTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2C1C3F141E00AE3E12 /* RTreeTests.swift */; }; + 03A65E911C6BB3030062603F /* SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2D1C3F141E00AE3E12 /* SchemaTests.swift */; }; + 03A65E921C6BB3030062603F /* SetterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B181C3F134A00AE3E12 /* SetterTests.swift */; }; + 03A65E931C6BB3030062603F /* StatementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B321C3F142E00AE3E12 /* StatementTests.swift */; }; + 03A65E941C6BB3030062603F /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B331C3F142E00AE3E12 /* ValueTests.swift */; }; + 03A65E951C6BB3030062603F /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; }; + 03A65E971C6BB3210062603F /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E961C6BB3210062603F /* libsqlite3.tbd */; }; + 19A1709C3E7A406E62293B2A /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B93B48B5560E6E51791 /* Fixtures.swift */; }; + 19A1717B10CC941ACB5533D6 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; }; + 19A171E6FA242F72A308C594 /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; }; + 19A171F12AB8B07F2FD7201A /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; }; + 19A17254FBA7894891F7297B /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; }; + 19A17408007B182F884E3A53 /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B93B48B5560E6E51791 /* Fixtures.swift */; }; + 19A174D78559CD30679BCCCB /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; }; + 19A1750CEE9B05267995CF3D /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; }; + 19A175DFF47B84757E547C62 /* fixtures in Resources */ = {isa = PBXBuildFile; fileRef = 19A17E2695737FAB5D6086E3 /* fixtures */; }; + 19A177CC33F2E6A24AF90B02 /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17399EA9E61235D5D77BF /* CipherTests.swift */; }; + 19A178072B371489E6A1E839 /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; }; + 19A17835FD5886FDC5A3228F /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; }; + 19A179A0C45377CB09BB358C /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17399EA9E61235D5D77BF /* CipherTests.swift */; }; + 19A179CCF9671E345E5A9811 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; }; + 19A179E76EA6207669B60C1B /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; }; + 19A17C4B951CB054EE48AB1C /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17399EA9E61235D5D77BF /* CipherTests.swift */; }; + 19A17E04C4C0956715C5676A /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; }; + 19A17EC0D68BA8C03288ADF7 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; }; + 19A17F3E1F7ACA33BD43E138 /* fixtures in Resources */ = {isa = PBXBuildFile; fileRef = 19A17E2695737FAB5D6086E3 /* fixtures */; }; + 19A17F60B685636D1F83C2DD /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B93B48B5560E6E51791 /* Fixtures.swift */; }; + 19A17FB80B94E882050AA908 /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; }; + 19A17FDA323BAFDEC627E76F /* fixtures in Resources */ = {isa = PBXBuildFile; fileRef = 19A17E2695737FAB5D6086E3 /* fixtures */; }; + 3D67B3E61DB2469200A4F4C6 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D67B3E51DB2469200A4F4C6 /* libsqlite3.tbd */; }; + 3D67B3E71DB246BA00A4F4C6 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; + 3D67B3E81DB246BA00A4F4C6 /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; }; + 3D67B3E91DB246D100A4F4C6 /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; }; + 3D67B3EA1DB246D100A4F4C6 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; }; + 3D67B3EB1DB246D100A4F4C6 /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; }; + 3D67B3EC1DB246D100A4F4C6 /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; }; + 3D67B3ED1DB246D100A4F4C6 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; }; + 3D67B3EE1DB246D100A4F4C6 /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; }; + 3D67B3EF1DB246D100A4F4C6 /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; }; + 3D67B3F01DB246D100A4F4C6 /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; }; + 3D67B3F11DB246D100A4F4C6 /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; }; + 3D67B3F21DB246D100A4F4C6 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; }; + 3D67B3F31DB246D100A4F4C6 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; }; + 3D67B3F41DB246D100A4F4C6 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; }; + 3D67B3F51DB246D100A4F4C6 /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; }; + 3D67B3F61DB246D100A4F4C6 /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; }; + 3D67B3F71DB246D700A4F4C6 /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; }; + 3D67B3F81DB246D700A4F4C6 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; }; + 3D67B3F91DB246E700A4F4C6 /* SQLite-Bridging.m in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF11C3F06E900AE3E12 /* SQLite-Bridging.m */; }; + 3D67B3FA1DB2470600A4F4C6 /* usr/include/sqlite3.h in Headers */ = {isa = PBXBuildFile; fileRef = EE91808B1C46E34A0038162A /* usr/include/sqlite3.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3D67B3FB1DB2470600A4F4C6 /* SQLite-Bridging.h in Headers */ = {isa = PBXBuildFile; fileRef = EE91808D1C46E5230038162A /* SQLite-Bridging.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3D67B3FC1DB2471B00A4F4C6 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3D67B3FD1DB2472D00A4F4C6 /* fts3_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AF01C3F06E900AE3E12 /* fts3_tokenizer.h */; }; + EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; }; + EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; + EE247B041C3F06E900AE3E12 /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; }; + EE247B051C3F06E900AE3E12 /* fts3_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AF01C3F06E900AE3E12 /* fts3_tokenizer.h */; }; + EE247B061C3F06E900AE3E12 /* SQLite-Bridging.m in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF11C3F06E900AE3E12 /* SQLite-Bridging.m */; }; + EE247B071C3F06E900AE3E12 /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; }; + EE247B081C3F06E900AE3E12 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; }; + EE247B091C3F06E900AE3E12 /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; }; + EE247B0A1C3F06E900AE3E12 /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; }; + EE247B0B1C3F06E900AE3E12 /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; }; + EE247B0C1C3F06E900AE3E12 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; }; + EE247B0D1C3F06E900AE3E12 /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; }; + EE247B0E1C3F06E900AE3E12 /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; }; + EE247B0F1C3F06E900AE3E12 /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; }; + EE247B101C3F06E900AE3E12 /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; }; + EE247B111C3F06E900AE3E12 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; }; + EE247B121C3F06E900AE3E12 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; }; + EE247B131C3F06E900AE3E12 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; }; + EE247B141C3F06E900AE3E12 /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; }; + EE247B151C3F06E900AE3E12 /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; }; + EE247B171C3F127200AE3E12 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; }; + EE247B191C3F134A00AE3E12 /* SetterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B181C3F134A00AE3E12 /* SetterTests.swift */; }; + EE247B221C3F137700AE3E12 /* AggregateFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1A1C3F137700AE3E12 /* AggregateFunctionsTests.swift */; }; + EE247B231C3F137700AE3E12 /* BlobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1B1C3F137700AE3E12 /* BlobTests.swift */; }; + EE247B251C3F137700AE3E12 /* ConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1D1C3F137700AE3E12 /* ConnectionTests.swift */; }; + EE247B261C3F137700AE3E12 /* CoreFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1E1C3F137700AE3E12 /* CoreFunctionsTests.swift */; }; + EE247B271C3F137700AE3E12 /* CustomFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1F1C3F137700AE3E12 /* CustomFunctionsTests.swift */; }; + EE247B281C3F137700AE3E12 /* ExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B201C3F137700AE3E12 /* ExpressionTests.swift */; }; + EE247B291C3F137700AE3E12 /* FTS4Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B211C3F137700AE3E12 /* FTS4Tests.swift */; }; + EE247B2E1C3F141E00AE3E12 /* OperatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2A1C3F141E00AE3E12 /* OperatorsTests.swift */; }; + EE247B2F1C3F141E00AE3E12 /* QueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2B1C3F141E00AE3E12 /* QueryTests.swift */; }; + EE247B301C3F141E00AE3E12 /* RTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2C1C3F141E00AE3E12 /* RTreeTests.swift */; }; + EE247B311C3F141E00AE3E12 /* SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2D1C3F141E00AE3E12 /* SchemaTests.swift */; }; + EE247B341C3F142E00AE3E12 /* StatementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B321C3F142E00AE3E12 /* StatementTests.swift */; }; + EE247B351C3F142E00AE3E12 /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B331C3F142E00AE3E12 /* ValueTests.swift */; }; + EE247B461C3F3ED000AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247B3C1C3F3ED000AE3E12 /* SQLite.framework */; }; + EE247B531C3F3FC700AE3E12 /* AggregateFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1A1C3F137700AE3E12 /* AggregateFunctionsTests.swift */; }; + EE247B541C3F3FC700AE3E12 /* BlobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1B1C3F137700AE3E12 /* BlobTests.swift */; }; + EE247B551C3F3FC700AE3E12 /* ConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1D1C3F137700AE3E12 /* ConnectionTests.swift */; }; + EE247B561C3F3FC700AE3E12 /* CoreFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1E1C3F137700AE3E12 /* CoreFunctionsTests.swift */; }; + EE247B571C3F3FC700AE3E12 /* CustomFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B1F1C3F137700AE3E12 /* CustomFunctionsTests.swift */; }; + EE247B581C3F3FC700AE3E12 /* ExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B201C3F137700AE3E12 /* ExpressionTests.swift */; }; + EE247B591C3F3FC700AE3E12 /* FTS4Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B211C3F137700AE3E12 /* FTS4Tests.swift */; }; + EE247B5A1C3F3FC700AE3E12 /* OperatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2A1C3F141E00AE3E12 /* OperatorsTests.swift */; }; + EE247B5B1C3F3FC700AE3E12 /* QueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2B1C3F141E00AE3E12 /* QueryTests.swift */; }; + EE247B5C1C3F3FC700AE3E12 /* RTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2C1C3F141E00AE3E12 /* RTreeTests.swift */; }; + EE247B5D1C3F3FC700AE3E12 /* SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B2D1C3F141E00AE3E12 /* SchemaTests.swift */; }; + EE247B5E1C3F3FC700AE3E12 /* SetterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B181C3F134A00AE3E12 /* SetterTests.swift */; }; + EE247B5F1C3F3FC700AE3E12 /* StatementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B321C3F142E00AE3E12 /* StatementTests.swift */; }; + EE247B601C3F3FC700AE3E12 /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B331C3F142E00AE3E12 /* ValueTests.swift */; }; + EE247B611C3F3FC700AE3E12 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; }; + EE247B621C3F3FDB00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EE247B631C3F3FDB00AE3E12 /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; }; + EE247B641C3F3FDB00AE3E12 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; }; + EE247B651C3F3FEC00AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; + EE247B661C3F3FEC00AE3E12 /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; }; + EE247B671C3F3FEC00AE3E12 /* fts3_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AF01C3F06E900AE3E12 /* fts3_tokenizer.h */; }; + EE247B681C3F3FEC00AE3E12 /* SQLite-Bridging.m in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF11C3F06E900AE3E12 /* SQLite-Bridging.m */; }; + EE247B691C3F3FEC00AE3E12 /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; }; + EE247B6A1C3F3FEC00AE3E12 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; }; + EE247B6B1C3F3FEC00AE3E12 /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; }; + EE247B6C1C3F3FEC00AE3E12 /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; }; + EE247B6D1C3F3FEC00AE3E12 /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; }; + EE247B6E1C3F3FEC00AE3E12 /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; }; + EE247B6F1C3F3FEC00AE3E12 /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; }; + EE247B701C3F3FEC00AE3E12 /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; }; + EE247B711C3F3FEC00AE3E12 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; }; + EE247B721C3F3FEC00AE3E12 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; }; + EE247B731C3F3FEC00AE3E12 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; }; + EE247B741C3F3FEC00AE3E12 /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; }; + EE247B751C3F3FEC00AE3E12 /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; }; + EE91808C1C46E34A0038162A /* usr/include/sqlite3.h in Headers */ = {isa = PBXBuildFile; fileRef = EE91808B1C46E34A0038162A /* usr/include/sqlite3.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EE91808E1C46E5230038162A /* SQLite-Bridging.h in Headers */ = {isa = PBXBuildFile; fileRef = EE91808D1C46E5230038162A /* SQLite-Bridging.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EE91808F1C46E76D0038162A /* SQLite-Bridging.h in Headers */ = {isa = PBXBuildFile; fileRef = EE91808D1C46E5230038162A /* SQLite-Bridging.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EE9180901C46E8980038162A /* usr/include/sqlite3.h in Headers */ = {isa = PBXBuildFile; fileRef = EE91808B1C46E34A0038162A /* usr/include/sqlite3.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EE9180941C46EA210038162A /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EE9180931C46EA210038162A /* libsqlite3.tbd */; }; + EE9180951C46EBCC0038162A /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EE9180911C46E9D30038162A /* libsqlite3.tbd */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 03A65E651C6BB0F60062603F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = EE247ACA1C3F04ED00AE3E12 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 03A65E591C6BB0F50062603F; + remoteInfo = "SQLite tvOS"; + }; + EE247ADF1C3F04ED00AE3E12 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = EE247ACA1C3F04ED00AE3E12 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EE247AD21C3F04ED00AE3E12; + remoteInfo = SQLite; + }; + EE247B471C3F3ED000AE3E12 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = EE247ACA1C3F04ED00AE3E12 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EE247B3B1C3F3ED000AE3E12; + remoteInfo = SQLite; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 03A65E5A1C6BB0F50062603F /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 03A65E631C6BB0F60062603F /* SQLiteTests tvOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests tvOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 03A65E961C6BB3210062603F /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/usr/lib/libsqlite3.tbd; sourceTree = DEVELOPER_DIR; }; + 19A1721B8984686B9963B45D /* FTS5Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS5Tests.swift; sourceTree = ""; }; + 19A1730E4390C775C25677D1 /* FTS5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS5.swift; sourceTree = ""; }; + 19A17399EA9E61235D5D77BF /* CipherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CipherTests.swift; sourceTree = ""; }; + 19A178A39ACA9667A62663CC /* Cipher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cipher.swift; sourceTree = ""; }; + 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationTests.swift; sourceTree = ""; }; + 19A17B93B48B5560E6E51791 /* Fixtures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fixtures.swift; sourceTree = ""; }; + 19A17E2695737FAB5D6086E3 /* fixtures */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = folder; path = fixtures; sourceTree = ""; }; + 39548A631CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; + 39548A651CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; + 39548A671CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; + 39548A691CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; + 39548A6B1CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; + 39548A6D1CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; + 39548A6F1CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; + 3D67B3E51DB2469200A4F4C6 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS3.0.sdk/usr/lib/libsqlite3.tbd; sourceTree = DEVELOPER_DIR; }; + A121AC451CA35C79005A31D1 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = ""; }; + EE247AD81C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EE247ADD1C3F04ED00AE3E12 /* SQLiteTests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + EE247AE41C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EE247AEE1C3F06E900AE3E12 /* Blob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Blob.swift; sourceTree = ""; }; + EE247AEF1C3F06E900AE3E12 /* Connection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Connection.swift; sourceTree = ""; }; + EE247AF01C3F06E900AE3E12 /* fts3_tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fts3_tokenizer.h; path = ../../SQLiteObjc/fts3_tokenizer.h; sourceTree = ""; }; + EE247AF11C3F06E900AE3E12 /* SQLite-Bridging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "SQLite-Bridging.m"; path = "../../SQLiteObjc/SQLite-Bridging.m"; sourceTree = ""; }; + EE247AF21C3F06E900AE3E12 /* Statement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Statement.swift; sourceTree = ""; }; + EE247AF31C3F06E900AE3E12 /* Value.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Value.swift; sourceTree = ""; }; + EE247AF51C3F06E900AE3E12 /* FTS4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS4.swift; sourceTree = ""; }; + EE247AF61C3F06E900AE3E12 /* RTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RTree.swift; sourceTree = ""; }; + EE247AF71C3F06E900AE3E12 /* Foundation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Foundation.swift; sourceTree = ""; }; + EE247AF81C3F06E900AE3E12 /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; + EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AggregateFunctions.swift; sourceTree = ""; }; + EE247AFB1C3F06E900AE3E12 /* Collation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Collation.swift; sourceTree = ""; }; + EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreFunctions.swift; sourceTree = ""; }; + EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomFunctions.swift; sourceTree = ""; }; + EE247AFE1C3F06E900AE3E12 /* Expression.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Expression.swift; sourceTree = ""; }; + EE247AFF1C3F06E900AE3E12 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; + EE247B001C3F06E900AE3E12 /* Query.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Query.swift; sourceTree = ""; }; + EE247B011C3F06E900AE3E12 /* Schema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Schema.swift; sourceTree = ""; }; + EE247B021C3F06E900AE3E12 /* Setter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Setter.swift; sourceTree = ""; }; + EE247B161C3F127200AE3E12 /* TestHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestHelpers.swift; sourceTree = ""; }; + EE247B181C3F134A00AE3E12 /* SetterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetterTests.swift; sourceTree = ""; }; + EE247B1A1C3F137700AE3E12 /* AggregateFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AggregateFunctionsTests.swift; sourceTree = ""; }; + EE247B1B1C3F137700AE3E12 /* BlobTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlobTests.swift; sourceTree = ""; }; + EE247B1D1C3F137700AE3E12 /* ConnectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionTests.swift; sourceTree = ""; }; + EE247B1E1C3F137700AE3E12 /* CoreFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreFunctionsTests.swift; sourceTree = ""; }; + EE247B1F1C3F137700AE3E12 /* CustomFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomFunctionsTests.swift; sourceTree = ""; }; + EE247B201C3F137700AE3E12 /* ExpressionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpressionTests.swift; sourceTree = ""; }; + EE247B211C3F137700AE3E12 /* FTS4Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS4Tests.swift; sourceTree = ""; }; + EE247B2A1C3F141E00AE3E12 /* OperatorsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperatorsTests.swift; sourceTree = ""; }; + EE247B2B1C3F141E00AE3E12 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = ""; }; + EE247B2C1C3F141E00AE3E12 /* RTreeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RTreeTests.swift; sourceTree = ""; }; + EE247B2D1C3F141E00AE3E12 /* SchemaTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaTests.swift; sourceTree = ""; }; + EE247B321C3F142E00AE3E12 /* StatementTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatementTests.swift; sourceTree = ""; }; + EE247B331C3F142E00AE3E12 /* ValueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValueTests.swift; sourceTree = ""; }; + EE247B3C1C3F3ED000AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EE247B451C3F3ED000AE3E12 /* SQLiteTests Mac.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests Mac.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + EE247B771C3F40D700AE3E12 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + EE247B8B1C3F820300AE3E12 /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = ""; }; + EE247B8C1C3F821200AE3E12 /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .travis.yml; sourceTree = ""; }; + EE247B8D1C3F821200AE3E12 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + EE247B8F1C3F822500AE3E12 /* Index.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Index.md; sourceTree = ""; }; + EE247B911C3F822500AE3E12 /* installation@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "installation@2x.png"; sourceTree = ""; }; + EE247B921C3F822600AE3E12 /* playground@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "playground@2x.png"; sourceTree = ""; }; + EE247B931C3F826100AE3E12 /* SQLite.swift.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = SQLite.swift.podspec; sourceTree = ""; }; + EE91808B1C46E34A0038162A /* usr/include/sqlite3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usr/include/sqlite3.h; sourceTree = SDKROOT; }; + EE91808D1C46E5230038162A /* SQLite-Bridging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SQLite-Bridging.h"; path = "../../SQLiteObjc/include/SQLite-Bridging.h"; sourceTree = ""; }; + EE9180911C46E9D30038162A /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/lib/libsqlite3.tbd; sourceTree = DEVELOPER_DIR; }; + EE9180931C46EA210038162A /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 03A65E561C6BB0F50062603F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 03A65E971C6BB3210062603F /* libsqlite3.tbd in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 03A65E601C6BB0F60062603F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 03A65E641C6BB0F60062603F /* SQLite.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A121AC411CA35C79005A31D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3D67B3E61DB2469200A4F4C6 /* libsqlite3.tbd in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247ACF1C3F04ED00AE3E12 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EE9180941C46EA210038162A /* libsqlite3.tbd in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247ADA1C3F04ED00AE3E12 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247B381C3F3ED000AE3E12 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EE9180951C46EBCC0038162A /* libsqlite3.tbd in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247B421C3F3ED000AE3E12 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EE247B461C3F3ED000AE3E12 /* SQLite.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 39548A611CA63C740003E3B5 /* CocoaPods */ = { + isa = PBXGroup; + children = ( + 39548A621CA63C740003E3B5 /* appletvos */, + 39548A641CA63C740003E3B5 /* appletvsimulator */, + 39548A661CA63C740003E3B5 /* iphoneos */, + 39548A681CA63C740003E3B5 /* iphonesimulator */, + 39548A6A1CA63C740003E3B5 /* macosx */, + 39548A6C1CA63C740003E3B5 /* watchos */, + 39548A6E1CA63C740003E3B5 /* watchsimulator */, + ); + path = CocoaPods; + sourceTree = ""; + }; + 39548A621CA63C740003E3B5 /* appletvos */ = { + isa = PBXGroup; + children = ( + 39548A631CA63C740003E3B5 /* module.modulemap */, + ); + path = appletvos; + sourceTree = ""; + }; + 39548A641CA63C740003E3B5 /* appletvsimulator */ = { + isa = PBXGroup; + children = ( + 39548A651CA63C740003E3B5 /* module.modulemap */, + ); + path = appletvsimulator; + sourceTree = ""; + }; + 39548A661CA63C740003E3B5 /* iphoneos */ = { + isa = PBXGroup; + children = ( + 39548A671CA63C740003E3B5 /* module.modulemap */, + ); + path = iphoneos; + sourceTree = ""; + }; + 39548A681CA63C740003E3B5 /* iphonesimulator */ = { + isa = PBXGroup; + children = ( + 39548A691CA63C740003E3B5 /* module.modulemap */, + ); + path = iphonesimulator; + sourceTree = ""; + }; + 39548A6A1CA63C740003E3B5 /* macosx */ = { + isa = PBXGroup; + children = ( + 39548A6B1CA63C740003E3B5 /* module.modulemap */, + ); + path = macosx; + sourceTree = ""; + }; + 39548A6C1CA63C740003E3B5 /* watchos */ = { + isa = PBXGroup; + children = ( + 39548A6D1CA63C740003E3B5 /* module.modulemap */, + ); + path = watchos; + sourceTree = ""; + }; + 39548A6E1CA63C740003E3B5 /* watchsimulator */ = { + isa = PBXGroup; + children = ( + 39548A6F1CA63C740003E3B5 /* module.modulemap */, + ); + path = watchsimulator; + sourceTree = ""; + }; + 3D67B3E41DB2469200A4F4C6 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3D67B3E51DB2469200A4F4C6 /* libsqlite3.tbd */, + ); + name = Frameworks; + sourceTree = ""; + }; + EE247AC91C3F04ED00AE3E12 = { + isa = PBXGroup; + children = ( + EE247AD51C3F04ED00AE3E12 /* SQLite */, + EE247AE11C3F04ED00AE3E12 /* SQLiteTests */, + EE247B8A1C3F81D000AE3E12 /* Metadata */, + EE247AD41C3F04ED00AE3E12 /* Products */, + 3D67B3E41DB2469200A4F4C6 /* Frameworks */, + ); + indentWidth = 4; + sourceTree = ""; + tabWidth = 4; + }; + EE247AD41C3F04ED00AE3E12 /* Products */ = { + isa = PBXGroup; + children = ( + EE247AD31C3F04ED00AE3E12 /* SQLite.framework */, + EE247ADD1C3F04ED00AE3E12 /* SQLiteTests iOS.xctest */, + EE247B3C1C3F3ED000AE3E12 /* SQLite.framework */, + EE247B451C3F3ED000AE3E12 /* SQLiteTests Mac.xctest */, + 03A65E5A1C6BB0F50062603F /* SQLite.framework */, + 03A65E631C6BB0F60062603F /* SQLiteTests tvOS.xctest */, + A121AC451CA35C79005A31D1 /* SQLite.framework */, + ); + name = Products; + sourceTree = ""; + }; + EE247AD51C3F04ED00AE3E12 /* SQLite */ = { + isa = PBXGroup; + children = ( + EE91808B1C46E34A0038162A /* usr/include/sqlite3.h */, + EE247AD61C3F04ED00AE3E12 /* SQLite.h */, + EE247AF71C3F06E900AE3E12 /* Foundation.swift */, + EE247AF81C3F06E900AE3E12 /* Helpers.swift */, + EE247AD81C3F04ED00AE3E12 /* Info.plist */, + EE247AED1C3F06E900AE3E12 /* Core */, + EE247AF41C3F06E900AE3E12 /* Extensions */, + EE247AF91C3F06E900AE3E12 /* Typed */, + ); + name = SQLite; + path = Sources/SQLite; + sourceTree = ""; + }; + EE247AE11C3F04ED00AE3E12 /* SQLiteTests */ = { + isa = PBXGroup; + children = ( + 19A17E2695737FAB5D6086E3 /* fixtures */, + EE247B1A1C3F137700AE3E12 /* AggregateFunctionsTests.swift */, + EE247B1B1C3F137700AE3E12 /* BlobTests.swift */, + EE247B1D1C3F137700AE3E12 /* ConnectionTests.swift */, + EE247B1E1C3F137700AE3E12 /* CoreFunctionsTests.swift */, + EE247B1F1C3F137700AE3E12 /* CustomFunctionsTests.swift */, + EE247B201C3F137700AE3E12 /* ExpressionTests.swift */, + EE247B211C3F137700AE3E12 /* FTS4Tests.swift */, + EE247B2A1C3F141E00AE3E12 /* OperatorsTests.swift */, + EE247B2B1C3F141E00AE3E12 /* QueryTests.swift */, + EE247B2C1C3F141E00AE3E12 /* RTreeTests.swift */, + EE247B2D1C3F141E00AE3E12 /* SchemaTests.swift */, + EE247B181C3F134A00AE3E12 /* SetterTests.swift */, + EE247B321C3F142E00AE3E12 /* StatementTests.swift */, + EE247B331C3F142E00AE3E12 /* ValueTests.swift */, + EE247B161C3F127200AE3E12 /* TestHelpers.swift */, + EE247AE41C3F04ED00AE3E12 /* Info.plist */, + 19A1721B8984686B9963B45D /* FTS5Tests.swift */, + 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */, + 19A17399EA9E61235D5D77BF /* CipherTests.swift */, + 19A17B93B48B5560E6E51791 /* Fixtures.swift */, + ); + name = SQLiteTests; + path = Tests/SQLiteTests; + sourceTree = ""; + }; + EE247AED1C3F06E900AE3E12 /* Core */ = { + isa = PBXGroup; + children = ( + EE91808D1C46E5230038162A /* SQLite-Bridging.h */, + EE247AEE1C3F06E900AE3E12 /* Blob.swift */, + EE247AEF1C3F06E900AE3E12 /* Connection.swift */, + EE247AF01C3F06E900AE3E12 /* fts3_tokenizer.h */, + EE247AF11C3F06E900AE3E12 /* SQLite-Bridging.m */, + EE247AF21C3F06E900AE3E12 /* Statement.swift */, + EE247AF31C3F06E900AE3E12 /* Value.swift */, + ); + path = Core; + sourceTree = ""; + }; + EE247AF41C3F06E900AE3E12 /* Extensions */ = { + isa = PBXGroup; + children = ( + EE247AF51C3F06E900AE3E12 /* FTS4.swift */, + EE247AF61C3F06E900AE3E12 /* RTree.swift */, + 19A1730E4390C775C25677D1 /* FTS5.swift */, + 19A178A39ACA9667A62663CC /* Cipher.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + EE247AF91C3F06E900AE3E12 /* Typed */ = { + isa = PBXGroup; + children = ( + EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */, + EE247AFB1C3F06E900AE3E12 /* Collation.swift */, + EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */, + EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */, + EE247AFE1C3F06E900AE3E12 /* Expression.swift */, + EE247AFF1C3F06E900AE3E12 /* Operators.swift */, + EE247B001C3F06E900AE3E12 /* Query.swift */, + EE247B011C3F06E900AE3E12 /* Schema.swift */, + EE247B021C3F06E900AE3E12 /* Setter.swift */, + ); + path = Typed; + sourceTree = ""; + }; + EE247B8A1C3F81D000AE3E12 /* Metadata */ = { + isa = PBXGroup; + children = ( + 39548A611CA63C740003E3B5 /* CocoaPods */, + EE247B771C3F40D700AE3E12 /* README.md */, + EE247B8B1C3F820300AE3E12 /* CONTRIBUTING.md */, + EE247B931C3F826100AE3E12 /* SQLite.swift.podspec */, + EE247B8C1C3F821200AE3E12 /* .travis.yml */, + EE247B8D1C3F821200AE3E12 /* Makefile */, + EE9180931C46EA210038162A /* libsqlite3.tbd */, + EE9180911C46E9D30038162A /* libsqlite3.tbd */, + 03A65E961C6BB3210062603F /* libsqlite3.tbd */, + EE247B8E1C3F822500AE3E12 /* Documentation */, + ); + name = Metadata; + sourceTree = ""; + }; + EE247B8E1C3F822500AE3E12 /* Documentation */ = { + isa = PBXGroup; + children = ( + EE247B8F1C3F822500AE3E12 /* Index.md */, + EE247B901C3F822500AE3E12 /* Resources */, + ); + path = Documentation; + sourceTree = ""; + }; + EE247B901C3F822500AE3E12 /* Resources */ = { + isa = PBXGroup; + children = ( + EE247B911C3F822500AE3E12 /* installation@2x.png */, + EE247B921C3F822600AE3E12 /* playground@2x.png */, + ); + path = Resources; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 03A65E571C6BB0F50062603F /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 03A65E781C6BB2EA0062603F /* fts3_tokenizer.h in Headers */, + 03A65E751C6BB2DF0062603F /* SQLite-Bridging.h in Headers */, + 03A65E711C6BB2CD0062603F /* usr/include/sqlite3.h in Headers */, + 03A65E721C6BB2D30062603F /* SQLite.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A121AC421CA35C79005A31D1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3D67B3FA1DB2470600A4F4C6 /* usr/include/sqlite3.h in Headers */, + 3D67B3FB1DB2470600A4F4C6 /* SQLite-Bridging.h in Headers */, + 3D67B3FC1DB2471B00A4F4C6 /* SQLite.h in Headers */, + 3D67B3FD1DB2472D00A4F4C6 /* fts3_tokenizer.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247AD01C3F04ED00AE3E12 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + EE91808E1C46E5230038162A /* SQLite-Bridging.h in Headers */, + EE247B051C3F06E900AE3E12 /* fts3_tokenizer.h in Headers */, + EE91808C1C46E34A0038162A /* usr/include/sqlite3.h in Headers */, + EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247B391C3F3ED000AE3E12 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + EE9180901C46E8980038162A /* usr/include/sqlite3.h in Headers */, + EE247B671C3F3FEC00AE3E12 /* fts3_tokenizer.h in Headers */, + EE247B621C3F3FDB00AE3E12 /* SQLite.h in Headers */, + EE91808F1C46E76D0038162A /* SQLite-Bridging.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 03A65E591C6BB0F50062603F /* SQLite tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 03A65E6F1C6BB0F60062603F /* Build configuration list for PBXNativeTarget "SQLite tvOS" */; + buildPhases = ( + 03A65E551C6BB0F50062603F /* Sources */, + 03A65E561C6BB0F50062603F /* Frameworks */, + 03A65E571C6BB0F50062603F /* Headers */, + 03A65E581C6BB0F50062603F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SQLite tvOS"; + productName = "SQLite tvOS"; + productReference = 03A65E5A1C6BB0F50062603F /* SQLite.framework */; + productType = "com.apple.product-type.framework"; + }; + 03A65E621C6BB0F60062603F /* SQLiteTests tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 03A65E701C6BB0F60062603F /* Build configuration list for PBXNativeTarget "SQLiteTests tvOS" */; + buildPhases = ( + 03A65E5F1C6BB0F60062603F /* Sources */, + 03A65E601C6BB0F60062603F /* Frameworks */, + 03A65E611C6BB0F60062603F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 03A65E661C6BB0F60062603F /* PBXTargetDependency */, + ); + name = "SQLiteTests tvOS"; + productName = "SQLite tvOSTests"; + productReference = 03A65E631C6BB0F60062603F /* SQLiteTests tvOS.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + A121AC441CA35C79005A31D1 /* SQLite watchOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = A121AC4C1CA35C79005A31D1 /* Build configuration list for PBXNativeTarget "SQLite watchOS" */; + buildPhases = ( + A121AC401CA35C79005A31D1 /* Sources */, + A121AC411CA35C79005A31D1 /* Frameworks */, + A121AC421CA35C79005A31D1 /* Headers */, + A121AC431CA35C79005A31D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SQLite watchOS"; + productName = "SQLite watchOS"; + productReference = A121AC451CA35C79005A31D1 /* SQLite.framework */; + productType = "com.apple.product-type.framework"; + }; + EE247AD21C3F04ED00AE3E12 /* SQLite iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = EE247AE71C3F04ED00AE3E12 /* Build configuration list for PBXNativeTarget "SQLite iOS" */; + buildPhases = ( + EE247ACE1C3F04ED00AE3E12 /* Sources */, + EE247ACF1C3F04ED00AE3E12 /* Frameworks */, + EE247AD01C3F04ED00AE3E12 /* Headers */, + EE247AD11C3F04ED00AE3E12 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SQLite iOS"; + productName = SQLite; + productReference = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; + productType = "com.apple.product-type.framework"; + }; + EE247ADC1C3F04ED00AE3E12 /* SQLiteTests iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = EE247AEA1C3F04ED00AE3E12 /* Build configuration list for PBXNativeTarget "SQLiteTests iOS" */; + buildPhases = ( + EE247AD91C3F04ED00AE3E12 /* Sources */, + EE247ADA1C3F04ED00AE3E12 /* Frameworks */, + EE247ADB1C3F04ED00AE3E12 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + EE247AE01C3F04ED00AE3E12 /* PBXTargetDependency */, + ); + name = "SQLiteTests iOS"; + productName = SQLiteTests; + productReference = EE247ADD1C3F04ED00AE3E12 /* SQLiteTests iOS.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + EE247B3B1C3F3ED000AE3E12 /* SQLite Mac */ = { + isa = PBXNativeTarget; + buildConfigurationList = EE247B511C3F3ED000AE3E12 /* Build configuration list for PBXNativeTarget "SQLite Mac" */; + buildPhases = ( + EE247B371C3F3ED000AE3E12 /* Sources */, + EE247B381C3F3ED000AE3E12 /* Frameworks */, + EE247B391C3F3ED000AE3E12 /* Headers */, + EE247B3A1C3F3ED000AE3E12 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SQLite Mac"; + productName = SQLite; + productReference = EE247B3C1C3F3ED000AE3E12 /* SQLite.framework */; + productType = "com.apple.product-type.framework"; + }; + EE247B441C3F3ED000AE3E12 /* SQLiteTests Mac */ = { + isa = PBXNativeTarget; + buildConfigurationList = EE247B521C3F3ED000AE3E12 /* Build configuration list for PBXNativeTarget "SQLiteTests Mac" */; + buildPhases = ( + EE247B411C3F3ED000AE3E12 /* Sources */, + EE247B421C3F3ED000AE3E12 /* Frameworks */, + EE247B431C3F3ED000AE3E12 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + EE247B481C3F3ED000AE3E12 /* PBXTargetDependency */, + ); + name = "SQLiteTests Mac"; + productName = SQLiteTests; + productReference = EE247B451C3F3ED000AE3E12 /* SQLiteTests Mac.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + EE247ACA1C3F04ED00AE3E12 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0800; + TargetAttributes = { + 03A65E591C6BB0F50062603F = { + CreatedOnToolsVersion = 7.2; + }; + 03A65E621C6BB0F60062603F = { + CreatedOnToolsVersion = 7.2; + }; + A121AC441CA35C79005A31D1 = { + CreatedOnToolsVersion = 7.3; + }; + EE247AD21C3F04ED00AE3E12 = { + CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; + }; + EE247ADC1C3F04ED00AE3E12 = { + CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; + }; + EE247B3B1C3F3ED000AE3E12 = { + CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; + }; + EE247B441C3F3ED000AE3E12 = { + CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; + }; + }; + }; + buildConfigurationList = EE247ACD1C3F04ED00AE3E12 /* Build configuration list for PBXProject "SQLite" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = EE247AC91C3F04ED00AE3E12; + productRefGroup = EE247AD41C3F04ED00AE3E12 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + EE247AD21C3F04ED00AE3E12 /* SQLite iOS */, + EE247ADC1C3F04ED00AE3E12 /* SQLiteTests iOS */, + EE247B3B1C3F3ED000AE3E12 /* SQLite Mac */, + EE247B441C3F3ED000AE3E12 /* SQLiteTests Mac */, + 03A65E591C6BB0F50062603F /* SQLite tvOS */, + 03A65E621C6BB0F60062603F /* SQLiteTests tvOS */, + A121AC441CA35C79005A31D1 /* SQLite watchOS */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 03A65E581C6BB0F50062603F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 03A65E611C6BB0F60062603F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 19A17F3E1F7ACA33BD43E138 /* fixtures in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A121AC431CA35C79005A31D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247AD11C3F04ED00AE3E12 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247ADB1C3F04ED00AE3E12 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 19A17FDA323BAFDEC627E76F /* fixtures in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247B3A1C3F3ED000AE3E12 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247B431C3F3ED000AE3E12 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 19A175DFF47B84757E547C62 /* fixtures in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 03A65E551C6BB0F50062603F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 03A65E801C6BB2FB0062603F /* CoreFunctions.swift in Sources */, + 03A65E761C6BB2E60062603F /* Blob.swift in Sources */, + 03A65E7D1C6BB2F70062603F /* RTree.swift in Sources */, + 03A65E791C6BB2EF0062603F /* SQLite-Bridging.m in Sources */, + 03A65E7B1C6BB2F70062603F /* Value.swift in Sources */, + 03A65E821C6BB2FB0062603F /* Expression.swift in Sources */, + 03A65E731C6BB2D80062603F /* Foundation.swift in Sources */, + 03A65E7F1C6BB2FB0062603F /* Collation.swift in Sources */, + 03A65E861C6BB2FB0062603F /* Setter.swift in Sources */, + 03A65E811C6BB2FB0062603F /* CustomFunctions.swift in Sources */, + 03A65E7A1C6BB2F70062603F /* Statement.swift in Sources */, + 03A65E741C6BB2DA0062603F /* Helpers.swift in Sources */, + 03A65E831C6BB2FB0062603F /* Operators.swift in Sources */, + 03A65E851C6BB2FB0062603F /* Schema.swift in Sources */, + 03A65E841C6BB2FB0062603F /* Query.swift in Sources */, + 03A65E7C1C6BB2F70062603F /* FTS4.swift in Sources */, + 03A65E771C6BB2E60062603F /* Connection.swift in Sources */, + 03A65E7E1C6BB2FB0062603F /* AggregateFunctions.swift in Sources */, + 19A17EC0D68BA8C03288ADF7 /* FTS5.swift in Sources */, + 19A179E76EA6207669B60C1B /* Cipher.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 03A65E5F1C6BB0F60062603F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 03A65E881C6BB3030062603F /* BlobTests.swift in Sources */, + 03A65E901C6BB3030062603F /* RTreeTests.swift in Sources */, + 03A65E941C6BB3030062603F /* ValueTests.swift in Sources */, + 03A65E8F1C6BB3030062603F /* QueryTests.swift in Sources */, + 03A65E8B1C6BB3030062603F /* CustomFunctionsTests.swift in Sources */, + 03A65E871C6BB3030062603F /* AggregateFunctionsTests.swift in Sources */, + 03A65E921C6BB3030062603F /* SetterTests.swift in Sources */, + 03A65E891C6BB3030062603F /* ConnectionTests.swift in Sources */, + 03A65E8A1C6BB3030062603F /* CoreFunctionsTests.swift in Sources */, + 03A65E931C6BB3030062603F /* StatementTests.swift in Sources */, + 03A65E911C6BB3030062603F /* SchemaTests.swift in Sources */, + 03A65E8D1C6BB3030062603F /* FTS4Tests.swift in Sources */, + 03A65E8C1C6BB3030062603F /* ExpressionTests.swift in Sources */, + 03A65E8E1C6BB3030062603F /* OperatorsTests.swift in Sources */, + 03A65E951C6BB3030062603F /* TestHelpers.swift in Sources */, + 19A17254FBA7894891F7297B /* FTS5Tests.swift in Sources */, + 19A17E04C4C0956715C5676A /* FoundationTests.swift in Sources */, + 19A179A0C45377CB09BB358C /* CipherTests.swift in Sources */, + 19A17F60B685636D1F83C2DD /* Fixtures.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A121AC401CA35C79005A31D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3D67B3F91DB246E700A4F4C6 /* SQLite-Bridging.m in Sources */, + 3D67B3F71DB246D700A4F4C6 /* Foundation.swift in Sources */, + 3D67B3F81DB246D700A4F4C6 /* Helpers.swift in Sources */, + 3D67B3E91DB246D100A4F4C6 /* Statement.swift in Sources */, + 3D67B3EA1DB246D100A4F4C6 /* Value.swift in Sources */, + 3D67B3EB1DB246D100A4F4C6 /* FTS4.swift in Sources */, + 3D67B3EC1DB246D100A4F4C6 /* RTree.swift in Sources */, + 3D67B3ED1DB246D100A4F4C6 /* FTS5.swift in Sources */, + 3D67B3EE1DB246D100A4F4C6 /* AggregateFunctions.swift in Sources */, + 3D67B3EF1DB246D100A4F4C6 /* Collation.swift in Sources */, + 3D67B3F01DB246D100A4F4C6 /* CoreFunctions.swift in Sources */, + 3D67B3F11DB246D100A4F4C6 /* CustomFunctions.swift in Sources */, + 3D67B3F21DB246D100A4F4C6 /* Expression.swift in Sources */, + 3D67B3F31DB246D100A4F4C6 /* Operators.swift in Sources */, + 3D67B3F41DB246D100A4F4C6 /* Query.swift in Sources */, + 3D67B3F51DB246D100A4F4C6 /* Schema.swift in Sources */, + 3D67B3F61DB246D100A4F4C6 /* Setter.swift in Sources */, + 3D67B3E71DB246BA00A4F4C6 /* Blob.swift in Sources */, + 3D67B3E81DB246BA00A4F4C6 /* Connection.swift in Sources */, + 19A179CCF9671E345E5A9811 /* Cipher.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247ACE1C3F04ED00AE3E12 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EE247B0F1C3F06E900AE3E12 /* CoreFunctions.swift in Sources */, + EE247B0A1C3F06E900AE3E12 /* RTree.swift in Sources */, + EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */, + EE247B0B1C3F06E900AE3E12 /* Foundation.swift in Sources */, + EE247B041C3F06E900AE3E12 /* Connection.swift in Sources */, + EE247B111C3F06E900AE3E12 /* Expression.swift in Sources */, + EE247B0C1C3F06E900AE3E12 /* Helpers.swift in Sources */, + EE247B0E1C3F06E900AE3E12 /* Collation.swift in Sources */, + EE247B151C3F06E900AE3E12 /* Setter.swift in Sources */, + EE247B101C3F06E900AE3E12 /* CustomFunctions.swift in Sources */, + EE247B091C3F06E900AE3E12 /* FTS4.swift in Sources */, + EE247B081C3F06E900AE3E12 /* Value.swift in Sources */, + EE247B121C3F06E900AE3E12 /* Operators.swift in Sources */, + EE247B141C3F06E900AE3E12 /* Schema.swift in Sources */, + EE247B131C3F06E900AE3E12 /* Query.swift in Sources */, + EE247B061C3F06E900AE3E12 /* SQLite-Bridging.m in Sources */, + EE247B071C3F06E900AE3E12 /* Statement.swift in Sources */, + EE247B0D1C3F06E900AE3E12 /* AggregateFunctions.swift in Sources */, + 19A1717B10CC941ACB5533D6 /* FTS5.swift in Sources */, + 19A171F12AB8B07F2FD7201A /* Cipher.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247AD91C3F04ED00AE3E12 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EE247B261C3F137700AE3E12 /* CoreFunctionsTests.swift in Sources */, + EE247B291C3F137700AE3E12 /* FTS4Tests.swift in Sources */, + EE247B191C3F134A00AE3E12 /* SetterTests.swift in Sources */, + EE247B311C3F141E00AE3E12 /* SchemaTests.swift in Sources */, + EE247B171C3F127200AE3E12 /* TestHelpers.swift in Sources */, + EE247B281C3F137700AE3E12 /* ExpressionTests.swift in Sources */, + EE247B271C3F137700AE3E12 /* CustomFunctionsTests.swift in Sources */, + EE247B341C3F142E00AE3E12 /* StatementTests.swift in Sources */, + EE247B301C3F141E00AE3E12 /* RTreeTests.swift in Sources */, + EE247B231C3F137700AE3E12 /* BlobTests.swift in Sources */, + EE247B351C3F142E00AE3E12 /* ValueTests.swift in Sources */, + EE247B2F1C3F141E00AE3E12 /* QueryTests.swift in Sources */, + EE247B221C3F137700AE3E12 /* AggregateFunctionsTests.swift in Sources */, + EE247B2E1C3F141E00AE3E12 /* OperatorsTests.swift in Sources */, + EE247B251C3F137700AE3E12 /* ConnectionTests.swift in Sources */, + 19A171E6FA242F72A308C594 /* FTS5Tests.swift in Sources */, + 19A17FB80B94E882050AA908 /* FoundationTests.swift in Sources */, + 19A177CC33F2E6A24AF90B02 /* CipherTests.swift in Sources */, + 19A17408007B182F884E3A53 /* Fixtures.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247B371C3F3ED000AE3E12 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EE247B6F1C3F3FEC00AE3E12 /* CoreFunctions.swift in Sources */, + EE247B651C3F3FEC00AE3E12 /* Blob.swift in Sources */, + EE247B6C1C3F3FEC00AE3E12 /* RTree.swift in Sources */, + EE247B681C3F3FEC00AE3E12 /* SQLite-Bridging.m in Sources */, + EE247B6A1C3F3FEC00AE3E12 /* Value.swift in Sources */, + EE247B711C3F3FEC00AE3E12 /* Expression.swift in Sources */, + EE247B631C3F3FDB00AE3E12 /* Foundation.swift in Sources */, + EE247B6E1C3F3FEC00AE3E12 /* Collation.swift in Sources */, + EE247B751C3F3FEC00AE3E12 /* Setter.swift in Sources */, + EE247B701C3F3FEC00AE3E12 /* CustomFunctions.swift in Sources */, + EE247B691C3F3FEC00AE3E12 /* Statement.swift in Sources */, + EE247B641C3F3FDB00AE3E12 /* Helpers.swift in Sources */, + EE247B721C3F3FEC00AE3E12 /* Operators.swift in Sources */, + EE247B741C3F3FEC00AE3E12 /* Schema.swift in Sources */, + EE247B731C3F3FEC00AE3E12 /* Query.swift in Sources */, + EE247B6B1C3F3FEC00AE3E12 /* FTS4.swift in Sources */, + EE247B661C3F3FEC00AE3E12 /* Connection.swift in Sources */, + EE247B6D1C3F3FEC00AE3E12 /* AggregateFunctions.swift in Sources */, + 19A1750CEE9B05267995CF3D /* FTS5.swift in Sources */, + 19A17835FD5886FDC5A3228F /* Cipher.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EE247B411C3F3ED000AE3E12 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EE247B561C3F3FC700AE3E12 /* CoreFunctionsTests.swift in Sources */, + EE247B5A1C3F3FC700AE3E12 /* OperatorsTests.swift in Sources */, + EE247B541C3F3FC700AE3E12 /* BlobTests.swift in Sources */, + EE247B5D1C3F3FC700AE3E12 /* SchemaTests.swift in Sources */, + EE247B591C3F3FC700AE3E12 /* FTS4Tests.swift in Sources */, + EE247B531C3F3FC700AE3E12 /* AggregateFunctionsTests.swift in Sources */, + EE247B5F1C3F3FC700AE3E12 /* StatementTests.swift in Sources */, + EE247B5C1C3F3FC700AE3E12 /* RTreeTests.swift in Sources */, + EE247B571C3F3FC700AE3E12 /* CustomFunctionsTests.swift in Sources */, + EE247B601C3F3FC700AE3E12 /* ValueTests.swift in Sources */, + EE247B551C3F3FC700AE3E12 /* ConnectionTests.swift in Sources */, + EE247B611C3F3FC700AE3E12 /* TestHelpers.swift in Sources */, + EE247B581C3F3FC700AE3E12 /* ExpressionTests.swift in Sources */, + EE247B5E1C3F3FC700AE3E12 /* SetterTests.swift in Sources */, + EE247B5B1C3F3FC700AE3E12 /* QueryTests.swift in Sources */, + 19A174D78559CD30679BCCCB /* FTS5Tests.swift in Sources */, + 19A178072B371489E6A1E839 /* FoundationTests.swift in Sources */, + 19A17C4B951CB054EE48AB1C /* CipherTests.swift in Sources */, + 19A1709C3E7A406E62293B2A /* Fixtures.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 03A65E661C6BB0F60062603F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 03A65E591C6BB0F50062603F /* SQLite tvOS */; + targetProxy = 03A65E651C6BB0F60062603F /* PBXContainerItemProxy */; + }; + EE247AE01C3F04ED00AE3E12 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EE247AD21C3F04ED00AE3E12 /* SQLite iOS */; + targetProxy = EE247ADF1C3F04ED00AE3E12 /* PBXContainerItemProxy */; + }; + EE247B481C3F3ED000AE3E12 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EE247B3B1C3F3ED000AE3E12 /* SQLite Mac */; + targetProxy = EE247B471C3F3ED000AE3E12 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 03A65E6B1C6BB0F60062603F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + "SWIFT_INCLUDE_PATHS[sdk=appletvos*]" = "$(SRCROOT)/CocoaPods/appletvos"; + "SWIFT_INCLUDE_PATHS[sdk=appletvsimulator*]" = "$(SRCROOT)/CocoaPods/appletvsimulator"; + SWIFT_VERSION = 3.0; + TVOS_DEPLOYMENT_TARGET = 9.1; + }; + name = Debug; + }; + 03A65E6C1C6BB0F60062603F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + "SWIFT_INCLUDE_PATHS[sdk=appletvos*]" = "$(SRCROOT)/CocoaPods/appletvos"; + "SWIFT_INCLUDE_PATHS[sdk=appletvsimulator*]" = "$(SRCROOT)/CocoaPods/appletvsimulator"; + SWIFT_VERSION = 3.0; + TVOS_DEPLOYMENT_TARGET = 9.1; + }; + name = Release; + }; + 03A65E6D1C6BB0F60062603F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Tests/SQLite/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 3.0; + TVOS_DEPLOYMENT_TARGET = 9.1; + }; + name = Debug; + }; + 03A65E6E1C6BB0F60062603F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Tests/SQLite/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_VERSION = 3.0; + TVOS_DEPLOYMENT_TARGET = 9.1; + }; + name = Release; + }; + A121AC4A1CA35C79005A31D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SDKROOT = watchos; + SKIP_INSTALL = YES; + "SWIFT_INCLUDE_PATHS[sdk=watchos*]" = "$(SRCROOT)/CocoaPods/watchos"; + "SWIFT_INCLUDE_PATHS[sdk=watchsimulator*]" = "$(SRCROOT)/CocoaPods/watchsimulator"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 2.2; + }; + name = Debug; + }; + A121AC4B1CA35C79005A31D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SDKROOT = watchos; + SKIP_INSTALL = YES; + "SWIFT_INCLUDE_PATHS[sdk=watchos*]" = "$(SRCROOT)/CocoaPods/watchos"; + "SWIFT_INCLUDE_PATHS[sdk=watchsimulator*]" = "$(SRCROOT)/CocoaPods/watchsimulator"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 2.2; + }; + name = Release; + }; + EE247AE51C3F04ED00AE3E12 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = ""; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2,3"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + EE247AE61C3F04ED00AE3E12 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = ""; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2,3"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + EE247AE81C3F04ED00AE3E12 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SKIP_INSTALL = YES; + "SWIFT_INCLUDE_PATHS[sdk=iphoneos*]" = "$(SRCROOT)/CocoaPods/iphoneos"; + "SWIFT_INCLUDE_PATHS[sdk=iphoneos10.0]" = "$(SRCROOT)/CocoaPods/iphoneos-10.0"; + "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]" = "$(SRCROOT)/CocoaPods/iphonesimulator"; + "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator10.0]" = "$(SRCROOT)/CocoaPods/iphonesimulator-10.0"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + EE247AE91C3F04ED00AE3E12 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SKIP_INSTALL = YES; + "SWIFT_INCLUDE_PATHS[sdk=iphoneos*]" = "$(SRCROOT)/CocoaPods/iphoneos"; + "SWIFT_INCLUDE_PATHS[sdk=iphoneos10.0]" = "$(SRCROOT)/CocoaPods/iphoneos-10.0"; + "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator*]" = "$(SRCROOT)/CocoaPods/iphonesimulator"; + "SWIFT_INCLUDE_PATHS[sdk=iphonesimulator10.0]" = "$(SRCROOT)/CocoaPods/iphonesimulator-10.0"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + EE247AEB1C3F04ED00AE3E12 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + EE247AEC1C3F04ED00AE3E12 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + EE247B4D1C3F3ED000AE3E12 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_INCLUDE_PATHS = ""; + "SWIFT_INCLUDE_PATHS[sdk=macosx*]" = "$(SRCROOT)/CocoaPods/macosx"; + "SWIFT_INCLUDE_PATHS[sdk=macosx10.11]" = "$(SRCROOT)/CocoaPods/macosx-10.11"; + "SWIFT_INCLUDE_PATHS[sdk=macosx10.12]" = "$(SRCROOT)/CocoaPods/macosx-10.12"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + EE247B4E1C3F3ED000AE3E12 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_INCLUDE_PATHS = ""; + "SWIFT_INCLUDE_PATHS[sdk=macosx*]" = "$(SRCROOT)/CocoaPods/macosx"; + "SWIFT_INCLUDE_PATHS[sdk=macosx10.11]" = "$(SRCROOT)/CocoaPods/macosx-10.11"; + "SWIFT_INCLUDE_PATHS[sdk=macosx10.12]" = "$(SRCROOT)/CocoaPods/macosx-10.12"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + EE247B4F1C3F3ED000AE3E12 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + EE247B501C3F3ED000AE3E12 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.11; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 03A65E6F1C6BB0F60062603F /* Build configuration list for PBXNativeTarget "SQLite tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 03A65E6B1C6BB0F60062603F /* Debug */, + 03A65E6C1C6BB0F60062603F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 03A65E701C6BB0F60062603F /* Build configuration list for PBXNativeTarget "SQLiteTests tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 03A65E6D1C6BB0F60062603F /* Debug */, + 03A65E6E1C6BB0F60062603F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A121AC4C1CA35C79005A31D1 /* Build configuration list for PBXNativeTarget "SQLite watchOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A121AC4A1CA35C79005A31D1 /* Debug */, + A121AC4B1CA35C79005A31D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EE247ACD1C3F04ED00AE3E12 /* Build configuration list for PBXProject "SQLite" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EE247AE51C3F04ED00AE3E12 /* Debug */, + EE247AE61C3F04ED00AE3E12 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EE247AE71C3F04ED00AE3E12 /* Build configuration list for PBXNativeTarget "SQLite iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EE247AE81C3F04ED00AE3E12 /* Debug */, + EE247AE91C3F04ED00AE3E12 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EE247AEA1C3F04ED00AE3E12 /* Build configuration list for PBXNativeTarget "SQLiteTests iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EE247AEB1C3F04ED00AE3E12 /* Debug */, + EE247AEC1C3F04ED00AE3E12 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EE247B511C3F3ED000AE3E12 /* Build configuration list for PBXNativeTarget "SQLite Mac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EE247B4D1C3F3ED000AE3E12 /* Debug */, + EE247B4E1C3F3ED000AE3E12 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EE247B521C3F3ED000AE3E12 /* Build configuration list for PBXNativeTarget "SQLiteTests Mac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EE247B4F1C3F3ED000AE3E12 /* Debug */, + EE247B501C3F3ED000AE3E12 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = EE247ACA1C3F04ED00AE3E12 /* Project object */; +} diff --git a/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..cd11dc9 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite Mac.xcscheme b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite Mac.xcscheme new file mode 100644 index 0000000..606b5a1 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite Mac.xcscheme @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite iOS.xcscheme b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite iOS.xcscheme new file mode 100644 index 0000000..64f3201 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite iOS.xcscheme @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite tvOS.xcscheme b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite tvOS.xcscheme new file mode 100644 index 0000000..71ba5f1 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite tvOS.xcscheme @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite watchOS.xcscheme b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite watchOS.xcscheme new file mode 100644 index 0000000..d2088e8 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite watchOS.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Blob.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Blob.swift new file mode 100644 index 0000000..2f5d2a1 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Blob.swift @@ -0,0 +1,60 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public struct Blob { + + public let bytes: [UInt8] + + public init(bytes: [UInt8]) { + self.bytes = bytes + } + + public init(bytes: UnsafeRawPointer, length: Int) { + let i8bufptr = UnsafeBufferPointer(start: bytes.assumingMemoryBound(to: UInt8.self), count: length) + self.init(bytes: [UInt8](i8bufptr)) + } + + public func toHex() -> String { + return bytes.map { + ($0 < 16 ? "0" : "") + String($0, radix: 16, uppercase: false) + }.joined(separator: "") + } + +} + +extension Blob : CustomStringConvertible { + + public var description: String { + return "x'\(toHex())'" + } + +} + +extension Blob : Equatable { + +} + +public func ==(lhs: Blob, rhs: Blob) -> Bool { + return lhs.bytes == rhs.bytes +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Connection.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Connection.swift new file mode 100644 index 0000000..0661175 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Connection.swift @@ -0,0 +1,756 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation.NSUUID +import Dispatch +#if SQLITE_SWIFT_STANDALONE +import sqlite3 +#elseif SQLITE_SWIFT_SQLCIPHER +import SQLCipher +#else +import CSQLite +#endif + +/// A connection to SQLite. +public final class Connection { + + /// The location of a SQLite database. + public enum Location { + + /// An in-memory database (equivalent to `.URI(":memory:")`). + /// + /// See: + case inMemory + + /// A temporary, file-backed database (equivalent to `.URI("")`). + /// + /// See: + case temporary + + /// A database located at the given URI filename (or path). + /// + /// See: + /// + /// - Parameter filename: A URI filename + case uri(String) + } + + /// An SQL operation passed to update callbacks. + public enum Operation { + + /// An INSERT operation. + case insert + + /// An UPDATE operation. + case update + + /// A DELETE operation. + case delete + + fileprivate init(rawValue:Int32) { + switch rawValue { + case SQLITE_INSERT: + self = .insert + case SQLITE_UPDATE: + self = .update + case SQLITE_DELETE: + self = .delete + default: + fatalError("unhandled operation code: \(rawValue)") + } + } + } + + public var handle: OpaquePointer { return _handle! } + + fileprivate var _handle: OpaquePointer? = nil + + /// Initializes a new SQLite connection. + /// + /// - Parameters: + /// + /// - location: The location of the database. Creates a new database if it + /// doesn’t already exist (unless in read-only mode). + /// + /// Default: `.InMemory`. + /// + /// - readonly: Whether or not to open the database in a read-only state. + /// + /// Default: `false`. + /// + /// - Returns: A new database connection. + public init(_ location: Location = .inMemory, readonly: Bool = false) throws { + let flags = readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE + try check(sqlite3_open_v2(location.description, &_handle, flags | SQLITE_OPEN_FULLMUTEX, nil)) + queue.setSpecific(key: Connection.queueKey, value: queueContext) + } + + /// Initializes a new connection to a database. + /// + /// - Parameters: + /// + /// - filename: The location of the database. Creates a new database if + /// it doesn’t already exist (unless in read-only mode). + /// + /// - readonly: Whether or not to open the database in a read-only state. + /// + /// Default: `false`. + /// + /// - Throws: `Result.Error` iff a connection cannot be established. + /// + /// - Returns: A new database connection. + public convenience init(_ filename: String, readonly: Bool = false) throws { + try self.init(.uri(filename), readonly: readonly) + } + + deinit { + sqlite3_close(handle) + } + + // MARK: - + + /// Whether or not the database was opened in a read-only state. + public var readonly: Bool { return sqlite3_db_readonly(handle, nil) == 1 } + + /// The last rowid inserted into the database via this connection. + public var lastInsertRowid: Int64 { + return sqlite3_last_insert_rowid(handle) + } + + /// The last number of changes (inserts, updates, or deletes) made to the + /// database via this connection. + public var changes: Int { + return Int(sqlite3_changes(handle)) + } + + /// The total number of changes (inserts, updates, or deletes) made to the + /// database via this connection. + public var totalChanges: Int { + return Int(sqlite3_total_changes(handle)) + } + + // MARK: - Execute + + /// Executes a batch of SQL statements. + /// + /// - Parameter SQL: A batch of zero or more semicolon-separated SQL + /// statements. + /// + /// - Throws: `Result.Error` if query execution fails. + public func execute(_ SQL: String) throws { + _ = try sync { try self.check(sqlite3_exec(self.handle, SQL, nil, nil, nil)) } + } + + // MARK: - Prepare + + /// Prepares a single SQL statement (with optional parameter bindings). + /// + /// - Parameters: + /// + /// - statement: A single SQL statement. + /// + /// - bindings: A list of parameters to bind to the statement. + /// + /// - Returns: A prepared statement. + public func prepare(_ statement: String, _ bindings: Binding?...) throws -> Statement { + if !bindings.isEmpty { return try prepare(statement, bindings) } + return try Statement(self, statement) + } + + /// Prepares a single SQL statement and binds parameters to it. + /// + /// - Parameters: + /// + /// - statement: A single SQL statement. + /// + /// - bindings: A list of parameters to bind to the statement. + /// + /// - Returns: A prepared statement. + public func prepare(_ statement: String, _ bindings: [Binding?]) throws -> Statement { + return try prepare(statement).bind(bindings) + } + + /// Prepares a single SQL statement and binds parameters to it. + /// + /// - Parameters: + /// + /// - statement: A single SQL statement. + /// + /// - bindings: A dictionary of named parameters to bind to the statement. + /// + /// - Returns: A prepared statement. + public func prepare(_ statement: String, _ bindings: [String: Binding?]) throws -> Statement { + return try prepare(statement).bind(bindings) + } + + // MARK: - Run + + /// Runs a single SQL statement (with optional parameter bindings). + /// + /// - Parameters: + /// + /// - statement: A single SQL statement. + /// + /// - bindings: A list of parameters to bind to the statement. + /// + /// - Throws: `Result.Error` if query execution fails. + /// + /// - Returns: The statement. + @discardableResult public func run(_ statement: String, _ bindings: Binding?...) throws -> Statement { + return try run(statement, bindings) + } + + /// Prepares, binds, and runs a single SQL statement. + /// + /// - Parameters: + /// + /// - statement: A single SQL statement. + /// + /// - bindings: A list of parameters to bind to the statement. + /// + /// - Throws: `Result.Error` if query execution fails. + /// + /// - Returns: The statement. + @discardableResult public func run(_ statement: String, _ bindings: [Binding?]) throws -> Statement { + return try prepare(statement).run(bindings) + } + + /// Prepares, binds, and runs a single SQL statement. + /// + /// - Parameters: + /// + /// - statement: A single SQL statement. + /// + /// - bindings: A dictionary of named parameters to bind to the statement. + /// + /// - Throws: `Result.Error` if query execution fails. + /// + /// - Returns: The statement. + @discardableResult public func run(_ statement: String, _ bindings: [String: Binding?]) throws -> Statement { + return try prepare(statement).run(bindings) + } + + // MARK: - Scalar + + /// Runs a single SQL statement (with optional parameter bindings), + /// returning the first value of the first row. + /// + /// - Parameters: + /// + /// - statement: A single SQL statement. + /// + /// - bindings: A list of parameters to bind to the statement. + /// + /// - Returns: The first value of the first row returned. + public func scalar(_ statement: String, _ bindings: Binding?...) throws -> Binding? { + return try scalar(statement, bindings) + } + + /// Runs a single SQL statement (with optional parameter bindings), + /// returning the first value of the first row. + /// + /// - Parameters: + /// + /// - statement: A single SQL statement. + /// + /// - bindings: A list of parameters to bind to the statement. + /// + /// - Returns: The first value of the first row returned. + public func scalar(_ statement: String, _ bindings: [Binding?]) throws -> Binding? { + return try prepare(statement).scalar(bindings) + } + + /// Runs a single SQL statement (with optional parameter bindings), + /// returning the first value of the first row. + /// + /// - Parameters: + /// + /// - statement: A single SQL statement. + /// + /// - bindings: A dictionary of named parameters to bind to the statement. + /// + /// - Returns: The first value of the first row returned. + public func scalar(_ statement: String, _ bindings: [String: Binding?]) throws -> Binding? { + return try prepare(statement).scalar(bindings) + } + + // MARK: - Transactions + + /// The mode in which a transaction acquires a lock. + public enum TransactionMode : String { + + /// Defers locking the database till the first read/write executes. + case deferred = "DEFERRED" + + /// Immediately acquires a reserved lock on the database. + case immediate = "IMMEDIATE" + + /// Immediately acquires an exclusive lock on all databases. + case exclusive = "EXCLUSIVE" + + } + + // TODO: Consider not requiring a throw to roll back? + /// Runs a transaction with the given mode. + /// + /// - Note: Transactions cannot be nested. To nest transactions, see + /// `savepoint()`, instead. + /// + /// - Parameters: + /// + /// - mode: The mode in which a transaction acquires a lock. + /// + /// Default: `.Deferred` + /// + /// - block: A closure to run SQL statements within the transaction. + /// The transaction will be committed when the block returns. The block + /// must throw to roll the transaction back. + /// + /// - Throws: `Result.Error`, and rethrows. + public func transaction(_ mode: TransactionMode = .deferred, block: @escaping () throws -> Void) throws { + try transaction("BEGIN \(mode.rawValue) TRANSACTION", block, "COMMIT TRANSACTION", or: "ROLLBACK TRANSACTION") + } + + // TODO: Consider not requiring a throw to roll back? + // TODO: Consider removing ability to set a name? + /// Runs a transaction with the given savepoint name (if omitted, it will + /// generate a UUID). + /// + /// - SeeAlso: `transaction()`. + /// + /// - Parameters: + /// + /// - savepointName: A unique identifier for the savepoint (optional). + /// + /// - block: A closure to run SQL statements within the transaction. + /// The savepoint will be released (committed) when the block returns. + /// The block must throw to roll the savepoint back. + /// + /// - Throws: `SQLite.Result.Error`, and rethrows. + public func savepoint(_ name: String = UUID().uuidString, block: @escaping () throws -> Void) throws { + let name = name.quote("'") + let savepoint = "SAVEPOINT \(name)" + + try transaction(savepoint, block, "RELEASE \(savepoint)", or: "ROLLBACK TO \(savepoint)") + } + + fileprivate func transaction(_ begin: String, _ block: @escaping () throws -> Void, _ commit: String, or rollback: String) throws { + return try sync { + try self.run(begin) + do { + try block() + } catch { + try self.run(rollback) + throw error + } + try self.run(commit) + } + } + + /// Interrupts any long-running queries. + public func interrupt() { + sqlite3_interrupt(handle) + } + + // MARK: - Handlers + + /// The number of seconds a connection will attempt to retry a statement + /// after encountering a busy signal (lock). + public var busyTimeout: Double = 0 { + didSet { + sqlite3_busy_timeout(handle, Int32(busyTimeout * 1_000)) + } + } + + /// Sets a handler to call after encountering a busy signal (lock). + /// + /// - Parameter callback: This block is executed during a lock in which a + /// busy error would otherwise be returned. It’s passed the number of + /// times it’s been called for this lock. If it returns `true`, it will + /// try again. If it returns `false`, no further attempts will be made. + public func busyHandler(_ callback: ((_ tries: Int) -> Bool)?) { + guard let callback = callback else { + sqlite3_busy_handler(handle, nil, nil) + busyHandler = nil + return + } + + let box: BusyHandler = { callback(Int($0)) ? 1 : 0 } + sqlite3_busy_handler(handle, { callback, tries in + unsafeBitCast(callback, to: BusyHandler.self)(tries) + }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) + busyHandler = box + } + fileprivate typealias BusyHandler = @convention(block) (Int32) -> Int32 + fileprivate var busyHandler: BusyHandler? + + /// Sets a handler to call when a statement is executed with the compiled + /// SQL. + /// + /// - Parameter callback: This block is invoked when a statement is executed + /// with the compiled SQL as its argument. + /// + /// db.trace { SQL in print(SQL) } + public func trace(_ callback: ((String) -> Void)?) { + #if SQLITE_SWIFT_SQLCIPHER + trace_v1(callback) + #else + if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) { + trace_v2(callback) + } else { + trace_v1(callback) + } + #endif + } + + fileprivate func trace_v1(_ callback: ((String) -> Void)?) { + guard let callback = callback else { + sqlite3_trace(handle, nil /* xCallback */, nil /* pCtx */) + trace = nil + return + } + let box: Trace = { (pointer: UnsafeRawPointer) in + callback(String(cString: pointer.assumingMemoryBound(to: UInt8.self))) + } + sqlite3_trace(handle, + { + (C: UnsafeMutableRawPointer?, SQL: UnsafePointer?) in + if let C = C, let SQL = SQL { + unsafeBitCast(C, to: Trace.self)(SQL) + } + }, + unsafeBitCast(box, to: UnsafeMutableRawPointer.self) + ) + trace = box + } + + + + + fileprivate typealias Trace = @convention(block) (UnsafeRawPointer) -> Void + fileprivate var trace: Trace? + + /// Registers a callback to be invoked whenever a row is inserted, updated, + /// or deleted in a rowid table. + /// + /// - Parameter callback: A callback invoked with the `Operation` (one of + /// `.Insert`, `.Update`, or `.Delete`), database name, table name, and + /// rowid. + public func updateHook(_ callback: ((_ operation: Operation, _ db: String, _ table: String, _ rowid: Int64) -> Void)?) { + guard let callback = callback else { + sqlite3_update_hook(handle, nil, nil) + updateHook = nil + return + } + + let box: UpdateHook = { + callback( + Operation(rawValue: $0), + String(cString: $1), + String(cString: $2), + $3 + ) + } + sqlite3_update_hook(handle, { callback, operation, db, table, rowid in + unsafeBitCast(callback, to: UpdateHook.self)(operation, db!, table!, rowid) + }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) + updateHook = box + } + fileprivate typealias UpdateHook = @convention(block) (Int32, UnsafePointer, UnsafePointer, Int64) -> Void + fileprivate var updateHook: UpdateHook? + + /// Registers a callback to be invoked whenever a transaction is committed. + /// + /// - Parameter callback: A callback invoked whenever a transaction is + /// committed. If this callback throws, the transaction will be rolled + /// back. + public func commitHook(_ callback: (() throws -> Void)?) { + guard let callback = callback else { + sqlite3_commit_hook(handle, nil, nil) + commitHook = nil + return + } + + let box: CommitHook = { + do { + try callback() + } catch { + return 1 + } + return 0 + } + sqlite3_commit_hook(handle, { callback in + unsafeBitCast(callback, to: CommitHook.self)() + }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) + commitHook = box + } + fileprivate typealias CommitHook = @convention(block) () -> Int32 + fileprivate var commitHook: CommitHook? + + /// Registers a callback to be invoked whenever a transaction rolls back. + /// + /// - Parameter callback: A callback invoked when a transaction is rolled + /// back. + public func rollbackHook(_ callback: (() -> Void)?) { + guard let callback = callback else { + sqlite3_rollback_hook(handle, nil, nil) + rollbackHook = nil + return + } + + let box: RollbackHook = { callback() } + sqlite3_rollback_hook(handle, { callback in + unsafeBitCast(callback, to: RollbackHook.self)() + }, unsafeBitCast(box, to: UnsafeMutableRawPointer.self)) + rollbackHook = box + } + fileprivate typealias RollbackHook = @convention(block) () -> Void + fileprivate var rollbackHook: RollbackHook? + + /// Creates or redefines a custom SQL function. + /// + /// - Parameters: + /// + /// - function: The name of the function to create or redefine. + /// + /// - argumentCount: The number of arguments that the function takes. If + /// `nil`, the function may take any number of arguments. + /// + /// Default: `nil` + /// + /// - deterministic: Whether or not the function is deterministic (_i.e._ + /// the function always returns the same result for a given input). + /// + /// Default: `false` + /// + /// - block: A block of code to run when the function is called. The block + /// is called with an array of raw SQL values mapped to the function’s + /// parameters and should return a raw SQL value (or nil). + public func createFunction(_ function: String, argumentCount: UInt? = nil, deterministic: Bool = false, _ block: @escaping (_ args: [Binding?]) -> Binding?) { + let argc = argumentCount.map { Int($0) } ?? -1 + let box: Function = { context, argc, argv in + let arguments: [Binding?] = (0..?) -> Void + fileprivate var functions = [String: [Int: Function]]() + + /// Defines a new collating sequence. + /// + /// - Parameters: + /// + /// - collation: The name of the collation added. + /// + /// - block: A collation function that takes two strings and returns the + /// comparison result. + public func createCollation(_ collation: String, _ block: @escaping (_ lhs: String, _ rhs: String) -> ComparisonResult) throws { + let box: Collation = { (lhs: UnsafeRawPointer, rhs: UnsafeRawPointer) in + let lstr = String(cString: lhs.assumingMemoryBound(to: UInt8.self)) + let rstr = String(cString: rhs.assumingMemoryBound(to: UInt8.self)) + return Int32(block(lstr, rstr).rawValue) + } + try check(sqlite3_create_collation_v2(handle, collation, SQLITE_UTF8, + unsafeBitCast(box, to: UnsafeMutableRawPointer.self), + { (callback: UnsafeMutableRawPointer?, _, lhs: UnsafeRawPointer?, _, rhs: UnsafeRawPointer?) in /* xCompare */ + if let lhs = lhs, let rhs = rhs { + return unsafeBitCast(callback, to: Collation.self)(lhs, rhs) + } else { + fatalError("sqlite3_create_collation_v2 callback called with NULL pointer") + } + }, nil /* xDestroy */)) + collations[collation] = box + } + fileprivate typealias Collation = @convention(block) (UnsafeRawPointer, UnsafeRawPointer) -> Int32 + fileprivate var collations = [String: Collation]() + + // MARK: - Error Handling + + func sync(_ block: @escaping () throws -> T) rethrows -> T { + var success: T? + var failure: Error? + + let box: () -> Void = { + do { + success = try block() + } catch { + failure = error + } + } + + if DispatchQueue.getSpecific(key: Connection.queueKey) == queueContext { + box() + } else { + queue.sync(execute: box) // FIXME: rdar://problem/21389236 + } + + if let failure = failure { + try { () -> Void in throw failure }() + } + + return success! + } + + @discardableResult func check(_ resultCode: Int32, statement: Statement? = nil) throws -> Int32 { + guard let error = Result(errorCode: resultCode, connection: self, statement: statement) else { + return resultCode + } + + throw error + } + + fileprivate var queue = DispatchQueue(label: "SQLite.Database", attributes: []) + + fileprivate static let queueKey = DispatchSpecificKey() + + fileprivate lazy var queueContext: Int = unsafeBitCast(self, to: Int.self) + +} + +extension Connection : CustomStringConvertible { + + public var description: String { + return String(cString: sqlite3_db_filename(handle, nil)) + } + +} + +extension Connection.Location : CustomStringConvertible { + + public var description: String { + switch self { + case .inMemory: + return ":memory:" + case .temporary: + return "" + case .uri(let URI): + return URI + } + } + +} + +public enum Result : Error { + + fileprivate static let successCodes: Set = [SQLITE_OK, SQLITE_ROW, SQLITE_DONE] + + case error(message: String, code: Int32, statement: Statement?) + + init?(errorCode: Int32, connection: Connection, statement: Statement? = nil) { + guard !Result.successCodes.contains(errorCode) else { return nil } + + let message = String(cString: sqlite3_errmsg(connection.handle)) + self = .error(message: message, code: errorCode, statement: statement) + } + +} + +extension Result : CustomStringConvertible { + + public var description: String { + switch self { + case let .error(message, errorCode, statement): + if let statement = statement { + return "\(message) (\(statement)) (code: \(errorCode))" + } else { + return "\(message) (code: \(errorCode))" + } + } + } +} + +#if !SQLITE_SWIFT_SQLCIPHER +@available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) +extension Connection { + fileprivate func trace_v2(_ callback: ((String) -> Void)?) { + guard let callback = callback else { + // If the X callback is NULL or if the M mask is zero, then tracing is disabled. + sqlite3_trace_v2(handle, 0 /* mask */, nil /* xCallback */, nil /* pCtx */) + trace = nil + return + } + + let box: Trace = { (pointer: UnsafeRawPointer) in + callback(String(cString: pointer.assumingMemoryBound(to: UInt8.self))) + } + sqlite3_trace_v2(handle, + UInt32(SQLITE_TRACE_STMT) /* mask */, + { + // A trace callback is invoked with four arguments: callback(T,C,P,X). + // The T argument is one of the SQLITE_TRACE constants to indicate why the + // callback was invoked. The C argument is a copy of the context pointer. + // The P and X arguments are pointers whose meanings depend on T. + (T: UInt32, C: UnsafeMutableRawPointer?, P: UnsafeMutableRawPointer?, X: UnsafeMutableRawPointer?) in + if let P = P, + let expandedSQL = sqlite3_expanded_sql(OpaquePointer(P)) { + unsafeBitCast(C, to: Trace.self)(expandedSQL) + sqlite3_free(expandedSQL) + } + return Int32(0) // currently ignored + }, + unsafeBitCast(box, to: UnsafeMutableRawPointer.self) /* pCtx */ + ) + trace = box + } +} +#endif diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Statement.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Statement.swift new file mode 100644 index 0000000..766bd15 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Statement.swift @@ -0,0 +1,297 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#if SQLITE_SWIFT_STANDALONE +import sqlite3 +#elseif SQLITE_SWIFT_SQLCIPHER +import SQLCipher +#else +import CSQLite +#endif + +/// A single SQL statement. +public final class Statement { + + fileprivate var handle: OpaquePointer? = nil + + fileprivate let connection: Connection + + init(_ connection: Connection, _ SQL: String) throws { + self.connection = connection + try connection.check(sqlite3_prepare_v2(connection.handle, SQL, -1, &handle, nil)) + } + + deinit { + sqlite3_finalize(handle) + } + + public lazy var columnCount: Int = Int(sqlite3_column_count(self.handle)) + + public lazy var columnNames: [String] = (0.. Statement { + return bind(values) + } + + /// Binds a list of parameters to a statement. + /// + /// - Parameter values: A list of parameters to bind to the statement. + /// + /// - Returns: The statement object (useful for chaining). + public func bind(_ values: [Binding?]) -> Statement { + if values.isEmpty { return self } + reset() + guard values.count == Int(sqlite3_bind_parameter_count(handle)) else { + fatalError("\(sqlite3_bind_parameter_count(handle)) values expected, \(values.count) passed") + } + for idx in 1...values.count { bind(values[idx - 1], atIndex: idx) } + return self + } + + /// Binds a dictionary of named parameters to a statement. + /// + /// - Parameter values: A dictionary of named parameters to bind to the + /// statement. + /// + /// - Returns: The statement object (useful for chaining). + public func bind(_ values: [String: Binding?]) -> Statement { + reset() + for (name, value) in values { + let idx = sqlite3_bind_parameter_index(handle, name) + guard idx > 0 else { + fatalError("parameter not found: \(name)") + } + bind(value, atIndex: Int(idx)) + } + return self + } + + fileprivate func bind(_ value: Binding?, atIndex idx: Int) { + if value == nil { + sqlite3_bind_null(handle, Int32(idx)) + } else if let value = value as? Blob { + sqlite3_bind_blob(handle, Int32(idx), value.bytes, Int32(value.bytes.count), SQLITE_TRANSIENT) + } else if let value = value as? Double { + sqlite3_bind_double(handle, Int32(idx), value) + } else if let value = value as? Int64 { + sqlite3_bind_int64(handle, Int32(idx), value) + } else if let value = value as? String { + sqlite3_bind_text(handle, Int32(idx), value, -1, SQLITE_TRANSIENT) + } else if let value = value as? Int { + self.bind(value.datatypeValue, atIndex: idx) + } else if let value = value as? Bool { + self.bind(value.datatypeValue, atIndex: idx) + } else if let value = value { + fatalError("tried to bind unexpected value \(value)") + } + } + + /// - Parameter bindings: A list of parameters to bind to the statement. + /// + /// - Throws: `Result.Error` if query execution fails. + /// + /// - Returns: The statement object (useful for chaining). + @discardableResult public func run(_ bindings: Binding?...) throws -> Statement { + guard bindings.isEmpty else { + return try run(bindings) + } + + reset(clearBindings: false) + repeat {} while try step() + return self + } + + /// - Parameter bindings: A list of parameters to bind to the statement. + /// + /// - Throws: `Result.Error` if query execution fails. + /// + /// - Returns: The statement object (useful for chaining). + @discardableResult public func run(_ bindings: [Binding?]) throws -> Statement { + return try bind(bindings).run() + } + + /// - Parameter bindings: A dictionary of named parameters to bind to the + /// statement. + /// + /// - Throws: `Result.Error` if query execution fails. + /// + /// - Returns: The statement object (useful for chaining). + @discardableResult public func run(_ bindings: [String: Binding?]) throws -> Statement { + return try bind(bindings).run() + } + + /// - Parameter bindings: A list of parameters to bind to the statement. + /// + /// - Returns: The first value of the first row returned. + public func scalar(_ bindings: Binding?...) throws -> Binding? { + guard bindings.isEmpty else { + return try scalar(bindings) + } + + reset(clearBindings: false) + _ = try step() + return row[0] + } + + /// - Parameter bindings: A list of parameters to bind to the statement. + /// + /// - Returns: The first value of the first row returned. + public func scalar(_ bindings: [Binding?]) throws -> Binding? { + return try bind(bindings).scalar() + } + + + /// - Parameter bindings: A dictionary of named parameters to bind to the + /// statement. + /// + /// - Returns: The first value of the first row returned. + public func scalar(_ bindings: [String: Binding?]) throws -> Binding? { + return try bind(bindings).scalar() + } + + public func step() throws -> Bool { + return try connection.sync { try self.connection.check(sqlite3_step(self.handle)) == SQLITE_ROW } + } + + fileprivate func reset(clearBindings shouldClear: Bool = true) { + sqlite3_reset(handle) + if (shouldClear) { sqlite3_clear_bindings(handle) } + } + +} + +extension Statement : Sequence { + + public func makeIterator() -> Statement { + reset(clearBindings: false) + return self + } + +} + +extension Statement : IteratorProtocol { + + public func next() -> [Binding?]? { + return try! step() ? Array(row) : nil + } + +} + +extension Statement : CustomStringConvertible { + + public var description: String { + return String(cString: sqlite3_sql(handle)) + } + +} + +public struct Cursor { + + fileprivate let handle: OpaquePointer + + fileprivate let columnCount: Int + + fileprivate init(_ statement: Statement) { + handle = statement.handle! + columnCount = statement.columnCount + } + + public subscript(idx: Int) -> Double { + return sqlite3_column_double(handle, Int32(idx)) + } + + public subscript(idx: Int) -> Int64 { + return sqlite3_column_int64(handle, Int32(idx)) + } + + public subscript(idx: Int) -> String { + return String(cString: UnsafePointer(sqlite3_column_text(handle, Int32(idx)))) + } + + public subscript(idx: Int) -> Blob { + if let pointer = sqlite3_column_blob(handle, Int32(idx)) { + let length = Int(sqlite3_column_bytes(handle, Int32(idx))) + return Blob(bytes: pointer, length: length) + } else { + // The return value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. + // https://www.sqlite.org/c3ref/column_blob.html + return Blob(bytes: []) + } + } + + // MARK: - + + public subscript(idx: Int) -> Bool { + return Bool.fromDatatypeValue(self[idx]) + } + + public subscript(idx: Int) -> Int { + return Int.fromDatatypeValue(self[idx]) + } + +} + +/// Cursors provide direct access to a statement’s current row. +extension Cursor : Sequence { + + public subscript(idx: Int) -> Binding? { + switch sqlite3_column_type(handle, Int32(idx)) { + case SQLITE_BLOB: + return self[idx] as Blob + case SQLITE_FLOAT: + return self[idx] as Double + case SQLITE_INTEGER: + return self[idx] as Int64 + case SQLITE_NULL: + return nil + case SQLITE_TEXT: + return self[idx] as String + case let type: + fatalError("unsupported column type: \(type)") + } + } + + public func makeIterator() -> AnyIterator { + var idx = 0 + return AnyIterator { + if idx >= self.columnCount { + return Optional.none + } else { + idx += 1 + return self[idx - 1] + } + } + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Value.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Value.swift new file mode 100644 index 0000000..608f0ce --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Core/Value.swift @@ -0,0 +1,132 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/// - Warning: `Binding` is a protocol that SQLite.swift uses internally to +/// directly map SQLite types to Swift types. +/// +/// Do not conform custom types to the Binding protocol. See the `Value` +/// protocol, instead. +public protocol Binding {} + +public protocol Number : Binding {} + +public protocol Value : Expressible { // extensions cannot have inheritance clauses + + associatedtype ValueType = Self + + associatedtype Datatype : Binding + + static var declaredDatatype: String { get } + + static func fromDatatypeValue(_ datatypeValue: Datatype) -> ValueType + + var datatypeValue: Datatype { get } + +} + +extension Double : Number, Value { + + public static let declaredDatatype = "REAL" + + public static func fromDatatypeValue(_ datatypeValue: Double) -> Double { + return datatypeValue + } + + public var datatypeValue: Double { + return self + } + +} + +extension Int64 : Number, Value { + + public static let declaredDatatype = "INTEGER" + + public static func fromDatatypeValue(_ datatypeValue: Int64) -> Int64 { + return datatypeValue + } + + public var datatypeValue: Int64 { + return self + } + +} + +extension String : Binding, Value { + + public static let declaredDatatype = "TEXT" + + public static func fromDatatypeValue(_ datatypeValue: String) -> String { + return datatypeValue + } + + public var datatypeValue: String { + return self + } + +} + +extension Blob : Binding, Value { + + public static let declaredDatatype = "BLOB" + + public static func fromDatatypeValue(_ datatypeValue: Blob) -> Blob { + return datatypeValue + } + + public var datatypeValue: Blob { + return self + } + +} + +// MARK: - + +extension Bool : Binding, Value { + + public static var declaredDatatype = Int64.declaredDatatype + + public static func fromDatatypeValue(_ datatypeValue: Int64) -> Bool { + return datatypeValue != 0 + } + + public var datatypeValue: Int64 { + return self ? 1 : 0 + } + +} + +extension Int : Number, Value { + + public static var declaredDatatype = Int64.declaredDatatype + + public static func fromDatatypeValue(_ datatypeValue: Int64) -> Int { + return Int(datatypeValue) + } + + public var datatypeValue: Int64 { + return Int64(self) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/Cipher.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/Cipher.swift new file mode 100644 index 0000000..6c0d465 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/Cipher.swift @@ -0,0 +1,61 @@ +#if SQLITE_SWIFT_SQLCIPHER +import SQLCipher + + +/// Extension methods for [SQLCipher](https://www.zetetic.net/sqlcipher/). +/// @see [sqlcipher api](https://www.zetetic.net/sqlcipher/sqlcipher-api/) +extension Connection { + + /// Specify the key for an encrypted database. This routine should be + /// called right after sqlite3_open(). + /// + /// @param key The key to use.The key itself can be a passphrase, which is converted to a key + /// using [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2) key derivation. The result + /// is used as the encryption key for the database. + /// + /// Alternatively, it is possible to specify an exact byte sequence using a blob literal. + /// With this method, it is the calling application's responsibility to ensure that the data + /// provided is a 64 character hex string, which will be converted directly to 32 bytes (256 bits) + /// of key data. + /// e.g. x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99' + /// @param db name of the database, defaults to 'main' + public func key(_ key: String, db: String = "main") throws { + try _key_v2(db: db, keyPointer: key, keySize: key.utf8.count) + } + + public func key(_ key: Blob, db: String = "main") throws { + try _key_v2(db: db, keyPointer: key.bytes, keySize: key.bytes.count) + } + + + /// Change the key on an open database. If the current database is not encrypted, this routine + /// will encrypt it. + /// To change the key on an existing encrypted database, it must first be unlocked with the + /// current encryption key. Once the database is readable and writeable, rekey can be used + /// to re-encrypt every page in the database with a new key. + public func rekey(_ key: String, db: String = "main") throws { + try _rekey_v2(db: db, keyPointer: key, keySize: key.utf8.count) + } + + public func rekey(_ key: Blob, db: String = "main") throws { + try _rekey_v2(db: db, keyPointer: key.bytes, keySize: key.bytes.count) + } + + // MARK: - private + private func _key_v2(db: String, keyPointer: UnsafePointer, keySize: Int) throws { + try check(sqlite3_key_v2(handle, db, keyPointer, Int32(keySize))) + try cipher_key_check() + } + + private func _rekey_v2(db: String, keyPointer: UnsafePointer, keySize: Int) throws { + try check(sqlite3_rekey_v2(handle, db, keyPointer, Int32(keySize))) + } + + // When opening an existing database, sqlite3_key_v2 will not immediately throw an error if + // the key provided is incorrect. To test that the database can be successfully opened with the + // provided key, it is necessary to perform some operation on the database (i.e. read from it). + private func cipher_key_check() throws { + try scalar("SELECT count(*) FROM sqlite_master;") + } +} +#endif diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/FTS4.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/FTS4.swift new file mode 100644 index 0000000..152a292 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/FTS4.swift @@ -0,0 +1,346 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#if SWIFT_PACKAGE +import SQLiteObjc +#endif + +extension Module { + + public static func FTS4(_ column: Expressible, _ more: Expressible...) -> Module { + return FTS4([column] + more) + } + + public static func FTS4(_ columns: [Expressible] = [], tokenize tokenizer: Tokenizer? = nil) -> Module { + return FTS4(FTS4Config().columns(columns).tokenizer(tokenizer)) + } + + public static func FTS4(_ config: FTS4Config) -> Module { + return Module(name: "fts4", arguments: config.arguments()) + } +} + +extension VirtualTable { + + /// Builds an expression appended with a `MATCH` query against the given + /// pattern. + /// + /// let emails = VirtualTable("emails") + /// + /// emails.filter(emails.match("Hello")) + /// // SELECT * FROM "emails" WHERE "emails" MATCH 'Hello' + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: An expression appended with a `MATCH` query against the given + /// pattern. + public func match(_ pattern: String) -> Expression { + return "MATCH".infix(tableName(), pattern) + } + + public func match(_ pattern: Expression) -> Expression { + return "MATCH".infix(tableName(), pattern) + } + + public func match(_ pattern: Expression) -> Expression { + return "MATCH".infix(tableName(), pattern) + } + + /// Builds a copy of the query with a `WHERE … MATCH` clause. + /// + /// let emails = VirtualTable("emails") + /// + /// emails.match("Hello") + /// // SELECT * FROM "emails" WHERE "emails" MATCH 'Hello' + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: A query with the given `WHERE … MATCH` clause applied. + public func match(_ pattern: String) -> QueryType { + return filter(match(pattern)) + } + + public func match(_ pattern: Expression) -> QueryType { + return filter(match(pattern)) + } + + public func match(_ pattern: Expression) -> QueryType { + return filter(match(pattern)) + } + +} + +public struct Tokenizer { + + public static let Simple = Tokenizer("simple") + + public static let Porter = Tokenizer("porter") + + public static func Unicode61(removeDiacritics: Bool? = nil, tokenchars: Set = [], separators: Set = []) -> Tokenizer { + var arguments = [String]() + + if let removeDiacritics = removeDiacritics { + arguments.append("removeDiacritics=\(removeDiacritics ? 1 : 0)".quote()) + } + + if !tokenchars.isEmpty { + let joined = tokenchars.map { String($0) }.joined(separator: "") + arguments.append("tokenchars=\(joined)".quote()) + } + + if !separators.isEmpty { + let joined = separators.map { String($0) }.joined(separator: "") + arguments.append("separators=\(joined)".quote()) + } + + return Tokenizer("unicode61", arguments) + } + + public static func Custom(_ name: String) -> Tokenizer { + return Tokenizer(Tokenizer.moduleName.quote(), [name.quote()]) + } + + public let name: String + + public let arguments: [String] + + fileprivate init(_ name: String, _ arguments: [String] = []) { + self.name = name + self.arguments = arguments + } + + fileprivate static let moduleName = "SQLite.swift" + +} + +extension Tokenizer : CustomStringConvertible { + + public var description: String { + return ([name] + arguments).joined(separator: " ") + } + +} + +extension Connection { + + public func registerTokenizer(_ submoduleName: String, next: @escaping (String) -> (String, Range)?) throws { + try check(_SQLiteRegisterTokenizer(handle, Tokenizer.moduleName, submoduleName) { input, offset, length in + let string = String(cString: input) + + guard let (token, range) = next(string) else { return nil } + + let view = string.utf8 + offset.pointee += string.substring(to: range.lowerBound).utf8.count + length.pointee = Int32(view.distance(from: range.lowerBound.samePosition(in: view), to: range.upperBound.samePosition(in: view))) + return token + }) + } + +} + +/// Configuration options shared between the [FTS4](https://www.sqlite.org/fts3.html) and +/// [FTS5](https://www.sqlite.org/fts5.html) extensions. +open class FTSConfig { + public enum ColumnOption { + /// [The notindexed= option](https://www.sqlite.org/fts3.html#section_6_5) + case unindexed + } + + typealias ColumnDefinition = (Expressible, options: [ColumnOption]) + var columnDefinitions = [ColumnDefinition]() + var tokenizer: Tokenizer? + var prefixes = [Int]() + var externalContentSchema: SchemaType? + var isContentless: Bool = false + + /// Adds a column definition + @discardableResult open func column(_ column: Expressible, _ options: [ColumnOption] = []) -> Self { + self.columnDefinitions.append((column, options)) + return self + } + + @discardableResult open func columns(_ columns: [Expressible]) -> Self { + for column in columns { + self.column(column) + } + return self + } + + /// [Tokenizers](https://www.sqlite.org/fts3.html#tokenizer) + open func tokenizer(_ tokenizer: Tokenizer?) -> Self { + self.tokenizer = tokenizer + return self + } + + /// [The prefix= option](https://www.sqlite.org/fts3.html#section_6_6) + open func prefix(_ prefix: [Int]) -> Self { + self.prefixes += prefix + return self + } + + /// [The content= option](https://www.sqlite.org/fts3.html#section_6_2) + open func externalContent(_ schema: SchemaType) -> Self { + self.externalContentSchema = schema + return self + } + + /// [Contentless FTS4 Tables](https://www.sqlite.org/fts3.html#section_6_2_1) + open func contentless() -> Self { + self.isContentless = true + return self + } + + func formatColumnDefinitions() -> [Expressible] { + return columnDefinitions.map { $0.0 } + } + + func arguments() -> [Expressible] { + return options().arguments + } + + func options() -> Options { + var options = Options() + options.append(formatColumnDefinitions()) + if let tokenizer = tokenizer { + options.append("tokenize", value: Expression(literal: tokenizer.description)) + } + options.appendCommaSeparated("prefix", values:prefixes.sorted().map { String($0) }) + if isContentless { + options.append("content", value: "") + } else if let externalContentSchema = externalContentSchema { + options.append("content", value: externalContentSchema.tableName()) + } + return options + } + + struct Options { + var arguments = [Expressible]() + + @discardableResult mutating func append(_ columns: [Expressible]) -> Options { + arguments.append(contentsOf: columns) + return self + } + + @discardableResult mutating func appendCommaSeparated(_ key: String, values: [String]) -> Options { + if values.isEmpty { + return self + } else { + return append(key, value: values.joined(separator: ",")) + } + } + + @discardableResult mutating func append(_ key: String, value: CustomStringConvertible?) -> Options { + return append(key, value: value?.description) + } + + @discardableResult mutating func append(_ key: String, value: String?) -> Options { + return append(key, value: value.map { Expression($0) }) + } + + @discardableResult mutating func append(_ key: String, value: Expressible?) -> Options { + if let value = value { + arguments.append("=".join([Expression(literal: key), value])) + } + return self + } + } +} + +/// Configuration for the [FTS4](https://www.sqlite.org/fts3.html) extension. +open class FTS4Config : FTSConfig { + /// [The matchinfo= option](https://www.sqlite.org/fts3.html#section_6_4) + public enum MatchInfo : CustomStringConvertible { + case fts3 + public var description: String { + return "fts3" + } + } + + /// [FTS4 options](https://www.sqlite.org/fts3.html#fts4_options) + public enum Order : CustomStringConvertible { + /// Data structures are optimized for returning results in ascending order by docid (default) + case asc + /// FTS4 stores its data in such a way as to optimize returning results in descending order by docid. + case desc + + public var description: String { + switch self { + case .asc: return "asc" + case .desc: return "desc" + } + } + } + + var compressFunction: String? + var uncompressFunction: String? + var languageId: String? + var matchInfo: MatchInfo? + var order: Order? + + override public init() { + } + + /// [The compress= and uncompress= options](https://www.sqlite.org/fts3.html#section_6_1) + open func compress(_ functionName: String) -> Self { + self.compressFunction = functionName + return self + } + + /// [The compress= and uncompress= options](https://www.sqlite.org/fts3.html#section_6_1) + open func uncompress(_ functionName: String) -> Self { + self.uncompressFunction = functionName + return self + } + + /// [The languageid= option](https://www.sqlite.org/fts3.html#section_6_3) + open func languageId(_ columnName: String) -> Self { + self.languageId = columnName + return self + } + + /// [The matchinfo= option](https://www.sqlite.org/fts3.html#section_6_4) + open func matchInfo(_ matchInfo: MatchInfo) -> Self { + self.matchInfo = matchInfo + return self + } + + /// [FTS4 options](https://www.sqlite.org/fts3.html#fts4_options) + open func order(_ order: Order) -> Self { + self.order = order + return self + } + + override func options() -> Options { + var options = super.options() + for (column, _) in (columnDefinitions.filter { $0.options.contains(.unindexed) }) { + options.append("notindexed", value: column) + } + options.append("languageid", value: languageId) + options.append("compress", value: compressFunction) + options.append("uncompress", value: uncompressFunction) + options.append("matchinfo", value: matchInfo) + options.append("order", value: order) + return options + } +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/FTS5.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/FTS5.swift new file mode 100644 index 0000000..763927f --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/FTS5.swift @@ -0,0 +1,97 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +extension Module { + public static func FTS5(_ config: FTS5Config) -> Module { + return Module(name: "fts5", arguments: config.arguments()) + } +} + +/// Configuration for the [FTS5](https://www.sqlite.org/fts5.html) extension. +/// +/// **Note:** this is currently only applicable when using SQLite.swift together with a FTS5-enabled version +/// of SQLite. +open class FTS5Config : FTSConfig { + public enum Detail : CustomStringConvertible { + /// store rowid, column number, term offset + case full + /// store rowid, column number + case column + /// store rowid + case none + + public var description: String { + switch self { + case .full: return "full" + case .column: return "column" + case .none: return "none" + } + } + } + + var detail: Detail? + var contentRowId: Expressible? + var columnSize: Int? + + override public init() { + } + + /// [External Content Tables](https://www.sqlite.org/fts5.html#section_4_4_2) + open func contentRowId(_ column: Expressible) -> Self { + self.contentRowId = column + return self + } + + /// [The Columnsize Option](https://www.sqlite.org/fts5.html#section_4_5) + open func columnSize(_ size: Int) -> Self { + self.columnSize = size + return self + } + + /// [The Detail Option](https://www.sqlite.org/fts5.html#section_4_6) + open func detail(_ detail: Detail) -> Self { + self.detail = detail + return self + } + + override func options() -> Options { + var options = super.options() + options.append("content_rowid", value: contentRowId) + if let columnSize = columnSize { + options.append("columnsize", value: Expression(value: columnSize)) + } + options.append("detail", value: detail) + return options + } + + override func formatColumnDefinitions() -> [Expressible] { + return columnDefinitions.map { definition in + if definition.options.contains(.unindexed) { + return " ".join([definition.0, Expression(literal: "UNINDEXED")]) + } else { + return definition.0 + } + } + } +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/RTree.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/RTree.swift new file mode 100644 index 0000000..4fc1a23 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Extensions/RTree.swift @@ -0,0 +1,37 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +extension Module { + + public static func RTree(_ primaryKey: Expression, _ pairs: (Expression, Expression)...) -> Module where T.Datatype == Int64, U.Datatype == Double { + var arguments: [Expressible] = [primaryKey] + + for pair in pairs { + arguments.append(contentsOf: [pair.0, pair.1] as [Expressible]) + } + + return Module(name: "rtree", arguments: arguments) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Foundation.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Foundation.swift new file mode 100644 index 0000000..5e10229 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Foundation.swift @@ -0,0 +1,108 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +extension Data : Value { + + public static var declaredDatatype: String { + return Blob.declaredDatatype + } + + public static func fromDatatypeValue(_ dataValue: Blob) -> Data { + return Data(bytes: dataValue.bytes) + } + + public var datatypeValue: Blob { + return withUnsafeBytes { (pointer: UnsafePointer) -> Blob in + return Blob(bytes: pointer, length: count) + } + } + +} + +extension Date : Value { + + public static var declaredDatatype: String { + return String.declaredDatatype + } + + public static func fromDatatypeValue(_ stringValue: String) -> Date { + return dateFormatter.date(from: stringValue)! + } + + public var datatypeValue: String { + return dateFormatter.string(from: self) + } + +} + +/// A global date formatter used to serialize and deserialize `NSDate` objects. +/// If multiple date formats are used in an application’s database(s), use a +/// custom `Value` type per additional format. +public var dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS" + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.timeZone = TimeZone(secondsFromGMT: 0) + return formatter +}() + +// FIXME: rdar://problem/18673897 // subscript… + +extension QueryType { + + public subscript(column: Expression) -> Expression { + return namespace(column) + } + public subscript(column: Expression) -> Expression { + return namespace(column) + } + + public subscript(column: Expression) -> Expression { + return namespace(column) + } + public subscript(column: Expression) -> Expression { + return namespace(column) + } + +} + +extension Row { + + public subscript(column: Expression) -> Data { + return get(column) + } + public subscript(column: Expression) -> Data? { + return get(column) + } + + public subscript(column: Expression) -> Date { + return get(column) + } + public subscript(column: Expression) -> Date? { + return get(column) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Helpers.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Helpers.swift new file mode 100644 index 0000000..81a7507 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Helpers.swift @@ -0,0 +1,130 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#if SQLITE_SWIFT_STANDALONE +import sqlite3 +#elseif SQLITE_SWIFT_SQLCIPHER +import SQLCipher +#else +import CSQLite +#endif + +public typealias Star = (Expression?, Expression?) -> Expression + +public func *(_: Expression?, _: Expression?) -> Expression { + return Expression(literal: "*") +} + +public protocol _OptionalType { + + associatedtype WrappedType + +} + +extension Optional : _OptionalType { + + public typealias WrappedType = Wrapped + +} + +// let SQLITE_STATIC = unsafeBitCast(0, sqlite3_destructor_type.self) +let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self) + +extension String { + + func quote(_ mark: Character = "\"") -> String { + let escaped = characters.reduce("") { string, character in + string + (character == mark ? "\(mark)\(mark)" : "\(character)") + } + return "\(mark)\(escaped)\(mark)" + } + + func join(_ expressions: [Expressible]) -> Expressible { + var (template, bindings) = ([String](), [Binding?]()) + for expressible in expressions { + let expression = expressible.expression + template.append(expression.template) + bindings.append(contentsOf: expression.bindings) + } + return Expression(template.joined(separator: self), bindings) + } + + func infix(_ lhs: Expressible, _ rhs: Expressible, wrap: Bool = true) -> Expression { + let expression = Expression(" \(self) ".join([lhs, rhs]).expression) + guard wrap else { + return expression + } + return "".wrap(expression) + } + + func prefix(_ expressions: Expressible) -> Expressible { + return "\(self) ".wrap(expressions) as Expression + } + + func prefix(_ expressions: [Expressible]) -> Expressible { + return "\(self) ".wrap(expressions) as Expression + } + + func wrap(_ expression: Expressible) -> Expression { + return Expression("\(self)(\(expression.expression.template))", expression.expression.bindings) + } + + func wrap(_ expressions: [Expressible]) -> Expression { + return wrap(", ".join(expressions)) + } + +} + +func infix(_ lhs: Expressible, _ rhs: Expressible, wrap: Bool = true, function: String = #function) -> Expression { + return function.infix(lhs, rhs, wrap: wrap) +} + +func wrap(_ expression: Expressible, function: String = #function) -> Expression { + return function.wrap(expression) +} + +func wrap(_ expressions: [Expressible], function: String = #function) -> Expression { + return function.wrap(", ".join(expressions)) +} + +func transcode(_ literal: Binding?) -> String { + guard let literal = literal else { return "NULL" } + + switch literal { + case let blob as Blob: + return blob.description + case let string as String: + return string.quote("'") + case let binding: + return "\(binding)" + } +} + +func value(_ v: Binding) -> A { + return A.fromDatatypeValue(v as! A.Datatype) as! A +} + +func value(_ v: Binding?) -> A { + return value(v!) +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Info.plist b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Info.plist new file mode 100644 index 0000000..588139c --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.11.2 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/SQLite.h b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/SQLite.h new file mode 100644 index 0000000..693ce32 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/SQLite.h @@ -0,0 +1,6 @@ +@import Foundation; + +FOUNDATION_EXPORT double SQLiteVersionNumber; +FOUNDATION_EXPORT const unsigned char SQLiteVersionString[]; + +#import diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/AggregateFunctions.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/AggregateFunctions.swift new file mode 100644 index 0000000..249bbe6 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/AggregateFunctions.swift @@ -0,0 +1,251 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +extension ExpressionType where UnderlyingType : Value { + + /// Builds a copy of the expression prefixed with the `DISTINCT` keyword. + /// + /// let name = Expression("name") + /// name.distinct + /// // DISTINCT "name" + /// + /// - Returns: A copy of the expression prefixed with the `DISTINCT` + /// keyword. + public var distinct: Expression { + return Expression("DISTINCT \(template)", bindings) + } + + /// Builds a copy of the expression wrapped with the `count` aggregate + /// function. + /// + /// let name = Expression("name") + /// name.count + /// // count("name") + /// name.distinct.count + /// // count(DISTINCT "name") + /// + /// - Returns: A copy of the expression wrapped with the `count` aggregate + /// function. + public var count: Expression { + return wrap(self) + } + +} + +extension ExpressionType where UnderlyingType : _OptionalType, UnderlyingType.WrappedType : Value { + + /// Builds a copy of the expression prefixed with the `DISTINCT` keyword. + /// + /// let name = Expression("name") + /// name.distinct + /// // DISTINCT "name" + /// + /// - Returns: A copy of the expression prefixed with the `DISTINCT` + /// keyword. + public var distinct: Expression { + return Expression("DISTINCT \(template)", bindings) + } + + /// Builds a copy of the expression wrapped with the `count` aggregate + /// function. + /// + /// let name = Expression("name") + /// name.count + /// // count("name") + /// name.distinct.count + /// // count(DISTINCT "name") + /// + /// - Returns: A copy of the expression wrapped with the `count` aggregate + /// function. + public var count: Expression { + return wrap(self) + } + +} + +extension ExpressionType where UnderlyingType : Value, UnderlyingType.Datatype : Comparable { + + /// Builds a copy of the expression wrapped with the `max` aggregate + /// function. + /// + /// let age = Expression("age") + /// age.max + /// // max("age") + /// + /// - Returns: A copy of the expression wrapped with the `max` aggregate + /// function. + public var max: Expression { + return wrap(self) + } + + /// Builds a copy of the expression wrapped with the `min` aggregate + /// function. + /// + /// let age = Expression("age") + /// age.min + /// // min("age") + /// + /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// function. + public var min: Expression { + return wrap(self) + } + +} + +extension ExpressionType where UnderlyingType : _OptionalType, UnderlyingType.WrappedType : Value, UnderlyingType.WrappedType.Datatype : Comparable { + + /// Builds a copy of the expression wrapped with the `max` aggregate + /// function. + /// + /// let age = Expression("age") + /// age.max + /// // max("age") + /// + /// - Returns: A copy of the expression wrapped with the `max` aggregate + /// function. + public var max: Expression { + return wrap(self) + } + + /// Builds a copy of the expression wrapped with the `min` aggregate + /// function. + /// + /// let age = Expression("age") + /// age.min + /// // min("age") + /// + /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// function. + public var min: Expression { + return wrap(self) + } + +} + +extension ExpressionType where UnderlyingType : Value, UnderlyingType.Datatype : Number { + + /// Builds a copy of the expression wrapped with the `avg` aggregate + /// function. + /// + /// let salary = Expression("salary") + /// salary.average + /// // avg("salary") + /// + /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// function. + public var average: Expression { + return "avg".wrap(self) + } + + /// Builds a copy of the expression wrapped with the `sum` aggregate + /// function. + /// + /// let salary = Expression("salary") + /// salary.sum + /// // sum("salary") + /// + /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// function. + public var sum: Expression { + return wrap(self) + } + + /// Builds a copy of the expression wrapped with the `total` aggregate + /// function. + /// + /// let salary = Expression("salary") + /// salary.total + /// // total("salary") + /// + /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// function. + public var total: Expression { + return wrap(self) + } + +} + +extension ExpressionType where UnderlyingType : _OptionalType, UnderlyingType.WrappedType : Value, UnderlyingType.WrappedType.Datatype : Number { + + /// Builds a copy of the expression wrapped with the `avg` aggregate + /// function. + /// + /// let salary = Expression("salary") + /// salary.average + /// // avg("salary") + /// + /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// function. + public var average: Expression { + return "avg".wrap(self) + } + + /// Builds a copy of the expression wrapped with the `sum` aggregate + /// function. + /// + /// let salary = Expression("salary") + /// salary.sum + /// // sum("salary") + /// + /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// function. + public var sum: Expression { + return wrap(self) + } + + /// Builds a copy of the expression wrapped with the `total` aggregate + /// function. + /// + /// let salary = Expression("salary") + /// salary.total + /// // total("salary") + /// + /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// function. + public var total: Expression { + return wrap(self) + } + +} + +extension ExpressionType where UnderlyingType == Int { + + static func count(_ star: Star) -> Expression { + return wrap(star(nil, nil)) + } + +} + +/// Builds an expression representing `count(*)` (when called with the `*` +/// function literal). +/// +/// count(*) +/// // count(*) +/// +/// - Returns: An expression returning `count(*)` (when called with the `*` +/// function literal). +public func count(_ star: Star) -> Expression { + return Expression.count(star) +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Collation.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Collation.swift new file mode 100644 index 0000000..e2ff9d1 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Collation.swift @@ -0,0 +1,69 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +/// A collating function used to compare to strings. +/// +/// - SeeAlso: +public enum Collation { + + /// Compares string by raw data. + case binary + + /// Like binary, but folds uppercase ASCII letters into their lowercase + /// equivalents. + case nocase + + /// Like binary, but strips trailing space. + case rtrim + + /// A custom collating sequence identified by the given string, registered + /// using `Database.create(collation:…)` + case custom(String) + +} + +extension Collation : Expressible { + + public var expression: Expression { + return Expression(literal: description) + } + +} + +extension Collation : CustomStringConvertible { + + public var description : String { + switch self { + case .binary: + return "BINARY" + case .nocase: + return "NOCASE" + case .rtrim: + return "RTRIM" + case .custom(let collation): + return collation.quote() + } + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/CoreFunctions.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/CoreFunctions.swift new file mode 100644 index 0000000..9d17a32 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/CoreFunctions.swift @@ -0,0 +1,683 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation.NSData + + +extension ExpressionType where UnderlyingType : Number { + + /// Builds a copy of the expression wrapped with the `abs` function. + /// + /// let x = Expression("x") + /// x.absoluteValue + /// // abs("x") + /// + /// - Returns: A copy of the expression wrapped with the `abs` function. + public var absoluteValue : Expression { + return "abs".wrap(self) + } + +} + +extension ExpressionType where UnderlyingType : _OptionalType, UnderlyingType.WrappedType : Number { + + /// Builds a copy of the expression wrapped with the `abs` function. + /// + /// let x = Expression("x") + /// x.absoluteValue + /// // abs("x") + /// + /// - Returns: A copy of the expression wrapped with the `abs` function. + public var absoluteValue : Expression { + return "abs".wrap(self) + } + +} + +extension ExpressionType where UnderlyingType == Double { + + /// Builds a copy of the expression wrapped with the `round` function. + /// + /// let salary = Expression("salary") + /// salary.round() + /// // round("salary") + /// salary.round(2) + /// // round("salary", 2) + /// + /// - Returns: A copy of the expression wrapped with the `round` function. + public func round(_ precision: Int? = nil) -> Expression { + guard let precision = precision else { + return wrap([self]) + } + return wrap([self, Int(precision)]) + } + +} + +extension ExpressionType where UnderlyingType == Double? { + + /// Builds a copy of the expression wrapped with the `round` function. + /// + /// let salary = Expression("salary") + /// salary.round() + /// // round("salary") + /// salary.round(2) + /// // round("salary", 2) + /// + /// - Returns: A copy of the expression wrapped with the `round` function. + public func round(_ precision: Int? = nil) -> Expression { + guard let precision = precision else { + return wrap(self) + } + return wrap([self, Int(precision)]) + } + +} + +extension ExpressionType where UnderlyingType : Value, UnderlyingType.Datatype == Int64 { + + /// Builds an expression representing the `random` function. + /// + /// Expression.random() + /// // random() + /// + /// - Returns: An expression calling the `random` function. + public static func random() -> Expression { + return "random".wrap([]) + } + +} + +extension ExpressionType where UnderlyingType == Data { + + /// Builds an expression representing the `randomblob` function. + /// + /// Expression.random(16) + /// // randomblob(16) + /// + /// - Parameter length: Length in bytes. + /// + /// - Returns: An expression calling the `randomblob` function. + public static func random(_ length: Int) -> Expression { + return "randomblob".wrap([]) + } + + /// Builds an expression representing the `zeroblob` function. + /// + /// Expression.allZeros(16) + /// // zeroblob(16) + /// + /// - Parameter length: Length in bytes. + /// + /// - Returns: An expression calling the `zeroblob` function. + public static func allZeros(_ length: Int) -> Expression { + return "zeroblob".wrap([]) + } + + /// Builds a copy of the expression wrapped with the `length` function. + /// + /// let data = Expression("data") + /// data.length + /// // length("data") + /// + /// - Returns: A copy of the expression wrapped with the `length` function. + public var length: Expression { + return wrap(self) + } + +} + +extension ExpressionType where UnderlyingType == Data? { + + /// Builds a copy of the expression wrapped with the `length` function. + /// + /// let data = Expression("data") + /// data.length + /// // length("data") + /// + /// - Returns: A copy of the expression wrapped with the `length` function. + public var length: Expression { + return wrap(self) + } + +} + +extension ExpressionType where UnderlyingType == String { + + /// Builds a copy of the expression wrapped with the `length` function. + /// + /// let name = Expression("name") + /// name.length + /// // length("name") + /// + /// - Returns: A copy of the expression wrapped with the `length` function. + public var length: Expression { + return wrap(self) + } + + /// Builds a copy of the expression wrapped with the `lower` function. + /// + /// let name = Expression("name") + /// name.lowercaseString + /// // lower("name") + /// + /// - Returns: A copy of the expression wrapped with the `lower` function. + public var lowercaseString: Expression { + return "lower".wrap(self) + } + + /// Builds a copy of the expression wrapped with the `upper` function. + /// + /// let name = Expression("name") + /// name.uppercaseString + /// // lower("name") + /// + /// - Returns: A copy of the expression wrapped with the `upper` function. + public var uppercaseString: Expression { + return "upper".wrap(self) + } + + /// Builds a copy of the expression appended with a `LIKE` query against the + /// given pattern. + /// + /// let email = Expression("email") + /// email.like("%@example.com") + /// // "email" LIKE '%@example.com' + /// email.like("99\\%@%", escape: "\\") + /// // "email" LIKE '99\%@%' ESCAPE '\' + /// + /// - Parameters: + /// + /// - pattern: A pattern to match. + /// + /// - escape: An (optional) character designated for escaping + /// pattern-matching characters (*i.e.*, the `%` and `_` characters). + /// + /// - Returns: A copy of the expression appended with a `LIKE` query against + /// the given pattern. + public func like(_ pattern: String, escape character: Character? = nil) -> Expression { + guard let character = character else { + return "LIKE".infix(self, pattern) + } + return Expression("(\(template) LIKE ? ESCAPE ?)", bindings + [pattern, String(character)]) + } + + /// Builds a copy of the expression appended with a `GLOB` query against the + /// given pattern. + /// + /// let path = Expression("path") + /// path.glob("*.png") + /// // "path" GLOB '*.png' + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: A copy of the expression appended with a `GLOB` query against + /// the given pattern. + public func glob(_ pattern: String) -> Expression { + return "GLOB".infix(self, pattern) + } + + /// Builds a copy of the expression appended with a `MATCH` query against + /// the given pattern. + /// + /// let title = Expression("title") + /// title.match("swift AND programming") + /// // "title" MATCH 'swift AND programming' + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: A copy of the expression appended with a `MATCH` query + /// against the given pattern. + public func match(_ pattern: String) -> Expression { + return "MATCH".infix(self, pattern) + } + + /// Builds a copy of the expression appended with a `REGEXP` query against + /// the given pattern. + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: A copy of the expression appended with a `REGEXP` query + /// against the given pattern. + public func regexp(_ pattern: String) -> Expression { + return "REGEXP".infix(self, pattern) + } + + /// Builds a copy of the expression appended with a `COLLATE` clause with + /// the given sequence. + /// + /// let name = Expression("name") + /// name.collate(.Nocase) + /// // "name" COLLATE NOCASE + /// + /// - Parameter collation: A collating sequence. + /// + /// - Returns: A copy of the expression appended with a `COLLATE` clause + /// with the given sequence. + public func collate(_ collation: Collation) -> Expression { + return "COLLATE".infix(self, collation) + } + + /// Builds a copy of the expression wrapped with the `ltrim` function. + /// + /// let name = Expression("name") + /// name.ltrim() + /// // ltrim("name") + /// name.ltrim([" ", "\t"]) + /// // ltrim("name", ' \t') + /// + /// - Parameter characters: A set of characters to trim. + /// + /// - Returns: A copy of the expression wrapped with the `ltrim` function. + public func ltrim(_ characters: Set? = nil) -> Expression { + guard let characters = characters else { + return wrap(self) + } + return wrap([self, String(characters)]) + } + + /// Builds a copy of the expression wrapped with the `rtrim` function. + /// + /// let name = Expression("name") + /// name.rtrim() + /// // rtrim("name") + /// name.rtrim([" ", "\t"]) + /// // rtrim("name", ' \t') + /// + /// - Parameter characters: A set of characters to trim. + /// + /// - Returns: A copy of the expression wrapped with the `rtrim` function. + public func rtrim(_ characters: Set? = nil) -> Expression { + guard let characters = characters else { + return wrap(self) + } + return wrap([self, String(characters)]) + } + + /// Builds a copy of the expression wrapped with the `trim` function. + /// + /// let name = Expression("name") + /// name.trim() + /// // trim("name") + /// name.trim([" ", "\t"]) + /// // trim("name", ' \t') + /// + /// - Parameter characters: A set of characters to trim. + /// + /// - Returns: A copy of the expression wrapped with the `trim` function. + public func trim(_ characters: Set? = nil) -> Expression { + guard let characters = characters else { + return wrap([self]) + } + return wrap([self, String(characters)]) + } + + /// Builds a copy of the expression wrapped with the `replace` function. + /// + /// let email = Expression("email") + /// email.replace("@mac.com", with: "@icloud.com") + /// // replace("email", '@mac.com', '@icloud.com') + /// + /// - Parameters: + /// + /// - pattern: A pattern to match. + /// + /// - replacement: The replacement string. + /// + /// - Returns: A copy of the expression wrapped with the `replace` function. + public func replace(_ pattern: String, with replacement: String) -> Expression { + return "replace".wrap([self, pattern, replacement]) + } + + public func substring(_ location: Int, length: Int? = nil) -> Expression { + guard let length = length else { + return "substr".wrap([self, location]) + } + return "substr".wrap([self, location, length]) + } + + public subscript(range: Range) -> Expression { + return substring(range.lowerBound, length: range.upperBound - range.lowerBound) + } + +} + +extension ExpressionType where UnderlyingType == String? { + + /// Builds a copy of the expression wrapped with the `length` function. + /// + /// let name = Expression("name") + /// name.length + /// // length("name") + /// + /// - Returns: A copy of the expression wrapped with the `length` function. + public var length: Expression { + return wrap(self) + } + + /// Builds a copy of the expression wrapped with the `lower` function. + /// + /// let name = Expression("name") + /// name.lowercaseString + /// // lower("name") + /// + /// - Returns: A copy of the expression wrapped with the `lower` function. + public var lowercaseString: Expression { + return "lower".wrap(self) + } + + /// Builds a copy of the expression wrapped with the `upper` function. + /// + /// let name = Expression("name") + /// name.uppercaseString + /// // lower("name") + /// + /// - Returns: A copy of the expression wrapped with the `upper` function. + public var uppercaseString: Expression { + return "upper".wrap(self) + } + + /// Builds a copy of the expression appended with a `LIKE` query against the + /// given pattern. + /// + /// let email = Expression("email") + /// email.like("%@example.com") + /// // "email" LIKE '%@example.com' + /// email.like("99\\%@%", escape: "\\") + /// // "email" LIKE '99\%@%' ESCAPE '\' + /// + /// - Parameters: + /// + /// - pattern: A pattern to match. + /// + /// - escape: An (optional) character designated for escaping + /// pattern-matching characters (*i.e.*, the `%` and `_` characters). + /// + /// - Returns: A copy of the expression appended with a `LIKE` query against + /// the given pattern. + public func like(_ pattern: String, escape character: Character? = nil) -> Expression { + guard let character = character else { + return "LIKE".infix(self, pattern) + } + return Expression("(\(template) LIKE ? ESCAPE ?)", bindings + [pattern, String(character)]) + } + + /// Builds a copy of the expression appended with a `GLOB` query against the + /// given pattern. + /// + /// let path = Expression("path") + /// path.glob("*.png") + /// // "path" GLOB '*.png' + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: A copy of the expression appended with a `GLOB` query against + /// the given pattern. + public func glob(_ pattern: String) -> Expression { + return "GLOB".infix(self, pattern) + } + + /// Builds a copy of the expression appended with a `MATCH` query against + /// the given pattern. + /// + /// let title = Expression("title") + /// title.match("swift AND programming") + /// // "title" MATCH 'swift AND programming' + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: A copy of the expression appended with a `MATCH` query + /// against the given pattern. + public func match(_ pattern: String) -> Expression { + return "MATCH".infix(self, pattern) + } + + /// Builds a copy of the expression appended with a `REGEXP` query against + /// the given pattern. + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: A copy of the expression appended with a `REGEXP` query + /// against the given pattern. + public func regexp(_ pattern: String) -> Expression { + return "REGEXP".infix(self, pattern) + } + + /// Builds a copy of the expression appended with a `COLLATE` clause with + /// the given sequence. + /// + /// let name = Expression("name") + /// name.collate(.Nocase) + /// // "name" COLLATE NOCASE + /// + /// - Parameter collation: A collating sequence. + /// + /// - Returns: A copy of the expression appended with a `COLLATE` clause + /// with the given sequence. + public func collate(_ collation: Collation) -> Expression { + return "COLLATE".infix(self, collation) + } + + /// Builds a copy of the expression wrapped with the `ltrim` function. + /// + /// let name = Expression("name") + /// name.ltrim() + /// // ltrim("name") + /// name.ltrim([" ", "\t"]) + /// // ltrim("name", ' \t') + /// + /// - Parameter characters: A set of characters to trim. + /// + /// - Returns: A copy of the expression wrapped with the `ltrim` function. + public func ltrim(_ characters: Set? = nil) -> Expression { + guard let characters = characters else { + return wrap(self) + } + return wrap([self, String(characters)]) + } + + /// Builds a copy of the expression wrapped with the `rtrim` function. + /// + /// let name = Expression("name") + /// name.rtrim() + /// // rtrim("name") + /// name.rtrim([" ", "\t"]) + /// // rtrim("name", ' \t') + /// + /// - Parameter characters: A set of characters to trim. + /// + /// - Returns: A copy of the expression wrapped with the `rtrim` function. + public func rtrim(_ characters: Set? = nil) -> Expression { + guard let characters = characters else { + return wrap(self) + } + return wrap([self, String(characters)]) + } + + /// Builds a copy of the expression wrapped with the `trim` function. + /// + /// let name = Expression("name") + /// name.trim() + /// // trim("name") + /// name.trim([" ", "\t"]) + /// // trim("name", ' \t') + /// + /// - Parameter characters: A set of characters to trim. + /// + /// - Returns: A copy of the expression wrapped with the `trim` function. + public func trim(_ characters: Set? = nil) -> Expression { + guard let characters = characters else { + return wrap(self) + } + return wrap([self, String(characters)]) + } + + /// Builds a copy of the expression wrapped with the `replace` function. + /// + /// let email = Expression("email") + /// email.replace("@mac.com", with: "@icloud.com") + /// // replace("email", '@mac.com', '@icloud.com') + /// + /// - Parameters: + /// + /// - pattern: A pattern to match. + /// + /// - replacement: The replacement string. + /// + /// - Returns: A copy of the expression wrapped with the `replace` function. + public func replace(_ pattern: String, with replacement: String) -> Expression { + return "replace".wrap([self, pattern, replacement]) + } + + /// Builds a copy of the expression wrapped with the `substr` function. + /// + /// let title = Expression("title") + /// title.substr(-100) + /// // substr("title", -100) + /// title.substr(0, length: 100) + /// // substr("title", 0, 100) + /// + /// - Parameters: + /// + /// - location: The substring’s start index. + /// + /// - length: An optional substring length. + /// + /// - Returns: A copy of the expression wrapped with the `substr` function. + public func substring(_ location: Int, length: Int? = nil) -> Expression { + guard let length = length else { + return "substr".wrap([self, location]) + } + return "substr".wrap([self, location, length]) + } + + /// Builds a copy of the expression wrapped with the `substr` function. + /// + /// let title = Expression("title") + /// title[0..<100] + /// // substr("title", 0, 100) + /// + /// - Parameter range: The character index range of the substring. + /// + /// - Returns: A copy of the expression wrapped with the `substr` function. + public subscript(range: Range) -> Expression { + return substring(range.lowerBound, length: range.upperBound - range.lowerBound) + } + +} + +extension Collection where Iterator.Element : Value, IndexDistance == Int { + + /// Builds a copy of the expression prepended with an `IN` check against the + /// collection. + /// + /// let name = Expression("name") + /// ["alice", "betty"].contains(name) + /// // "name" IN ('alice', 'betty') + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: A copy of the expression prepended with an `IN` check against + /// the collection. + public func contains(_ expression: Expression) -> Expression { + let templates = [String](repeating: "?", count: count).joined(separator: ", ") + return "IN".infix(expression, Expression("(\(templates))", map { $0.datatypeValue })) + } + + /// Builds a copy of the expression prepended with an `IN` check against the + /// collection. + /// + /// let name = Expression("name") + /// ["alice", "betty"].contains(name) + /// // "name" IN ('alice', 'betty') + /// + /// - Parameter pattern: A pattern to match. + /// + /// - Returns: A copy of the expression prepended with an `IN` check against + /// the collection. + public func contains(_ expression: Expression) -> Expression { + let templates = [String](repeating: "?", count: count).joined(separator: ", ") + return "IN".infix(expression, Expression("(\(templates))", map { $0.datatypeValue })) + } + +} + +/// Builds a copy of the given expressions wrapped with the `ifnull` function. +/// +/// let name = Expression("name") +/// name ?? "An Anonymous Coward" +/// // ifnull("name", 'An Anonymous Coward') +/// +/// - Parameters: +/// +/// - optional: An optional expression. +/// +/// - defaultValue: A fallback value for when the optional expression is +/// `nil`. +/// +/// - Returns: A copy of the given expressions wrapped with the `ifnull` +/// function. +public func ??(optional: Expression, defaultValue: V) -> Expression { + return "ifnull".wrap([optional, defaultValue]) +} + +/// Builds a copy of the given expressions wrapped with the `ifnull` function. +/// +/// let nick = Expression("nick") +/// let name = Expression("name") +/// nick ?? name +/// // ifnull("nick", "name") +/// +/// - Parameters: +/// +/// - optional: An optional expression. +/// +/// - defaultValue: A fallback expression for when the optional expression is +/// `nil`. +/// +/// - Returns: A copy of the given expressions wrapped with the `ifnull` +/// function. +public func ??(optional: Expression, defaultValue: Expression) -> Expression { + return "ifnull".wrap([optional, defaultValue]) +} + +/// Builds a copy of the given expressions wrapped with the `ifnull` function. +/// +/// let nick = Expression("nick") +/// let name = Expression("name") +/// nick ?? name +/// // ifnull("nick", "name") +/// +/// - Parameters: +/// +/// - optional: An optional expression. +/// +/// - defaultValue: A fallback expression for when the optional expression is +/// `nil`. +/// +/// - Returns: A copy of the given expressions wrapped with the `ifnull` +/// function. +public func ??(optional: Expression, defaultValue: Expression) -> Expression { + return "ifnull".wrap([optional, defaultValue]) +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/CustomFunctions.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/CustomFunctions.swift new file mode 100644 index 0000000..64b54ed --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/CustomFunctions.swift @@ -0,0 +1,136 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public extension Connection { + + /// Creates or redefines a custom SQL function. + /// + /// - Parameters: + /// + /// - function: The name of the function to create or redefine. + /// + /// - deterministic: Whether or not the function is deterministic (_i.e._ + /// the function always returns the same result for a given input). + /// + /// Default: `false` + /// + /// - block: A block of code to run when the function is called. + /// The assigned types must be explicit. + /// + /// - Returns: A closure returning an SQL expression to call the function. + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping () -> Z) throws -> (() -> Expression) { + let fn = try createFunction(function, 0, deterministic) { _ in block() } + return { fn([]) } + } + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping () -> Z?) throws -> (() -> Expression) { + let fn = try createFunction(function, 0, deterministic) { _ in block() } + return { fn([]) } + } + + // MARK: - + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A) -> Z) throws -> ((Expression) -> Expression) { + let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0])) } + return { arg in fn([arg]) } + } + + public func createFunction(function: String, deterministic: Bool = false, _ block: @escaping (A?) -> Z) throws -> ((Expression) -> Expression) { + let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value)) } + return { arg in fn([arg]) } + } + + public func createFunction(function: String, deterministic: Bool = false, _ block: @escaping (A) -> Z?) throws -> ((Expression) -> Expression) { + let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0])) } + return { arg in fn([arg]) } + } + + public func createFunction(function: String, deterministic: Bool = false, _ block: @escaping (A?) -> Z?) throws -> ((Expression) -> Expression) { + let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value)) } + return { arg in fn([arg]) } + } + + // MARK: - + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A, B) -> Z) throws -> (Expression, Expression) -> Expression { + let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0]), value(args[1])) } + return { a, b in fn([a, b]) } + } + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A?, B) -> Z) throws -> (Expression, Expression) -> Expression { + let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value), value(args[1])) } + return { a, b in fn([a, b]) } + } + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A, B?) -> Z) throws -> (Expression, Expression) -> Expression { + let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0]), args[1].map(value)) } + return { a, b in fn([a, b]) } + } + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A, B) -> Z?) throws -> (Expression, Expression) -> Expression { + let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0]), value(args[1])) } + return { a, b in fn([a, b]) } + } + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A?, B?) -> Z) throws -> (Expression, Expression) -> Expression { + let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value), args[1].map(value)) } + return { a, b in fn([a, b]) } + } + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A?, B) -> Z?) throws -> (Expression, Expression) -> Expression { + let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value), value(args[1])) } + return { a, b in fn([a, b]) } + } + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A, B?) -> Z?) throws -> (Expression, Expression) -> Expression { + let fn = try createFunction(function, 1, deterministic) { args in block(value(args[0]), args[1].map(value)) } + return { a, b in fn([a, b]) } + } + + public func createFunction(_ function: String, deterministic: Bool = false, _ block: @escaping (A?, B?) -> Z?) throws -> (Expression, Expression) -> Expression { + let fn = try createFunction(function, 1, deterministic) { args in block(args[0].map(value), args[1].map(value)) } + return { a, b in fn([a, b]) } + } + + // MARK: - + + fileprivate func createFunction(_ function: String, _ argumentCount: UInt, _ deterministic: Bool, _ block: @escaping ([Binding?]) -> Z) throws -> (([Expressible]) -> Expression) { + createFunction(function, argumentCount: argumentCount, deterministic: deterministic) { arguments in + block(arguments).datatypeValue + } + return { arguments in + function.quote().wrap(", ".join(arguments)) + } + } + + fileprivate func createFunction(_ function: String, _ argumentCount: UInt, _ deterministic: Bool, _ block: @escaping ([Binding?]) -> Z?) throws -> (([Expressible]) -> Expression) { + createFunction(function, argumentCount: argumentCount, deterministic: deterministic) { arguments in + block(arguments)?.datatypeValue + } + return { arguments in + function.quote().wrap(", ".join(arguments)) + } + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Expression.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Expression.swift new file mode 100644 index 0000000..3198901 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Expression.swift @@ -0,0 +1,147 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public protocol ExpressionType : Expressible { // extensions cannot have inheritance clauses + + associatedtype UnderlyingType = Void + + var template: String { get } + var bindings: [Binding?] { get } + + init(_ template: String, _ bindings: [Binding?]) + +} + +extension ExpressionType { + + public init(literal: String) { + self.init(literal, []) + } + + public init(_ identifier: String) { + self.init(literal: identifier.quote()) + } + + public init(_ expression: U) { + self.init(expression.template, expression.bindings) + } + +} + +/// An `Expression` represents a raw SQL fragment and any associated bindings. +public struct Expression : ExpressionType { + + public typealias UnderlyingType = Datatype + + public var template: String + public var bindings: [Binding?] + + public init(_ template: String, _ bindings: [Binding?]) { + self.template = template + self.bindings = bindings + } + +} + +public protocol Expressible { + + var expression: Expression { get } + +} + +extension Expressible { + + // naïve compiler for statements that can’t be bound, e.g., CREATE TABLE + // FIXME: use @testable and make internal + public func asSQL() -> String { + let expressed = expression + var idx = 0 + return expressed.template.characters.reduce("") { template, character in + let transcoded: String + + if character == "?" { + transcoded = transcode(expressed.bindings[idx]) + idx += 1 + } else { + transcoded = String(character) + } + return template + transcoded + } + } + +} + +extension ExpressionType { + + public var expression: Expression { + return Expression(template, bindings) + } + + public var asc: Expressible { + return " ".join([self, Expression(literal: "ASC")]) + } + + public var desc: Expressible { + return " ".join([self, Expression(literal: "DESC")]) + } + +} + +extension ExpressionType where UnderlyingType : Value { + + public init(value: UnderlyingType) { + self.init("?", [value.datatypeValue]) + } + +} + +extension ExpressionType where UnderlyingType : _OptionalType, UnderlyingType.WrappedType : Value { + + public static var null: Self { + return self.init(value: nil) + } + + public init(value: UnderlyingType.WrappedType?) { + self.init("?", [value?.datatypeValue]) + } + +} + +extension Value { + + public var expression: Expression { + return Expression(value: self).expression + } + +} + +public let rowid = Expression("ROWID") + +public func cast(_ expression: Expression) -> Expression { + return Expression("CAST (\(expression.template) AS \(U.declaredDatatype))", expression.bindings) +} + +public func cast(_ expression: Expression) -> Expression { + return Expression("CAST (\(expression.template) AS \(U.declaredDatatype))", expression.bindings) +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Operators.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Operators.swift new file mode 100644 index 0000000..fdd293b --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Operators.swift @@ -0,0 +1,541 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +// TODO: use `@warn_unused_result` by the time operator functions support it + +public func +(lhs: Expression, rhs: Expression) -> Expression { + return "||".infix(lhs, rhs) +} + +public func +(lhs: Expression, rhs: Expression) -> Expression { + return "||".infix(lhs, rhs) +} +public func +(lhs: Expression, rhs: Expression) -> Expression { + return "||".infix(lhs, rhs) +} +public func +(lhs: Expression, rhs: Expression) -> Expression { + return "||".infix(lhs, rhs) +} +public func +(lhs: Expression, rhs: String) -> Expression { + return "||".infix(lhs, rhs) +} +public func +(lhs: Expression, rhs: String) -> Expression { + return "||".infix(lhs, rhs) +} +public func +(lhs: String, rhs: Expression) -> Expression { + return "||".infix(lhs, rhs) +} +public func +(lhs: String, rhs: Expression) -> Expression { + return "||".infix(lhs, rhs) +} + +// MARK: - + +public func +(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func +(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func +(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func +(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func +(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func +(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func +(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func +(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} + +public func -(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func -(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func -(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func -(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func -(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func -(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func -(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func -(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} + +public func *(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func *(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func *(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func *(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func *(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func *(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func *(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func *(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} + +public func /(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func /(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func /(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func /(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func /(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func /(lhs: Expression, rhs: V) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func /(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} +public func /(lhs: V, rhs: Expression) -> Expression where V.Datatype : Number { + return infix(lhs, rhs) +} + +public prefix func -(rhs: Expression) -> Expression where V.Datatype : Number { + return wrap(rhs) +} +public prefix func -(rhs: Expression) -> Expression where V.Datatype : Number { + return wrap(rhs) +} + +// MARK: - + +public func %(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func %(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func %(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func %(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func %(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func %(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func %(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func %(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} + +public func <<(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func <<(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func <<(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func <<(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func <<(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func <<(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func <<(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func <<(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} + +public func >>(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func >>(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func >>(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func >>(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func >>(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func >>(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func >>(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func >>(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} + +public func &(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func &(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func &(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func &(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func &(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func &(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func &(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func &(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} + +public func |(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func |(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func |(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func |(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func |(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func |(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func |(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} +public func |(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return infix(lhs, rhs) +} + +public func ^(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return (~(lhs & rhs)) & (lhs | rhs) +} +public func ^(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return (~(lhs & rhs)) & (lhs | rhs) +} +public func ^(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return (~(lhs & rhs)) & (lhs | rhs) +} +public func ^(lhs: Expression, rhs: Expression) -> Expression where V.Datatype == Int64 { + return (~(lhs & rhs)) & (lhs | rhs) +} +public func ^(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return (~(lhs & rhs)) & (lhs | rhs) +} +public func ^(lhs: Expression, rhs: V) -> Expression where V.Datatype == Int64 { + return (~(lhs & rhs)) & (lhs | rhs) +} +public func ^(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return (~(lhs & rhs)) & (lhs | rhs) +} +public func ^(lhs: V, rhs: Expression) -> Expression where V.Datatype == Int64 { + return (~(lhs & rhs)) & (lhs | rhs) +} + +public prefix func ~(rhs: Expression) -> Expression where V.Datatype == Int64 { + return wrap(rhs) +} +public prefix func ~(rhs: Expression) -> Expression where V.Datatype == Int64 { + return wrap(rhs) +} + +// MARK: - + +public func ==(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { + return "=".infix(lhs, rhs) +} +public func ==(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { + return "=".infix(lhs, rhs) +} +public func ==(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { + return "=".infix(lhs, rhs) +} +public func ==(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { + return "=".infix(lhs, rhs) +} +public func ==(lhs: Expression, rhs: V) -> Expression where V.Datatype : Equatable { + return "=".infix(lhs, rhs) +} +public func ==(lhs: Expression, rhs: V?) -> Expression where V.Datatype : Equatable { + guard let rhs = rhs else { return "IS".infix(lhs, Expression(value: nil)) } + return "=".infix(lhs, rhs) +} +public func ==(lhs: V, rhs: Expression) -> Expression where V.Datatype : Equatable { + return "=".infix(lhs, rhs) +} +public func ==(lhs: V?, rhs: Expression) -> Expression where V.Datatype : Equatable { + guard let lhs = lhs else { return "IS".infix(Expression(value: nil), rhs) } + return "=".infix(lhs, rhs) +} + +public func !=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { + return infix(lhs, rhs) +} +public func !=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { + return infix(lhs, rhs) +} +public func !=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { + return infix(lhs, rhs) +} +public func !=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Equatable { + return infix(lhs, rhs) +} +public func !=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Equatable { + return infix(lhs, rhs) +} +public func !=(lhs: Expression, rhs: V?) -> Expression where V.Datatype : Equatable { + guard let rhs = rhs else { return "IS NOT".infix(lhs, Expression(value: nil)) } + return infix(lhs, rhs) +} +public func !=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Equatable { + return infix(lhs, rhs) +} +public func !=(lhs: V?, rhs: Expression) -> Expression where V.Datatype : Equatable { + guard let lhs = lhs else { return "IS NOT".infix(Expression(value: nil), rhs) } + return infix(lhs, rhs) +} + +public func >(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} + +public func >=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func >=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} + +public func <(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} + +public func <=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <=(lhs: Expression, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <=(lhs: Expression, rhs: V) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} +public func <=(lhs: V, rhs: Expression) -> Expression where V.Datatype : Comparable { + return infix(lhs, rhs) +} + +public func ~=(lhs: ClosedRange, rhs: Expression) -> Expression where V.Datatype : Binding & Comparable { + return Expression("\(rhs.template) BETWEEN ? AND ?", rhs.bindings + [lhs.lowerBound as? Binding, lhs.upperBound as? Binding]) +} +public func ~=(lhs: ClosedRange, rhs: Expression) -> Expression where V.Datatype : Binding & Comparable { + return Expression("\(rhs.template) BETWEEN ? AND ?", rhs.bindings + [lhs.lowerBound as? Binding, lhs.upperBound as? Binding]) +} + +// MARK: - + +public func &&(lhs: Expression, rhs: Expression) -> Expression { + return "AND".infix(lhs, rhs) +} +public func &&(lhs: Expression, rhs: Expression) -> Expression { + return "AND".infix(lhs, rhs) +} +public func &&(lhs: Expression, rhs: Expression) -> Expression { + return "AND".infix(lhs, rhs) +} +public func &&(lhs: Expression, rhs: Expression) -> Expression { + return "AND".infix(lhs, rhs) +} +public func &&(lhs: Expression, rhs: Bool) -> Expression { + return "AND".infix(lhs, rhs) +} +public func &&(lhs: Expression, rhs: Bool) -> Expression { + return "AND".infix(lhs, rhs) +} +public func &&(lhs: Bool, rhs: Expression) -> Expression { + return "AND".infix(lhs, rhs) +} +public func &&(lhs: Bool, rhs: Expression) -> Expression { + return "AND".infix(lhs, rhs) +} + +public func ||(lhs: Expression, rhs: Expression) -> Expression { + return "OR".infix(lhs, rhs) +} +public func ||(lhs: Expression, rhs: Expression) -> Expression { + return "OR".infix(lhs, rhs) +} +public func ||(lhs: Expression, rhs: Expression) -> Expression { + return "OR".infix(lhs, rhs) +} +public func ||(lhs: Expression, rhs: Expression) -> Expression { + return "OR".infix(lhs, rhs) +} +public func ||(lhs: Expression, rhs: Bool) -> Expression { + return "OR".infix(lhs, rhs) +} +public func ||(lhs: Expression, rhs: Bool) -> Expression { + return "OR".infix(lhs, rhs) +} +public func ||(lhs: Bool, rhs: Expression) -> Expression { + return "OR".infix(lhs, rhs) +} +public func ||(lhs: Bool, rhs: Expression) -> Expression { + return "OR".infix(lhs, rhs) +} + +public prefix func !(rhs: Expression) -> Expression { + return "NOT ".wrap(rhs) +} +public prefix func !(rhs: Expression) -> Expression { + return "NOT ".wrap(rhs) +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Query.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Query.swift new file mode 100644 index 0000000..c9d2ea9 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Query.swift @@ -0,0 +1,1162 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public protocol QueryType : Expressible { + + var clauses: QueryClauses { get set } + + init(_ name: String, database: String?) + +} + +public protocol SchemaType : QueryType { + + static var identifier: String { get } + +} + +extension SchemaType { + + /// Builds a copy of the query with the `SELECT` clause applied. + /// + /// let users = Table("users") + /// let id = Expression("id") + /// let email = Expression("email") + /// + /// users.select(id, email) + /// // SELECT "id", "email" FROM "users" + /// + /// - Parameter all: A list of expressions to select. + /// + /// - Returns: A query with the given `SELECT` clause applied. + public func select(_ column1: Expressible, _ more: Expressible...) -> Self { + return select(false, [column1] + more) + } + + /// Builds a copy of the query with the `SELECT DISTINCT` clause applied. + /// + /// let users = Table("users") + /// let email = Expression("email") + /// + /// users.select(distinct: email) + /// // SELECT DISTINCT "email" FROM "users" + /// + /// - Parameter columns: A list of expressions to select. + /// + /// - Returns: A query with the given `SELECT DISTINCT` clause applied. + public func select(distinct column1: Expressible, _ more: Expressible...) -> Self { + return select(true, [column1] + more) + } + + /// Builds a copy of the query with the `SELECT` clause applied. + /// + /// let users = Table("users") + /// let id = Expression("id") + /// let email = Expression("email") + /// + /// users.select([id, email]) + /// // SELECT "id", "email" FROM "users" + /// + /// - Parameter all: A list of expressions to select. + /// + /// - Returns: A query with the given `SELECT` clause applied. + public func select(_ all: [Expressible]) -> Self { + return select(false, all) + } + + /// Builds a copy of the query with the `SELECT DISTINCT` clause applied. + /// + /// let users = Table("users") + /// let email = Expression("email") + /// + /// users.select(distinct: [email]) + /// // SELECT DISTINCT "email" FROM "users" + /// + /// - Parameter columns: A list of expressions to select. + /// + /// - Returns: A query with the given `SELECT DISTINCT` clause applied. + public func select(distinct columns: [Expressible]) -> Self { + return select(true, columns) + } + + /// Builds a copy of the query with the `SELECT *` clause applied. + /// + /// let users = Table("users") + /// + /// users.select(*) + /// // SELECT * FROM "users" + /// + /// - Parameter star: A star literal. + /// + /// - Returns: A query with the given `SELECT *` clause applied. + public func select(_ star: Star) -> Self { + return select([star(nil, nil)]) + } + + /// Builds a copy of the query with the `SELECT DISTINCT *` clause applied. + /// + /// let users = Table("users") + /// + /// users.select(distinct: *) + /// // SELECT DISTINCT * FROM "users" + /// + /// - Parameter star: A star literal. + /// + /// - Returns: A query with the given `SELECT DISTINCT *` clause applied. + public func select(distinct star: Star) -> Self { + return select(distinct: [star(nil, nil)]) + } + + /// Builds a scalar copy of the query with the `SELECT` clause applied. + /// + /// let users = Table("users") + /// let id = Expression("id") + /// + /// users.select(id) + /// // SELECT "id" FROM "users" + /// + /// - Parameter all: A list of expressions to select. + /// + /// - Returns: A query with the given `SELECT` clause applied. + public func select(_ column: Expression) -> ScalarQuery { + return select(false, [column]) + } + public func select(_ column: Expression) -> ScalarQuery { + return select(false, [column]) + } + + /// Builds a scalar copy of the query with the `SELECT DISTINCT` clause + /// applied. + /// + /// let users = Table("users") + /// let email = Expression("email") + /// + /// users.select(distinct: email) + /// // SELECT DISTINCT "email" FROM "users" + /// + /// - Parameter column: A list of expressions to select. + /// + /// - Returns: A query with the given `SELECT DISTINCT` clause applied. + public func select(distinct column: Expression) -> ScalarQuery { + return select(true, [column]) + } + public func select(distinct column: Expression) -> ScalarQuery { + return select(true, [column]) + } + + public var count: ScalarQuery { + return select(Expression.count(*)) + } + +} + +extension QueryType { + + fileprivate func select(_ distinct: Bool, _ columns: [Expressible]) -> Q { + var query = Q.init(clauses.from.name, database: clauses.from.database) + query.clauses = clauses + query.clauses.select = (distinct, columns) + return query + } + + // MARK: JOIN + + /// Adds a `JOIN` clause to the query. + /// + /// let users = Table("users") + /// let id = Expression("id") + /// let posts = Table("posts") + /// let userId = Expression("user_id") + /// + /// users.join(posts, on: posts[userId] == users[id]) + /// // SELECT * FROM "users" INNER JOIN "posts" ON ("posts"."user_id" = "users"."id") + /// + /// - Parameters: + /// + /// - table: A query representing the other table. + /// + /// - condition: A boolean expression describing the join condition. + /// + /// - Returns: A query with the given `JOIN` clause applied. + public func join(_ table: QueryType, on condition: Expression) -> Self { + return join(table, on: Expression(condition)) + } + + /// Adds a `JOIN` clause to the query. + /// + /// let users = Table("users") + /// let id = Expression("id") + /// let posts = Table("posts") + /// let userId = Expression("user_id") + /// + /// users.join(posts, on: posts[userId] == users[id]) + /// // SELECT * FROM "users" INNER JOIN "posts" ON ("posts"."user_id" = "users"."id") + /// + /// - Parameters: + /// + /// - table: A query representing the other table. + /// + /// - condition: A boolean expression describing the join condition. + /// + /// - Returns: A query with the given `JOIN` clause applied. + public func join(_ table: QueryType, on condition: Expression) -> Self { + return join(.inner, table, on: condition) + } + + /// Adds a `JOIN` clause to the query. + /// + /// let users = Table("users") + /// let id = Expression("id") + /// let posts = Table("posts") + /// let userId = Expression("user_id") + /// + /// users.join(.LeftOuter, posts, on: posts[userId] == users[id]) + /// // SELECT * FROM "users" LEFT OUTER JOIN "posts" ON ("posts"."user_id" = "users"."id") + /// + /// - Parameters: + /// + /// - type: The `JOIN` operator. + /// + /// - table: A query representing the other table. + /// + /// - condition: A boolean expression describing the join condition. + /// + /// - Returns: A query with the given `JOIN` clause applied. + public func join(_ type: JoinType, _ table: QueryType, on condition: Expression) -> Self { + return join(type, table, on: Expression(condition)) + } + + /// Adds a `JOIN` clause to the query. + /// + /// let users = Table("users") + /// let id = Expression("id") + /// let posts = Table("posts") + /// let userId = Expression("user_id") + /// + /// users.join(.LeftOuter, posts, on: posts[userId] == users[id]) + /// // SELECT * FROM "users" LEFT OUTER JOIN "posts" ON ("posts"."user_id" = "users"."id") + /// + /// - Parameters: + /// + /// - type: The `JOIN` operator. + /// + /// - table: A query representing the other table. + /// + /// - condition: A boolean expression describing the join condition. + /// + /// - Returns: A query with the given `JOIN` clause applied. + public func join(_ type: JoinType, _ table: QueryType, on condition: Expression) -> Self { + var query = self + query.clauses.join.append((type: type, query: table, condition: table.clauses.filters.map { condition && $0 } ?? condition as Expressible)) + return query + } + + // MARK: WHERE + + /// Adds a condition to the query’s `WHERE` clause. + /// + /// let users = Table("users") + /// let id = Expression("id") + /// + /// users.filter(id == 1) + /// // SELECT * FROM "users" WHERE ("id" = 1) + /// + /// - Parameter condition: A boolean expression to filter on. + /// + /// - Returns: A query with the given `WHERE` clause applied. + public func filter(_ predicate: Expression) -> Self { + return filter(Expression(predicate)) + } + + /// Adds a condition to the query’s `WHERE` clause. + /// + /// let users = Table("users") + /// let age = Expression("age") + /// + /// users.filter(age >= 35) + /// // SELECT * FROM "users" WHERE ("age" >= 35) + /// + /// - Parameter condition: A boolean expression to filter on. + /// + /// - Returns: A query with the given `WHERE` clause applied. + public func filter(_ predicate: Expression) -> Self { + var query = self + query.clauses.filters = query.clauses.filters.map { $0 && predicate } ?? predicate + return query + } + + /// Adds a condition to the query’s `WHERE` clause. + /// This is an alias for `filter(predicate)` + public func `where`(_ predicate: Expression) -> Self { + return `where`(Expression(predicate)) + } + + /// Adds a condition to the query’s `WHERE` clause. + /// This is an alias for `filter(predicate)` + public func `where`(_ predicate: Expression) -> Self { + return filter(predicate) + } + + // MARK: GROUP BY + + /// Sets a `GROUP BY` clause on the query. + /// + /// - Parameter by: A list of columns to group by. + /// + /// - Returns: A query with the given `GROUP BY` clause applied. + public func group(_ by: Expressible...) -> Self { + return group(by) + } + + /// Sets a `GROUP BY` clause on the query. + /// + /// - Parameter by: A list of columns to group by. + /// + /// - Returns: A query with the given `GROUP BY` clause applied. + public func group(_ by: [Expressible]) -> Self { + return group(by, nil) + } + + /// Sets a `GROUP BY`-`HAVING` clause on the query. + /// + /// - Parameters: + /// + /// - by: A column to group by. + /// + /// - having: A condition determining which groups are returned. + /// + /// - Returns: A query with the given `GROUP BY`–`HAVING` clause applied. + public func group(_ by: Expressible, having: Expression) -> Self { + return group([by], having: having) + } + + /// Sets a `GROUP BY`-`HAVING` clause on the query. + /// + /// - Parameters: + /// + /// - by: A column to group by. + /// + /// - having: A condition determining which groups are returned. + /// + /// - Returns: A query with the given `GROUP BY`–`HAVING` clause applied. + public func group(_ by: Expressible, having: Expression) -> Self { + return group([by], having: having) + } + + /// Sets a `GROUP BY`-`HAVING` clause on the query. + /// + /// - Parameters: + /// + /// - by: A list of columns to group by. + /// + /// - having: A condition determining which groups are returned. + /// + /// - Returns: A query with the given `GROUP BY`–`HAVING` clause applied. + public func group(_ by: [Expressible], having: Expression) -> Self { + return group(by, Expression(having)) + } + + /// Sets a `GROUP BY`-`HAVING` clause on the query. + /// + /// - Parameters: + /// + /// - by: A list of columns to group by. + /// + /// - having: A condition determining which groups are returned. + /// + /// - Returns: A query with the given `GROUP BY`–`HAVING` clause applied. + public func group(_ by: [Expressible], having: Expression) -> Self { + return group(by, having) + } + + fileprivate func group(_ by: [Expressible], _ having: Expression?) -> Self { + var query = self + query.clauses.group = (by, having) + return query + } + + // MARK: ORDER BY + + /// Sets an `ORDER BY` clause on the query. + /// + /// let users = Table("users") + /// let email = Expression("email") + /// let name = Expression("name") + /// + /// users.order(email.desc, name.asc) + /// // SELECT * FROM "users" ORDER BY "email" DESC, "name" ASC + /// + /// - Parameter by: An ordered list of columns and directions to sort by. + /// + /// - Returns: A query with the given `ORDER BY` clause applied. + public func order(_ by: Expressible...) -> Self { + return order(by) + } + + /// Sets an `ORDER BY` clause on the query. + /// + /// let users = Table("users") + /// let email = Expression("email") + /// let name = Expression("name") + /// + /// users.order([email.desc, name.asc]) + /// // SELECT * FROM "users" ORDER BY "email" DESC, "name" ASC + /// + /// - Parameter by: An ordered list of columns and directions to sort by. + /// + /// - Returns: A query with the given `ORDER BY` clause applied. + public func order(_ by: [Expressible]) -> Self { + var query = self + query.clauses.order = by + return query + } + + // MARK: LIMIT/OFFSET + + /// Sets the LIMIT clause (and resets any OFFSET clause) on the query. + /// + /// let users = Table("users") + /// + /// users.limit(20) + /// // SELECT * FROM "users" LIMIT 20 + /// + /// - Parameter length: The maximum number of rows to return (or `nil` to + /// return unlimited rows). + /// + /// - Returns: A query with the given LIMIT clause applied. + public func limit(_ length: Int?) -> Self { + return limit(length, nil) + } + + /// Sets LIMIT and OFFSET clauses on the query. + /// + /// let users = Table("users") + /// + /// users.limit(20, offset: 20) + /// // SELECT * FROM "users" LIMIT 20 OFFSET 20 + /// + /// - Parameters: + /// + /// - length: The maximum number of rows to return. + /// + /// - offset: The number of rows to skip. + /// + /// - Returns: A query with the given LIMIT and OFFSET clauses applied. + public func limit(_ length: Int, offset: Int) -> Self { + return limit(length, offset) + } + + // prevents limit(nil, offset: 5) + fileprivate func limit(_ length: Int?, _ offset: Int?) -> Self { + var query = self + query.clauses.limit = length.map { ($0, offset) } + return query + } + + // MARK: - Clauses + // + // MARK: SELECT + + // MARK: - + + fileprivate var selectClause: Expressible { + return " ".join([ + Expression(literal: clauses.select.distinct ? "SELECT DISTINCT" : "SELECT"), + ", ".join(clauses.select.columns), + Expression(literal: "FROM"), + tableName(alias: true) + ]) + } + + fileprivate var joinClause: Expressible? { + guard !clauses.join.isEmpty else { + return nil + } + + return " ".join(clauses.join.map { type, query, condition in + " ".join([ + Expression(literal: "\(type.rawValue) JOIN"), + query.tableName(alias: true), + Expression(literal: "ON"), + condition + ]) + }) + } + + fileprivate var whereClause: Expressible? { + guard let filters = clauses.filters else { + return nil + } + + return " ".join([ + Expression(literal: "WHERE"), + filters + ]) + } + + fileprivate var groupByClause: Expressible? { + guard let group = clauses.group else { + return nil + } + + let groupByClause = " ".join([ + Expression(literal: "GROUP BY"), + ", ".join(group.by) + ]) + + guard let having = group.having else { + return groupByClause + } + + return " ".join([ + groupByClause, + " ".join([ + Expression(literal: "HAVING"), + having + ]) + ]) + } + + fileprivate var orderClause: Expressible? { + guard !clauses.order.isEmpty else { + return nil + } + + return " ".join([ + Expression(literal: "ORDER BY"), + ", ".join(clauses.order) + ]) + } + + fileprivate var limitOffsetClause: Expressible? { + guard let limit = clauses.limit else { + return nil + } + + let limitClause = Expression(literal: "LIMIT \(limit.length)") + + guard let offset = limit.offset else { + return limitClause + } + + return " ".join([ + limitClause, + Expression(literal: "OFFSET \(offset)") + ]) + } + + // MARK: - + + public func alias(_ aliasName: String) -> Self { + var query = self + query.clauses.from = (clauses.from.name, aliasName, clauses.from.database) + return query + } + + // MARK: - Operations + // + // MARK: INSERT + + public func insert(_ value: Setter, _ more: Setter...) -> Insert { + return insert([value] + more) + } + + public func insert(_ values: [Setter]) -> Insert { + return insert(nil, values) + } + + public func insert(or onConflict: OnConflict, _ values: Setter...) -> Insert { + return insert(or: onConflict, values) + } + + public func insert(or onConflict: OnConflict, _ values: [Setter]) -> Insert { + return insert(onConflict, values) + } + + fileprivate func insert(_ or: OnConflict?, _ values: [Setter]) -> Insert { + let insert = values.reduce((columns: [Expressible](), values: [Expressible]())) { insert, setter in + (insert.columns + [setter.column], insert.values + [setter.value]) + } + + let clauses: [Expressible?] = [ + Expression(literal: "INSERT"), + or.map { Expression(literal: "OR \($0.rawValue)") }, + Expression(literal: "INTO"), + tableName(), + "".wrap(insert.columns) as Expression, + Expression(literal: "VALUES"), + "".wrap(insert.values) as Expression, + whereClause + ] + + return Insert(" ".join(clauses.flatMap { $0 }).expression) + } + + /// Runs an `INSERT` statement against the query with `DEFAULT VALUES`. + public func insert() -> Insert { + return Insert(" ".join([ + Expression(literal: "INSERT INTO"), + tableName(), + Expression(literal: "DEFAULT VALUES") + ]).expression) + } + + /// Runs an `INSERT` statement against the query with the results of another + /// query. + /// + /// - Parameter query: A query to `SELECT` results from. + /// + /// - Returns: The number of updated rows and statement. + public func insert(_ query: QueryType) -> Update { + return Update(" ".join([ + Expression(literal: "INSERT INTO"), + tableName(), + query.expression + ]).expression) + } + + // MARK: UPDATE + + public func update(_ values: Setter...) -> Update { + return update(values) + } + + public func update(_ values: [Setter]) -> Update { + let clauses: [Expressible?] = [ + Expression(literal: "UPDATE"), + tableName(), + Expression(literal: "SET"), + ", ".join(values.map { " = ".join([$0.column, $0.value]) }), + whereClause + ] + + return Update(" ".join(clauses.flatMap { $0 }).expression) + } + + // MARK: DELETE + + public func delete() -> Delete { + let clauses: [Expressible?] = [ + Expression(literal: "DELETE FROM"), + tableName(), + whereClause + ] + + return Delete(" ".join(clauses.flatMap { $0 }).expression) + } + + // MARK: EXISTS + + public var exists: Select { + return Select(" ".join([ + Expression(literal: "SELECT EXISTS"), + "".wrap(expression) as Expression + ]).expression) + } + + // MARK: - + + /// Prefixes a column expression with the query’s table name or alias. + /// + /// - Parameter column: A column expression. + /// + /// - Returns: A column expression namespaced with the query’s table name or + /// alias. + public func namespace(_ column: Expression) -> Expression { + return Expression(".".join([tableName(), column]).expression) + } + + // FIXME: rdar://problem/18673897 // subscript… + + public subscript(column: Expression) -> Expression { + return namespace(column) + } + public subscript(column: Expression) -> Expression { + return namespace(column) + } + + public subscript(column: Expression) -> Expression { + return namespace(column) + } + public subscript(column: Expression) -> Expression { + return namespace(column) + } + + public subscript(column: Expression) -> Expression { + return namespace(column) + } + public subscript(column: Expression) -> Expression { + return namespace(column) + } + + public subscript(column: Expression) -> Expression { + return namespace(column) + } + public subscript(column: Expression) -> Expression { + return namespace(column) + } + + public subscript(column: Expression) -> Expression { + return namespace(column) + } + public subscript(column: Expression) -> Expression { + return namespace(column) + } + + public subscript(column: Expression) -> Expression { + return namespace(column) + } + public subscript(column: Expression) -> Expression { + return namespace(column) + } + + /// Prefixes a star with the query’s table name or alias. + /// + /// - Parameter star: A literal `*`. + /// + /// - Returns: A `*` expression namespaced with the query’s table name or + /// alias. + public subscript(star: Star) -> Expression { + return namespace(star(nil, nil)) + } + + // MARK: - + + // TODO: alias support + func tableName(alias aliased: Bool = false) -> Expressible { + guard let alias = clauses.from.alias , aliased else { + return database(namespace: clauses.from.alias ?? clauses.from.name) + } + + return " ".join([ + database(namespace: clauses.from.name), + Expression(literal: "AS"), + Expression(alias) + ]) + } + + func tableName(qualified: Bool) -> Expressible { + if qualified { + return tableName() + } + return Expression(clauses.from.alias ?? clauses.from.name) + } + + func database(namespace name: String) -> Expressible { + let name = Expression(name) + + guard let database = clauses.from.database else { + return name + } + + return ".".join([Expression(database), name]) + } + + public var expression: Expression { + let clauses: [Expressible?] = [ + selectClause, + joinClause, + whereClause, + groupByClause, + orderClause, + limitOffsetClause + ] + + return " ".join(clauses.flatMap { $0 }).expression + } + +} + +// TODO: decide: simplify the below with a boxed type instead + +/// Queries a collection of chainable helper functions and expressions to build +/// executable SQL statements. +public struct Table : SchemaType { + + public static let identifier = "TABLE" + + public var clauses: QueryClauses + + public init(_ name: String, database: String? = nil) { + clauses = QueryClauses(name, alias: nil, database: database) + } + +} + +public struct View : SchemaType { + + public static let identifier = "VIEW" + + public var clauses: QueryClauses + + public init(_ name: String, database: String? = nil) { + clauses = QueryClauses(name, alias: nil, database: database) + } + +} + +public struct VirtualTable : SchemaType { + + public static let identifier = "VIRTUAL TABLE" + + public var clauses: QueryClauses + + public init(_ name: String, database: String? = nil) { + clauses = QueryClauses(name, alias: nil, database: database) + } + +} + +// TODO: make `ScalarQuery` work in `QueryType.select()`, `.filter()`, etc. + +public struct ScalarQuery : QueryType { + + public var clauses: QueryClauses + + public init(_ name: String, database: String? = nil) { + clauses = QueryClauses(name, alias: nil, database: database) + } + +} + +// TODO: decide: simplify the below with a boxed type instead + +public struct Select : ExpressionType { + + public var template: String + public var bindings: [Binding?] + + public init(_ template: String, _ bindings: [Binding?]) { + self.template = template + self.bindings = bindings + } + +} + +public struct Insert : ExpressionType { + + public var template: String + public var bindings: [Binding?] + + public init(_ template: String, _ bindings: [Binding?]) { + self.template = template + self.bindings = bindings + } + +} + +public struct Update : ExpressionType { + + public var template: String + public var bindings: [Binding?] + + public init(_ template: String, _ bindings: [Binding?]) { + self.template = template + self.bindings = bindings + } + +} + +public struct Delete : ExpressionType { + + public var template: String + public var bindings: [Binding?] + + public init(_ template: String, _ bindings: [Binding?]) { + self.template = template + self.bindings = bindings + } + +} + +extension Connection { + + public func prepare(_ query: QueryType) throws -> AnySequence { + let expression = query.expression + let statement = try prepare(expression.template, expression.bindings) + + let columnNames: [String: Int] = try { + var (columnNames, idx) = ([String: Int](), 0) + column: for each in query.clauses.select.columns { + var names = each.expression.template.characters.split { $0 == "." }.map(String.init) + let column = names.removeLast() + let namespace = names.joined(separator: ".") + + func expandGlob(_ namespace: Bool) -> ((QueryType) throws -> Void) { + return { (query: QueryType) throws -> (Void) in + var q = type(of: query).init(query.clauses.from.name, database: query.clauses.from.database) + q.clauses.select = query.clauses.select + let e = q.expression + var names = try self.prepare(e.template, e.bindings).columnNames.map { $0.quote() } + if namespace { names = names.map { "\(query.tableName().expression.template).\($0)" } } + for name in names { columnNames[name] = idx; idx += 1 } + } + } + + if column == "*" { + var select = query + select.clauses.select = (false, [Expression(literal: "*") as Expressible]) + let queries = [select] + query.clauses.join.map { $0.query } + if !namespace.isEmpty { + for q in queries { + if q.tableName().expression.template == namespace { + try expandGlob(true)(q) + continue column + } + } + fatalError("no such table: \(namespace)") + } + for q in queries { + try expandGlob(query.clauses.join.count > 0)(q) + } + continue + } + + columnNames[each.expression.template] = idx + idx += 1 + } + return columnNames + }() + + return AnySequence { + AnyIterator { statement.next().map { Row(columnNames, $0) } } + } + } + + public func scalar(_ query: ScalarQuery) throws -> V { + let expression = query.expression + return value(try scalar(expression.template, expression.bindings)) + } + + public func scalar(_ query: ScalarQuery) throws -> V.ValueType? { + let expression = query.expression + guard let value = try scalar(expression.template, expression.bindings) as? V.Datatype else { return nil } + return V.fromDatatypeValue(value) + } + + public func scalar(_ query: Select) throws -> V { + let expression = query.expression + return value(try scalar(expression.template, expression.bindings)) + } + + public func scalar(_ query: Select) throws -> V.ValueType? { + let expression = query.expression + guard let value = try scalar(expression.template, expression.bindings) as? V.Datatype else { return nil } + return V.fromDatatypeValue(value) + } + + public func pluck(_ query: QueryType) throws -> Row? { + return try prepare(query.limit(1, query.clauses.limit?.offset)).makeIterator().next() + } + + /// Runs an `Insert` query. + /// + /// - SeeAlso: `QueryType.insert(value:_:)` + /// - SeeAlso: `QueryType.insert(values:)` + /// - SeeAlso: `QueryType.insert(or:_:)` + /// - SeeAlso: `QueryType.insert()` + /// + /// - Parameter query: An insert query. + /// + /// - Returns: The insert’s rowid. + @discardableResult public func run(_ query: Insert) throws -> Int64 { + let expression = query.expression + return try sync { + try self.run(expression.template, expression.bindings) + return self.lastInsertRowid + } + } + + /// Runs an `Update` query. + /// + /// - SeeAlso: `QueryType.insert(query:)` + /// - SeeAlso: `QueryType.update(values:)` + /// + /// - Parameter query: An update query. + /// + /// - Returns: The number of updated rows. + @discardableResult public func run(_ query: Update) throws -> Int { + let expression = query.expression + return try sync { + try self.run(expression.template, expression.bindings) + return self.changes + } + } + + /// Runs a `Delete` query. + /// + /// - SeeAlso: `QueryType.delete()` + /// + /// - Parameter query: A delete query. + /// + /// - Returns: The number of deleted rows. + @discardableResult public func run(_ query: Delete) throws -> Int { + let expression = query.expression + return try sync { + try self.run(expression.template, expression.bindings) + return self.changes + } + } + +} + +public struct Row { + + fileprivate let columnNames: [String: Int] + + fileprivate let values: [Binding?] + + fileprivate init(_ columnNames: [String: Int], _ values: [Binding?]) { + self.columnNames = columnNames + self.values = values + } + + /// Returns a row’s value for the given column. + /// + /// - Parameter column: An expression representing a column selected in a Query. + /// + /// - Returns: The value for the given column. + public func get(_ column: Expression) -> V { + return get(Expression(column))! + } + public func get(_ column: Expression) -> V? { + func valueAtIndex(_ idx: Int) -> V? { + guard let value = values[idx] as? V.Datatype else { return nil } + return (V.fromDatatypeValue(value) as? V)! + } + + guard let idx = columnNames[column.template] else { + let similar = Array(columnNames.keys).filter { $0.hasSuffix(".\(column.template)") } + + switch similar.count { + case 0: + fatalError("no such column '\(column.template)' in columns: \(columnNames.keys.sorted())") + case 1: + return valueAtIndex(columnNames[similar[0]]!) + default: + fatalError("ambiguous column '\(column.template)' (please disambiguate: \(similar))") + } + } + + return valueAtIndex(idx) + } + + // FIXME: rdar://problem/18673897 // subscript… + + public subscript(column: Expression) -> Blob { + return get(column) + } + public subscript(column: Expression) -> Blob? { + return get(column) + } + + public subscript(column: Expression) -> Bool { + return get(column) + } + public subscript(column: Expression) -> Bool? { + return get(column) + } + + public subscript(column: Expression) -> Double { + return get(column) + } + public subscript(column: Expression) -> Double? { + return get(column) + } + + public subscript(column: Expression) -> Int { + return get(column) + } + public subscript(column: Expression) -> Int? { + return get(column) + } + + public subscript(column: Expression) -> Int64 { + return get(column) + } + public subscript(column: Expression) -> Int64? { + return get(column) + } + + public subscript(column: Expression) -> String { + return get(column) + } + public subscript(column: Expression) -> String? { + return get(column) + } + +} + +/// Determines the join operator for a query’s `JOIN` clause. +public enum JoinType : String { + + /// A `CROSS` join. + case cross = "CROSS" + + /// An `INNER` join. + case inner = "INNER" + + /// A `LEFT OUTER` join. + case leftOuter = "LEFT OUTER" + +} + +/// ON CONFLICT resolutions. +public enum OnConflict: String { + + case replace = "REPLACE" + + case rollback = "ROLLBACK" + + case abort = "ABORT" + + case fail = "FAIL" + + case ignore = "IGNORE" + +} + +// MARK: - Private + +public struct QueryClauses { + + var select = (distinct: false, columns: [Expression(literal: "*") as Expressible]) + + var from: (name: String, alias: String?, database: String?) + + var join = [(type: JoinType, query: QueryType, condition: Expressible)]() + + var filters: Expression? + + var group: (by: [Expressible], having: Expression?)? + + var order = [Expressible]() + + var limit: (length: Int, offset: Int?)? + + fileprivate init(_ name: String, alias: String?, database: String?) { + self.from = (name, alias, database) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Schema.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Schema.swift new file mode 100644 index 0000000..1388170 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Schema.swift @@ -0,0 +1,519 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +extension SchemaType { + + // MARK: - DROP TABLE / VIEW / VIRTUAL TABLE + + public func drop(ifExists: Bool = false) -> String { + return drop("TABLE", tableName(), ifExists) + } + +} + +extension Table { + + // MARK: - CREATE TABLE + + public func create(temporary: Bool = false, ifNotExists: Bool = false, block: (TableBuilder) -> Void) -> String { + let builder = TableBuilder() + + block(builder) + + let clauses: [Expressible?] = [ + create(Table.identifier, tableName(), temporary ? .Temporary : nil, ifNotExists), + "".wrap(builder.definitions) as Expression + ] + + return " ".join(clauses.flatMap { $0 }).asSQL() + } + + public func create(_ query: QueryType, temporary: Bool = false, ifNotExists: Bool = false) -> String { + let clauses: [Expressible?] = [ + create(Table.identifier, tableName(), temporary ? .Temporary : nil, ifNotExists), + Expression(literal: "AS"), + query + ] + + return " ".join(clauses.flatMap { $0 }).asSQL() + } + + // MARK: - ALTER TABLE … ADD COLUMN + + public func addColumn(_ name: Expression, check: Expression? = nil, defaultValue: V) -> String { + return addColumn(definition(name, V.declaredDatatype, nil, false, false, check, defaultValue, nil, nil)) + } + + public func addColumn(_ name: Expression, check: Expression, defaultValue: V) -> String { + return addColumn(definition(name, V.declaredDatatype, nil, false, false, check, defaultValue, nil, nil)) + } + + public func addColumn(_ name: Expression, check: Expression? = nil, defaultValue: V? = nil) -> String { + return addColumn(definition(name, V.declaredDatatype, nil, true, false, check, defaultValue, nil, nil)) + } + + public func addColumn(_ name: Expression, check: Expression, defaultValue: V? = nil) -> String { + return addColumn(definition(name, V.declaredDatatype, nil, true, false, check, defaultValue, nil, nil)) + } + + public func addColumn(_ name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) -> String where V.Datatype == Int64 { + return addColumn(definition(name, V.declaredDatatype, nil, false, unique, check, nil, (table, other), nil)) + } + + public func addColumn(_ name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) -> String where V.Datatype == Int64 { + return addColumn(definition(name, V.declaredDatatype, nil, false, unique, check, nil, (table, other), nil)) + } + + public func addColumn(_ name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) -> String where V.Datatype == Int64 { + return addColumn(definition(name, V.declaredDatatype, nil, true, unique, check, nil, (table, other), nil)) + } + + public func addColumn(_ name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) -> String where V.Datatype == Int64 { + return addColumn(definition(name, V.declaredDatatype, nil, true, unique, check, nil, (table, other), nil)) + } + + public func addColumn(_ name: Expression, check: Expression? = nil, defaultValue: V, collate: Collation) -> String where V.Datatype == String { + return addColumn(definition(name, V.declaredDatatype, nil, false, false, check, defaultValue, nil, collate)) + } + + public func addColumn(_ name: Expression, check: Expression, defaultValue: V, collate: Collation) -> String where V.Datatype == String { + return addColumn(definition(name, V.declaredDatatype, nil, false, false, check, defaultValue, nil, collate)) + } + + public func addColumn(_ name: Expression, check: Expression? = nil, defaultValue: V? = nil, collate: Collation) -> String where V.Datatype == String { + return addColumn(definition(name, V.declaredDatatype, nil, true, false, check, defaultValue, nil, collate)) + } + + public func addColumn(_ name: Expression, check: Expression, defaultValue: V? = nil, collate: Collation) -> String where V.Datatype == String { + return addColumn(definition(name, V.declaredDatatype, nil, true, false, check, defaultValue, nil, collate)) + } + + fileprivate func addColumn(_ expression: Expressible) -> String { + return " ".join([ + Expression(literal: "ALTER TABLE"), + tableName(), + Expression(literal: "ADD COLUMN"), + expression + ]).asSQL() + } + + // MARK: - ALTER TABLE … RENAME TO + + public func rename(_ to: Table) -> String { + return rename(to: to) + } + + // MARK: - CREATE INDEX + + public func createIndex(_ columns: Expressible...) -> String { + return createIndex(columns) + } + + public func createIndex(_ columns: [Expressible], unique: Bool = false, ifNotExists: Bool = false) -> String { + let clauses: [Expressible?] = [ + create("INDEX", indexName(columns), unique ? .Unique : nil, ifNotExists), + Expression(literal: "ON"), + tableName(qualified: false), + "".wrap(columns) as Expression + ] + + return " ".join(clauses.flatMap { $0 }).asSQL() + } + + // MARK: - DROP INDEX + + public func dropIndex(_ columns: Expressible...) -> String { + return dropIndex(columns) + } + + public func dropIndex(_ columns: [Expressible], ifExists: Bool = false) -> String { + return drop("INDEX", indexName(columns), ifExists) + } + + fileprivate func indexName(_ columns: [Expressible]) -> Expressible { + let string = (["index", clauses.from.name, "on"] + columns.map { $0.expression.template }).joined(separator: " ").lowercased() + + let index = string.characters.reduce("") { underscored, character in + guard character != "\"" else { + return underscored + } + guard "a"..."z" ~= character || "0"..."9" ~= character else { + return underscored + "_" + } + return underscored + String(character) + } + + return database(namespace: index) + } + +} + +extension View { + + // MARK: - CREATE VIEW + + public func create(_ query: QueryType, temporary: Bool = false, ifNotExists: Bool = false) -> String { + let clauses: [Expressible?] = [ + create(View.identifier, tableName(), temporary ? .Temporary : nil, ifNotExists), + Expression(literal: "AS"), + query + ] + + return " ".join(clauses.flatMap { $0 }).asSQL() + } + + // MARK: - DROP VIEW + + public func drop(ifExists: Bool = false) -> String { + return drop("VIEW", tableName(), ifExists) + } + +} + +extension VirtualTable { + + // MARK: - CREATE VIRTUAL TABLE + + public func create(_ using: Module, ifNotExists: Bool = false) -> String { + let clauses: [Expressible?] = [ + create(VirtualTable.identifier, tableName(), nil, ifNotExists), + Expression(literal: "USING"), + using + ] + + return " ".join(clauses.flatMap { $0 }).asSQL() + } + + // MARK: - ALTER TABLE … RENAME TO + + public func rename(_ to: VirtualTable) -> String { + return rename(to: to) + } + +} + +public final class TableBuilder { + + fileprivate var definitions = [Expressible]() + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil) { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V) { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil) { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: V) { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil) { + column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression) { + column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V) { + column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil) { + column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression) { + column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: V) { + column(name, V.declaredDatatype, nil, true, unique, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, primaryKey: Bool, check: Expression? = nil, defaultValue: Expression? = nil) { + column(name, V.declaredDatatype, primaryKey ? .default : nil, false, false, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, primaryKey: Bool, check: Expression, defaultValue: Expression? = nil) { + column(name, V.declaredDatatype, primaryKey ? .default : nil, false, false, check, defaultValue, nil, nil) + } + + public func column(_ name: Expression, primaryKey: PrimaryKey, check: Expression? = nil) where V.Datatype == Int64 { + column(name, V.declaredDatatype, primaryKey, false, false, check, nil, nil, nil) + } + + public func column(_ name: Expression, primaryKey: PrimaryKey, check: Expression) where V.Datatype == Int64 { + column(name, V.declaredDatatype, primaryKey, false, false, check, nil, nil, nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) where V.Datatype == Int64 { + column(name, V.declaredDatatype, nil, false, unique, check, nil, (table, other), nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) where V.Datatype == Int64 { + column(name, V.declaredDatatype, nil, false, unique, check, nil, (table, other), nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, references table: QueryType, _ other: Expression) where V.Datatype == Int64 { + column(name, V.declaredDatatype, nil, true, unique, check, nil, (table, other), nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, references table: QueryType, _ other: Expression) where V.Datatype == Int64 { + column(name, V.declaredDatatype, nil, true, unique, check, nil, (table, other), nil) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: V, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression? = nil, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: Expression, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression? = nil, defaultValue: V, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression? = nil, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: Expression, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + public func column(_ name: Expression, unique: Bool = false, check: Expression, defaultValue: V, collate: Collation) where V.Datatype == String { + column(name, V.declaredDatatype, nil, false, unique, check, defaultValue, nil, collate) + } + + fileprivate func column(_ name: Expressible, _ datatype: String, _ primaryKey: PrimaryKey?, _ null: Bool, _ unique: Bool, _ check: Expressible?, _ defaultValue: Expressible?, _ references: (QueryType, Expressible)?, _ collate: Collation?) { + definitions.append(definition(name, datatype, primaryKey, null, unique, check, defaultValue, references, collate)) + } + + // MARK: - + + public func primaryKey(_ column: Expression) { + primaryKey([column]) + } + + public func primaryKey(_ compositeA: Expression, _ b: Expression) { + primaryKey([compositeA, b]) + } + + public func primaryKey(_ compositeA: Expression, _ b: Expression, _ c: Expression) { + primaryKey([compositeA, b, c]) + } + + fileprivate func primaryKey(_ composite: [Expressible]) { + definitions.append("PRIMARY KEY".prefix(composite)) + } + + public func unique(_ columns: Expressible...) { + unique(columns) + } + + public func unique(_ columns: [Expressible]) { + definitions.append("UNIQUE".prefix(columns)) + } + + public func check(_ condition: Expression) { + check(Expression(condition)) + } + + public func check(_ condition: Expression) { + definitions.append("CHECK".prefix(condition)) + } + + public enum Dependency: String { + + case noAction = "NO ACTION" + + case restrict = "RESTRICT" + + case setNull = "SET NULL" + + case setDefault = "SET DEFAULT" + + case cascade = "CASCADE" + + } + + public func foreignKey(_ column: Expression, references table: QueryType, _ other: Expression, update: Dependency? = nil, delete: Dependency? = nil) { + foreignKey(column, (table, other), update, delete) + } + + public func foreignKey(_ column: Expression, references table: QueryType, _ other: Expression, update: Dependency? = nil, delete: Dependency? = nil) { + foreignKey(column, (table, other), update, delete) + } + + public func foreignKey(_ composite: (Expression, Expression), references table: QueryType, _ other: (Expression, Expression), update: Dependency? = nil, delete: Dependency? = nil) { + let composite = ", ".join([composite.0, composite.1]) + let references = (table, ", ".join([other.0, other.1])) + + foreignKey(composite, references, update, delete) + } + + public func foreignKey(_ composite: (Expression, Expression, Expression), references table: QueryType, _ other: (Expression, Expression, Expression), update: Dependency? = nil, delete: Dependency? = nil) { + let composite = ", ".join([composite.0, composite.1, composite.2]) + let references = (table, ", ".join([other.0, other.1, other.2])) + + foreignKey(composite, references, update, delete) + } + + fileprivate func foreignKey(_ column: Expressible, _ references: (QueryType, Expressible), _ update: Dependency?, _ delete: Dependency?) { + let clauses: [Expressible?] = [ + "FOREIGN KEY".prefix(column), + reference(references), + update.map { Expression(literal: "ON UPDATE \($0.rawValue)") }, + delete.map { Expression(literal: "ON DELETE \($0.rawValue)") } + ] + + definitions.append(" ".join(clauses.flatMap { $0 })) + } + +} + +public enum PrimaryKey { + + case `default` + + case autoincrement + +} + +public struct Module { + + fileprivate let name: String + + fileprivate let arguments: [Expressible] + + public init(_ name: String, _ arguments: [Expressible]) { + self.init(name: name.quote(), arguments: arguments) + } + + init(name: String, arguments: [Expressible]) { + self.name = name + self.arguments = arguments + } + +} + +extension Module : Expressible { + + public var expression: Expression { + return name.wrap(arguments) + } + +} + +// MARK: - Private + +private extension QueryType { + + func create(_ identifier: String, _ name: Expressible, _ modifier: Modifier?, _ ifNotExists: Bool) -> Expressible { + let clauses: [Expressible?] = [ + Expression(literal: "CREATE"), + modifier.map { Expression(literal: $0.rawValue) }, + Expression(literal: identifier), + ifNotExists ? Expression(literal: "IF NOT EXISTS") : nil, + name + ] + + return " ".join(clauses.flatMap { $0 }) + } + + func rename(to: Self) -> String { + return " ".join([ + Expression(literal: "ALTER TABLE"), + tableName(), + Expression(literal: "RENAME TO"), + Expression(to.clauses.from.name) + ]).asSQL() + } + + func drop(_ identifier: String, _ name: Expressible, _ ifExists: Bool) -> String { + let clauses: [Expressible?] = [ + Expression(literal: "DROP \(identifier)"), + ifExists ? Expression(literal: "IF EXISTS") : nil, + name + ] + + return " ".join(clauses.flatMap { $0 }).asSQL() + } + +} + +private func definition(_ column: Expressible, _ datatype: String, _ primaryKey: PrimaryKey?, _ null: Bool, _ unique: Bool, _ check: Expressible?, _ defaultValue: Expressible?, _ references: (QueryType, Expressible)?, _ collate: Collation?) -> Expressible { + let clauses: [Expressible?] = [ + column, + Expression(literal: datatype), + primaryKey.map { Expression(literal: $0 == .autoincrement ? "PRIMARY KEY AUTOINCREMENT" : "PRIMARY KEY") }, + null ? nil : Expression(literal: "NOT NULL"), + unique ? Expression(literal: "UNIQUE") : nil, + check.map { " ".join([Expression(literal: "CHECK"), $0]) }, + defaultValue.map { "DEFAULT".prefix($0) }, + references.map(reference), + collate.map { " ".join([Expression(literal: "COLLATE"), $0]) } + ] + + return " ".join(clauses.flatMap { $0 }) +} + +private func reference(_ primary: (QueryType, Expressible)) -> Expressible { + return " ".join([ + Expression(literal: "REFERENCES"), + primary.0.tableName(qualified: false), + "".wrap(primary.1) as Expression + ]) +} + +private enum Modifier : String { + + case Unique = "UNIQUE" + + case Temporary = "TEMPORARY" + +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Setter.swift b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Setter.swift new file mode 100644 index 0000000..86f16fc --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLite/Typed/Setter.swift @@ -0,0 +1,277 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +precedencegroup ColumnAssignment { + associativity: left + assignment: true + lowerThan: AssignmentPrecedence +} + +infix operator <- : ColumnAssignment + +public struct Setter { + + let column: Expressible + let value: Expressible + + fileprivate init(column: Expression, value: Expression) { + self.column = column + self.value = value + } + + fileprivate init(column: Expression, value: V) { + self.column = column + self.value = value + } + + fileprivate init(column: Expression, value: Expression) { + self.column = column + self.value = value + } + + fileprivate init(column: Expression, value: Expression) { + self.column = column + self.value = value + } + + fileprivate init(column: Expression, value: V?) { + self.column = column + self.value = Expression(value: value) + } + +} + +extension Setter : Expressible { + + public var expression: Expression { + return "=".infix(column, value, wrap: false) + } + +} + +public func <-(column: Expression, value: Expression) -> Setter { + return Setter(column: column, value: value) +} +public func <-(column: Expression, value: V) -> Setter { + return Setter(column: column, value: value) +} +public func <-(column: Expression, value: Expression) -> Setter { + return Setter(column: column, value: value) +} +public func <-(column: Expression, value: Expression) -> Setter { + return Setter(column: column, value: value) +} +public func <-(column: Expression, value: V?) -> Setter { + return Setter(column: column, value: value) +} + +public func +=(column: Expression, value: Expression) -> Setter { + return column <- column + value +} +public func +=(column: Expression, value: String) -> Setter { + return column <- column + value +} +public func +=(column: Expression, value: Expression) -> Setter { + return column <- column + value +} +public func +=(column: Expression, value: Expression) -> Setter { + return column <- column + value +} +public func +=(column: Expression, value: String) -> Setter { + return column <- column + value +} + +public func +=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column + value +} +public func +=(column: Expression, value: V) -> Setter where V.Datatype : Number { + return column <- column + value +} +public func +=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column + value +} +public func +=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column + value +} +public func +=(column: Expression, value: V) -> Setter where V.Datatype : Number { + return column <- column + value +} + +public func -=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column - value +} +public func -=(column: Expression, value: V) -> Setter where V.Datatype : Number { + return column <- column - value +} +public func -=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column - value +} +public func -=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column - value +} +public func -=(column: Expression, value: V) -> Setter where V.Datatype : Number { + return column <- column - value +} + +public func *=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column * value +} +public func *=(column: Expression, value: V) -> Setter where V.Datatype : Number { + return column <- column * value +} +public func *=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column * value +} +public func *=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column * value +} +public func *=(column: Expression, value: V) -> Setter where V.Datatype : Number { + return column <- column * value +} + +public func /=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column / value +} +public func /=(column: Expression, value: V) -> Setter where V.Datatype : Number { + return column <- column / value +} +public func /=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column / value +} +public func /=(column: Expression, value: Expression) -> Setter where V.Datatype : Number { + return column <- column / value +} +public func /=(column: Expression, value: V) -> Setter where V.Datatype : Number { + return column <- column / value +} + +public func %=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column % value +} +public func %=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column % value +} +public func %=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column % value +} +public func %=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column % value +} +public func %=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column % value +} + +public func <<=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column << value +} +public func <<=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column << value +} +public func <<=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column << value +} +public func <<=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column << value +} +public func <<=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column << value +} + +public func >>=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column >> value +} +public func >>=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column >> value +} +public func >>=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column >> value +} +public func >>=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column >> value +} +public func >>=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column >> value +} + +public func &=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column & value +} +public func &=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column & value +} +public func &=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column & value +} +public func &=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column & value +} +public func &=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column & value +} + +public func |=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column | value +} +public func |=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column | value +} +public func |=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column | value +} +public func |=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column | value +} +public func |=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column | value +} + +public func ^=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column ^ value +} +public func ^=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column ^ value +} +public func ^=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column ^ value +} +public func ^=(column: Expression, value: Expression) -> Setter where V.Datatype == Int64 { + return column <- column ^ value +} +public func ^=(column: Expression, value: V) -> Setter where V.Datatype == Int64 { + return column <- column ^ value +} + +public postfix func ++(column: Expression) -> Setter where V.Datatype == Int64 { + return Expression(column) += 1 +} +public postfix func ++(column: Expression) -> Setter where V.Datatype == Int64 { + return Expression(column) += 1 +} + +public postfix func --(column: Expression) -> Setter where V.Datatype == Int64 { + return Expression(column) -= 1 +} +public postfix func --(column: Expression) -> Setter where V.Datatype == Int64 { + return Expression(column) -= 1 +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLiteObjc/SQLite-Bridging.m b/Carthage/Checkouts/SQLite.swift/Sources/SQLiteObjc/SQLite-Bridging.m new file mode 100644 index 0000000..d8fe6b6 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLiteObjc/SQLite-Bridging.m @@ -0,0 +1,138 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "SQLite-Bridging.h" +#import "fts3_tokenizer.h" + +#pragma mark - FTS + +typedef struct __SQLiteTokenizer { + sqlite3_tokenizer base; + __unsafe_unretained _SQLiteTokenizerNextCallback callback; +} __SQLiteTokenizer; + +typedef struct __SQLiteTokenizerCursor { + void * base; + const char * input; + int inputOffset; + int inputLength; + int idx; +} __SQLiteTokenizerCursor; + +static NSMutableDictionary * __SQLiteTokenizerMap; + +static int __SQLiteTokenizerCreate(int argc, const char * const * argv, sqlite3_tokenizer ** ppTokenizer) { + __SQLiteTokenizer * tokenizer = (__SQLiteTokenizer *)sqlite3_malloc(sizeof(__SQLiteTokenizer)); + if (!tokenizer) { + return SQLITE_NOMEM; + } + memset(tokenizer, 0, sizeof(* tokenizer)); + + NSString * key = [NSString stringWithUTF8String:argv[0]]; + tokenizer->callback = [__SQLiteTokenizerMap objectForKey:key]; + if (!tokenizer->callback) { + return SQLITE_ERROR; + } + + *ppTokenizer = &tokenizer->base; + return SQLITE_OK; +} + +static int __SQLiteTokenizerDestroy(sqlite3_tokenizer * pTokenizer) { + sqlite3_free(pTokenizer); + return SQLITE_OK; +} + +static int __SQLiteTokenizerOpen(sqlite3_tokenizer * pTokenizer, const char * pInput, int nBytes, sqlite3_tokenizer_cursor ** ppCursor) { + __SQLiteTokenizerCursor * cursor = (__SQLiteTokenizerCursor *)sqlite3_malloc(sizeof(__SQLiteTokenizerCursor)); + if (!cursor) { + return SQLITE_NOMEM; + } + + cursor->input = pInput; + cursor->inputOffset = 0; + cursor->inputLength = 0; + cursor->idx = 0; + + *ppCursor = (sqlite3_tokenizer_cursor *)cursor; + return SQLITE_OK; +} + +static int __SQLiteTokenizerClose(sqlite3_tokenizer_cursor * pCursor) { + sqlite3_free(pCursor); + return SQLITE_OK; +} + +static int __SQLiteTokenizerNext(sqlite3_tokenizer_cursor * pCursor, const char ** ppToken, int * pnBytes, int * piStartOffset, int * piEndOffset, int * piPosition) { + __SQLiteTokenizerCursor * cursor = (__SQLiteTokenizerCursor *)pCursor; + __SQLiteTokenizer * tokenizer = (__SQLiteTokenizer *)cursor->base; + + cursor->inputOffset += cursor->inputLength; + const char * input = cursor->input + cursor->inputOffset; + const char * token = [tokenizer->callback(input, &cursor->inputOffset, &cursor->inputLength) cStringUsingEncoding:NSUTF8StringEncoding]; + if (!token) { + return SQLITE_DONE; + } + + *ppToken = token; + *pnBytes = (int)strlen(token); + *piStartOffset = cursor->inputOffset; + *piEndOffset = cursor->inputOffset + cursor->inputLength; + *piPosition = cursor->idx++; + return SQLITE_OK; +} + +static const sqlite3_tokenizer_module __SQLiteTokenizerModule = { + 0, + __SQLiteTokenizerCreate, + __SQLiteTokenizerDestroy, + __SQLiteTokenizerOpen, + __SQLiteTokenizerClose, + __SQLiteTokenizerNext +}; + +int _SQLiteRegisterTokenizer(SQLiteHandle * db, const char * moduleName, const char * submoduleName, _SQLiteTokenizerNextCallback callback) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + __SQLiteTokenizerMap = [NSMutableDictionary new]; + }); + + sqlite3_stmt * stmt; + int status = sqlite3_prepare_v2((sqlite3 *)db, "SELECT fts3_tokenizer(?, ?)", -1, &stmt, 0); + if (status != SQLITE_OK ){ + return status; + } + const sqlite3_tokenizer_module * pModule = &__SQLiteTokenizerModule; + sqlite3_bind_text(stmt, 1, moduleName, -1, SQLITE_STATIC); + sqlite3_bind_blob(stmt, 2, &pModule, sizeof(pModule), SQLITE_STATIC); + sqlite3_step(stmt); + status = sqlite3_finalize(stmt); + if (status != SQLITE_OK ){ + return status; + } + + [__SQLiteTokenizerMap setObject:[callback copy] forKey:[NSString stringWithUTF8String:submoduleName]]; + + return SQLITE_OK; +} diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLiteObjc/fts3_tokenizer.h b/Carthage/Checkouts/SQLite.swift/Sources/SQLiteObjc/fts3_tokenizer.h new file mode 100644 index 0000000..d8a1e44 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLiteObjc/fts3_tokenizer.h @@ -0,0 +1,161 @@ +/* +** 2006 July 10 +** +** The author disclaims copyright to this source code. +** +************************************************************************* +** Defines the interface to tokenizers used by fulltext-search. There +** are three basic components: +** +** sqlite3_tokenizer_module is a singleton defining the tokenizer +** interface functions. This is essentially the class structure for +** tokenizers. +** +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps +** including customization information defined at creation time. +** +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate +** tokens from a particular input. +*/ +#ifndef _FTS3_TOKENIZER_H_ +#define _FTS3_TOKENIZER_H_ + +/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. +** If tokenizers are to be allowed to call sqlite3_*() functions, then +** we will need a way to register the API consistently. +*/ +#import "sqlite3.h" + +/* +** Structures used by the tokenizer interface. When a new tokenizer +** implementation is registered, the caller provides a pointer to +** an sqlite3_tokenizer_module containing pointers to the callback +** functions that make up an implementation. +** +** When an fts3 table is created, it passes any arguments passed to +** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** implementation. The xCreate() function in turn returns an +** sqlite3_tokenizer structure representing the specific tokenizer to +** be used for the fts3 table (customized by the tokenizer clause arguments). +** +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object +** that may be used to tokenize a specific input buffer based on +** the tokenization rules supplied by a specific sqlite3_tokenizer +** object. +*/ +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; + +struct sqlite3_tokenizer_module { + + /* + ** Structure version. Should always be set to 0 or 1. + */ + int iVersion; + + /* + ** Create a new tokenizer. The values in the argv[] array are the + ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL + ** TABLE statement that created the fts3 table. For example, if + ** the following SQL is executed: + ** + ** CREATE .. USING fts3( ... , tokenizer arg1 arg2) + ** + ** then argc is set to 2, and the argv[] array contains pointers + ** to the strings "arg1" and "arg2". + ** + ** This method should return either SQLITE_OK (0), or an SQLite error + ** code. If SQLITE_OK is returned, then *ppTokenizer should be set + ** to point at the newly created tokenizer structure. The generic + ** sqlite3_tokenizer.pModule variable should not be initialized by + ** this callback. The caller will do so. + */ + int (*xCreate)( + int argc, /* Size of argv array */ + const char *const*argv, /* Tokenizer argument strings */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + ); + + /* + ** Destroy an existing tokenizer. The fts3 module calls this method + ** exactly once for each successful call to xCreate(). + */ + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); + + /* + ** Create a tokenizer cursor to tokenize an input buffer. The caller + ** is responsible for ensuring that the input buffer remains valid + ** until the cursor is closed (using the xClose() method). + */ + int (*xOpen)( + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + const char *pInput, int nBytes, /* Input buffer */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + ); + + /* + ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** method exactly once for each successful call to xOpen(). + */ + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); + + /* + ** Retrieve the next token from the tokenizer cursor pCursor. This + ** method should either return SQLITE_OK and set the values of the + ** "OUT" variables identified below, or SQLITE_DONE to indicate that + ** the end of the buffer has been reached, or an SQLite error code. + ** + ** *ppToken should be set to point at a buffer containing the + ** normalized version of the token (i.e. after any case-folding and/or + ** stemming has been performed). *pnBytes should be set to the length + ** of this buffer in bytes. The input text that generated the token is + ** identified by the byte offsets returned in *piStartOffset and + ** *piEndOffset. *piStartOffset should be set to the index of the first + ** byte of the token in the input buffer. *piEndOffset should be set + ** to the index of the first byte just past the end of the token in + ** the input buffer. + ** + ** The buffer *ppToken is set to point at is managed by the tokenizer + ** implementation. It is only required to be valid until the next call + ** to xNext() or xClose(). + */ + /* TODO(shess) current implementation requires pInput to be + ** nul-terminated. This should either be fixed, or pInput/nBytes + ** should be converted to zInput. + */ + int (*xNext)( + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ + int *piStartOffset, /* OUT: Byte offset of token in input buffer */ + int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ + int *piPosition /* OUT: Number of tokens returned before this one */ + ); + + /*********************************************************************** + ** Methods below this point are only available if iVersion>=1. + */ + + /* + ** Configure the language id of a tokenizer cursor. + */ + int (*xLanguageid)(sqlite3_tokenizer_cursor *pCsr, int iLangid); +}; + +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ + /* Tokenizer implementations will typically add additional fields */ +}; + +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ + /* Tokenizer implementations will typically add additional fields */ +}; + +int fts3_global_term_cnt(int iTerm, int iCol); +int fts3_term_cnt(int iTerm, int iCol); + + +#endif /* _FTS3_TOKENIZER_H_ */ diff --git a/Carthage/Checkouts/SQLite.swift/Sources/SQLiteObjc/include/SQLite-Bridging.h b/Carthage/Checkouts/SQLite.swift/Sources/SQLiteObjc/include/SQLite-Bridging.h new file mode 100644 index 0000000..d15e8d5 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Sources/SQLiteObjc/include/SQLite-Bridging.h @@ -0,0 +1,37 @@ +// +// SQLite.swift +// https://github.com/stephencelis/SQLite.swift +// Copyright © 2014-2015 Stephen Celis. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +@import Foundation; + +#ifndef COCOAPODS +#import "sqlite3.h" +#endif + +typedef struct SQLiteHandle SQLiteHandle; // CocoaPods workaround + +NS_ASSUME_NONNULL_BEGIN +typedef NSString * _Nullable (^_SQLiteTokenizerNextCallback)(const char * input, int * inputOffset, int * inputLength); +int _SQLiteRegisterTokenizer(SQLiteHandle * db, const char * module, const char * tokenizer, _Nullable _SQLiteTokenizerNextCallback callback); +NS_ASSUME_NONNULL_END + diff --git a/Carthage/Checkouts/SQLite.swift/Tests/Carthage/.gitignore b/Carthage/Checkouts/SQLite.swift/Tests/Carthage/.gitignore new file mode 100644 index 0000000..2d43454 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/Carthage/.gitignore @@ -0,0 +1,3 @@ +Carthage/ +Cartfile +Cartfile.resolved diff --git a/Carthage/Checkouts/SQLite.swift/Tests/Carthage/Makefile b/Carthage/Checkouts/SQLite.swift/Tests/Carthage/Makefile new file mode 100644 index 0000000..f28eb25 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/Carthage/Makefile @@ -0,0 +1,16 @@ +CARTHAGE := /usr/local/bin/carthage +CARTHAGE_PLATFORM := iOS +CARTHAGE_CONFIGURATION := Release +CARTHAGE_DIR := Carthage +CARTHAGE_ARGS := --no-use-binaries +CARTHAGE_TOOLCHAIN := com.apple.dt.toolchain.Swift_3_0 +CARTHAGE_CMDLINE := --configuration $(CARTHAGE_CONFIGURATION) --platform $(CARTHAGE_PLATFORM) --toolchain $(CARTHAGE_TOOLCHAIN) $(CARTHAGE_ARGS) + +test: $(CARTHAGE) Cartfile + $< bootstrap $(CARTHAGE_CMDLINE) + +Cartfile: + echo 'git "$(TRAVIS_BUILD_DIR)" "HEAD"' > $@ + +clean: + @rm -f Cartfile Cartfile.resolved diff --git a/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/.gitignore b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/.gitignore new file mode 100644 index 0000000..4cf24de --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/.gitignore @@ -0,0 +1 @@ +gems/ diff --git a/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/Gemfile b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/Gemfile new file mode 100644 index 0000000..94018f1 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem 'cocoapods', '~> 1.1.0' +gem 'minitest' diff --git a/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/Gemfile.lock b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/Gemfile.lock new file mode 100644 index 0000000..e8879f1 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/Gemfile.lock @@ -0,0 +1,74 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (2.3.3) + activesupport (4.2.7.1) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + claide (1.0.1) + cocoapods (1.1.1) + activesupport (>= 4.0.2, < 5) + claide (>= 1.0.1, < 2.0) + cocoapods-core (= 1.1.1) + cocoapods-deintegrate (>= 1.0.1, < 2.0) + cocoapods-downloader (>= 1.1.2, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-stats (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.1.1, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored (~> 1.2) + escape (~> 0.0.4) + fourflusher (~> 2.0.1) + gh_inspector (~> 1.0) + molinillo (~> 0.5.1) + nap (~> 1.0) + xcodeproj (>= 1.3.3, < 2.0) + cocoapods-core (1.1.1) + activesupport (>= 4.0.2, < 5) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + cocoapods-deintegrate (1.0.1) + cocoapods-downloader (1.1.2) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.0) + cocoapods-stats (1.0.0) + cocoapods-trunk (1.1.1) + nap (>= 0.8, < 2.0) + netrc (= 0.7.8) + cocoapods-try (1.1.0) + colored (1.2) + escape (0.0.4) + fourflusher (2.0.1) + fuzzy_match (2.0.4) + gh_inspector (1.0.2) + i18n (0.7.0) + json (1.8.3) + minitest (5.9.1) + molinillo (0.5.4) + nanaimo (0.2.2) + nap (1.1.0) + netrc (0.7.8) + thread_safe (0.3.5) + tzinfo (1.2.2) + thread_safe (~> 0.1) + xcodeproj (1.4.1) + CFPropertyList (~> 2.3.3) + activesupport (>= 3) + claide (>= 1.0.1, < 2.0) + colored (~> 1.2) + nanaimo (~> 0.2.0) + +PLATFORMS + ruby + +DEPENDENCIES + cocoapods (~> 1.1.0) + minitest + +BUNDLED WITH + 1.13.3 diff --git a/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/Makefile b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/Makefile new file mode 100644 index 0000000..26163fd --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/Makefile @@ -0,0 +1,13 @@ +test: install repo_update + @set -e; \ + for test in *_test.rb; do \ + bundle exec ./$$test; \ + done + +repo_update: + @bundle exec pod repo update --silent + +install: + @bundle install --path gems + +.PHONY: test install diff --git a/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/integration_test.rb b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/integration_test.rb new file mode 100755 index 0000000..192aff9 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/integration_test.rb @@ -0,0 +1,43 @@ +#!/usr/bin/env ruby + +require 'minitest/autorun' +require_relative 'test_running_validator' + +class IntegrationTest < Minitest::Test + + def test_validate_project + assert validator.validate, "validation failed: #{validator.failure_reason}" + end + + private + + def validator + @validator ||= TestRunningValidator.new(podspec, []).tap do |validator| + validator.test_files = Dir["#{project_test_dir}/**/*.swift"] + validator.test_resources = Dir["#{project_test_dir}/fixtures"] + validator.config.verbose = true + validator.no_clean = true + validator.use_frameworks = true + validator.fail_fast = true + validator.local = true + validator.allow_warnings = true + subspec = ENV['VALIDATOR_SUBSPEC'] + if subspec == 'none' + validator.no_subspecs = true + else + validator.only_subspec = subspec + end + if ENV['IOS_SIMULATOR'] + validator.ios_simulator = ENV['IOS_SIMULATOR'] + end + end + end + + def podspec + File.expand_path(File.dirname(__FILE__) + '/../../SQLite.swift.podspec') + end + + def project_test_dir + File.expand_path(File.dirname(__FILE__) + '/../SQLiteTests') + end +end diff --git a/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/test_running_validator.rb b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/test_running_validator.rb new file mode 100644 index 0000000..fcfd3c2 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/CocoaPods/test_running_validator.rb @@ -0,0 +1,120 @@ +require 'cocoapods' +require 'cocoapods/validator' +require 'fileutils' + +class TestRunningValidator < Pod::Validator + APP_TARGET = 'App' + TEST_TARGET = 'Tests' + + attr_accessor :test_files + attr_accessor :test_resources + attr_accessor :ios_simulator + attr_accessor :tvos_simulator + attr_accessor :watchos_simulator + + def initialize(spec_or_path, source_urls) + super(spec_or_path, source_urls) + self.test_files = [] + self.test_resources = [] + self.ios_simulator = :oldest + self.tvos_simulator = :oldest + self.watchos_simulator = :oldest + end + + def create_app_project + super + project = Xcodeproj::Project.open(validation_dir + "#{APP_TARGET}.xcodeproj") + create_test_target(project) + project.save + end + + def add_app_project_import + super + project = Xcodeproj::Project.open(validation_dir + 'App.xcodeproj') + group = project.new_group(TEST_TARGET) + test_target = project.targets.last + test_target.add_resources(test_resources.map { |resource| group.new_file(resource) }) + test_target.add_file_references(test_files.map { |file| group.new_file(file) }) + add_swift_version(test_target) + project.save + end + + def install_pod + super + if local? + FileUtils.ln_s file.dirname, validation_dir + "Pods/#{spec.name}" + end + end + + def podfile_from_spec(*args) + super(*args).tap do |pod_file| + add_test_target(pod_file) + end + end + + def build_pod + super + Pod::UI.message "\Testing with xcodebuild.\n".yellow do + run_tests + end + end + + private + def create_test_target(project) + test_target = project.new_target(:unit_test_bundle, TEST_TARGET, consumer.platform_name, deployment_target) + create_test_scheme(project, test_target) + end + + def create_test_scheme(project, test_target) + project.recreate_user_schemes + test_scheme = Xcodeproj::XCScheme.new(test_scheme_path(project)) + test_scheme.add_test_target(test_target) + test_scheme.save! + end + + def test_scheme_path(project) + Xcodeproj::XCScheme.user_data_dir(project.path) + "#{TEST_TARGET}.xcscheme" + end + + def add_test_target(pod_file) + app_target = pod_file.target_definitions[APP_TARGET] + Pod::Podfile::TargetDefinition.new(TEST_TARGET, app_target) + end + + def run_tests + command = [ + 'clean', 'build', 'build-for-testing', 'test-without-building', + '-workspace', File.join(validation_dir, "#{APP_TARGET}.xcworkspace"), + '-scheme', TEST_TARGET, + '-configuration', 'Debug' + ] + case consumer.platform_name + when :ios + command += %w(CODE_SIGN_IDENTITY=- -sdk iphonesimulator) + command += Fourflusher::SimControl.new.destination(ios_simulator, 'iOS', deployment_target) + when :osx + command += %w(LD_RUNPATH_SEARCH_PATHS=@loader_path/../Frameworks) + when :tvos + command += %w(CODE_SIGN_IDENTITY=- -sdk appletvsimulator) + command += Fourflusher::SimControl.new.destination(tvos_simulator, 'tvOS', deployment_target) + when :watchos + # there's no XCTest on watchOS (https://openradar.appspot.com/21760513) + return + else + return + end + + output, status = _xcodebuild(command) + + unless status.success? + message = 'Returned an unsuccessful exit code.' + if config.verbose? + message += "\nXcode output: \n#{output}\n" + else + message += ' You can use `--verbose` for more information.' + end + error('xcodebuild', message) + end + output + end +end diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/AggregateFunctionsTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/AggregateFunctionsTests.swift new file mode 100644 index 0000000..6b583cc --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/AggregateFunctionsTests.swift @@ -0,0 +1,68 @@ +import XCTest +import SQLite + +class AggregateFunctionsTests : XCTestCase { + + func test_distinct_prependsExpressionsWithDistinctKeyword() { + AssertSQL("DISTINCT \"int\"", int.distinct) + AssertSQL("DISTINCT \"intOptional\"", intOptional.distinct) + AssertSQL("DISTINCT \"double\"", double.distinct) + AssertSQL("DISTINCT \"doubleOptional\"", doubleOptional.distinct) + AssertSQL("DISTINCT \"string\"", string.distinct) + AssertSQL("DISTINCT \"stringOptional\"", stringOptional.distinct) + } + + func test_count_wrapsOptionalExpressionsWithCountFunction() { + AssertSQL("count(\"intOptional\")", intOptional.count) + AssertSQL("count(\"doubleOptional\")", doubleOptional.count) + AssertSQL("count(\"stringOptional\")", stringOptional.count) + } + + func test_max_wrapsComparableExpressionsWithMaxFunction() { + AssertSQL("max(\"int\")", int.max) + AssertSQL("max(\"intOptional\")", intOptional.max) + AssertSQL("max(\"double\")", double.max) + AssertSQL("max(\"doubleOptional\")", doubleOptional.max) + AssertSQL("max(\"string\")", string.max) + AssertSQL("max(\"stringOptional\")", stringOptional.max) + AssertSQL("max(\"date\")", date.max) + AssertSQL("max(\"dateOptional\")", dateOptional.max) + } + + func test_min_wrapsComparableExpressionsWithMinFunction() { + AssertSQL("min(\"int\")", int.min) + AssertSQL("min(\"intOptional\")", intOptional.min) + AssertSQL("min(\"double\")", double.min) + AssertSQL("min(\"doubleOptional\")", doubleOptional.min) + AssertSQL("min(\"string\")", string.min) + AssertSQL("min(\"stringOptional\")", stringOptional.min) + AssertSQL("min(\"date\")", date.min) + AssertSQL("min(\"dateOptional\")", dateOptional.min) + } + + func test_average_wrapsNumericExpressionsWithAvgFunction() { + AssertSQL("avg(\"int\")", int.average) + AssertSQL("avg(\"intOptional\")", intOptional.average) + AssertSQL("avg(\"double\")", double.average) + AssertSQL("avg(\"doubleOptional\")", doubleOptional.average) + } + + func test_sum_wrapsNumericExpressionsWithSumFunction() { + AssertSQL("sum(\"int\")", int.sum) + AssertSQL("sum(\"intOptional\")", intOptional.sum) + AssertSQL("sum(\"double\")", double.sum) + AssertSQL("sum(\"doubleOptional\")", doubleOptional.sum) + } + + func test_total_wrapsNumericExpressionsWithTotalFunction() { + AssertSQL("total(\"int\")", int.total) + AssertSQL("total(\"intOptional\")", intOptional.total) + AssertSQL("total(\"double\")", double.total) + AssertSQL("total(\"doubleOptional\")", doubleOptional.total) + } + + func test_count_withStar_wrapsStarWithCountFunction() { + AssertSQL("count(*)", count(*)) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/BlobTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/BlobTests.swift new file mode 100644 index 0000000..fbcca9b --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/BlobTests.swift @@ -0,0 +1,23 @@ +import XCTest +import SQLite + +class BlobTests : XCTestCase { + + func test_toHex() { + let blob = Blob(bytes: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 150, 250, 255]) + + XCTAssertEqual(blob.toHex(), "000a141e28323c46505a6496faff") + } + + func test_init_array() { + let blob = Blob(bytes: [42, 42, 42]) + XCTAssertEqual(blob.bytes, [42, 42, 42]) + } + + func test_init_unsafeRawPointer() { + let pointer = UnsafeMutablePointer.allocate(capacity: 3) + pointer.initialize(to: 42, count: 3) + let blob = Blob(bytes: pointer, length: 3) + XCTAssertEqual(blob.bytes, [42, 42, 42]) + } +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/CipherTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/CipherTests.swift new file mode 100644 index 0000000..3ee0b13 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/CipherTests.swift @@ -0,0 +1,98 @@ +#if SQLITE_SWIFT_SQLCIPHER +import XCTest +import SQLite +import SQLCipher + +class CipherTests: XCTestCase { + + let db1 = try! Connection() + let db2 = try! Connection() + + override func setUp() { + // db + + try! db1.key("hello") + + try! db1.run("CREATE TABLE foo (bar TEXT)") + try! db1.run("INSERT INTO foo (bar) VALUES ('world')") + + // db2 + let key2 = keyData() + try! db2.key(Blob(bytes: key2.bytes, length: key2.length)) + + try! db2.run("CREATE TABLE foo (bar TEXT)") + try! db2.run("INSERT INTO foo (bar) VALUES ('world')") + + super.setUp() + } + + func test_key() { + XCTAssertEqual(1, try! db1.scalar("SELECT count(*) FROM foo") as? Int64) + } + + func test_key_blob_literal() { + let db = try! Connection() + try! db.key("x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'") + } + + func test_rekey() { + try! db1.rekey("goodbye") + XCTAssertEqual(1, try! db1.scalar("SELECT count(*) FROM foo") as? Int64) + } + + func test_data_key() { + XCTAssertEqual(1, try! db2.scalar("SELECT count(*) FROM foo") as? Int64) + } + + func test_data_rekey() { + let newKey = keyData() + try! db2.rekey(Blob(bytes: newKey.bytes, length: newKey.length)) + XCTAssertEqual(1, try! db2.scalar("SELECT count(*) FROM foo") as? Int64) + } + + func test_keyFailure() { + let path = "\(NSTemporaryDirectory())/db.sqlite3" + _ = try? FileManager.default.removeItem(atPath: path) + + let connA = try! Connection(path) + defer { try! FileManager.default.removeItem(atPath: path) } + + try! connA.key("hello") + try! connA.run("CREATE TABLE foo (bar TEXT)") + + let connB = try! Connection(path, readonly: true) + + do { + try connB.key("world") + XCTFail("expected exception") + } catch Result.error(_, let code, _) { + XCTAssertEqual(SQLITE_NOTADB, code) + } catch { + XCTFail("unexpected error: \(error)") + } + } + + func test_open_db_encrypted_with_sqlcipher() { + // $ sqlcipher SQLiteTests/fixtures/encrypted.sqlite + // sqlite> pragma key = 'sqlcipher-test'; + // sqlite> CREATE TABLE foo (bar TEXT); + // sqlite> INSERT INTO foo (bar) VALUES ('world'); + let encryptedFile = fixture("encrypted", withExtension: "sqlite") + + try! FileManager.default.setAttributes([FileAttributeKey.immutable : 1], ofItemAtPath: encryptedFile) + XCTAssertFalse(FileManager.default.isWritableFile(atPath: encryptedFile)) + + let conn = try! Connection(encryptedFile) + try! conn.key("sqlcipher-test") + XCTAssertEqual(1, try! conn.scalar("SELECT count(*) FROM foo") as? Int64) + } + + private func keyData(length: Int = 64) -> NSMutableData { + let keyData = NSMutableData(length: length)! + let result = SecRandomCopyBytes(kSecRandomDefault, length, + keyData.mutableBytes.assumingMemoryBound(to: UInt8.self)) + XCTAssertEqual(0, result) + return keyData + } +} +#endif diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/ConnectionTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/ConnectionTests.swift new file mode 100644 index 0000000..59514a2 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/ConnectionTests.swift @@ -0,0 +1,384 @@ +import XCTest +@testable import SQLite + +#if SQLITE_SWIFT_STANDALONE +import sqlite3 +#elseif SQLITE_SWIFT_SQLCIPHER +import SQLCipher +#else +import CSQLite +#endif + +class ConnectionTests : SQLiteTestCase { + + override func setUp() { + super.setUp() + + CreateUsersTable() + } + + func test_init_withInMemory_returnsInMemoryConnection() { + let db = try! Connection(.inMemory) + XCTAssertEqual("", db.description) + } + + func test_init_returnsInMemoryByDefault() { + let db = try! Connection() + XCTAssertEqual("", db.description) + } + + func test_init_withTemporary_returnsTemporaryConnection() { + let db = try! Connection(.temporary) + XCTAssertEqual("", db.description) + } + + func test_init_withURI_returnsURIConnection() { + let db = try! Connection(.uri("\(NSTemporaryDirectory())/SQLite.swift Tests.sqlite3")) + XCTAssertEqual("\(NSTemporaryDirectory())/SQLite.swift Tests.sqlite3", db.description) + } + + func test_init_withString_returnsURIConnection() { + let db = try! Connection("\(NSTemporaryDirectory())/SQLite.swift Tests.sqlite3") + XCTAssertEqual("\(NSTemporaryDirectory())/SQLite.swift Tests.sqlite3", db.description) + } + + func test_readonly_returnsFalseOnReadWriteConnections() { + XCTAssertFalse(db.readonly) + } + + func test_readonly_returnsTrueOnReadOnlyConnections() { + let db = try! Connection(readonly: true) + XCTAssertTrue(db.readonly) + } + + func test_changes_returnsZeroOnNewConnections() { + XCTAssertEqual(0, db.changes) + } + + func test_lastInsertRowid_returnsLastIdAfterInserts() { + try! InsertUser("alice") + XCTAssertEqual(1, db.lastInsertRowid) + } + + func test_lastInsertRowid_doesNotResetAfterError() { + XCTAssert(db.lastInsertRowid == 0) + try! InsertUser("alice") + XCTAssertEqual(1, db.lastInsertRowid) + XCTAssertThrowsError( + try db.run("INSERT INTO \"users\" (email, age, admin) values ('invalid@example.com', 12, 'invalid')") + ) { error in + if case SQLite.Result.error(_, let code, _) = error { + XCTAssertEqual(SQLITE_CONSTRAINT, code) + } else { + XCTFail("expected error") + } + } + XCTAssertEqual(1, db.lastInsertRowid) + } + + func test_changes_returnsNumberOfChanges() { + try! InsertUser("alice") + XCTAssertEqual(1, db.changes) + try! InsertUser("betsy") + XCTAssertEqual(1, db.changes) + } + + func test_totalChanges_returnsTotalNumberOfChanges() { + XCTAssertEqual(0, db.totalChanges) + try! InsertUser("alice") + XCTAssertEqual(1, db.totalChanges) + try! InsertUser("betsy") + XCTAssertEqual(2, db.totalChanges) + } + + func test_prepare_preparesAndReturnsStatements() { + _ = try! db.prepare("SELECT * FROM users WHERE admin = 0") + _ = try! db.prepare("SELECT * FROM users WHERE admin = ?", 0) + _ = try! db.prepare("SELECT * FROM users WHERE admin = ?", [0]) + _ = try! db.prepare("SELECT * FROM users WHERE admin = $admin", ["$admin": 0]) + } + + func test_run_preparesRunsAndReturnsStatements() { + try! db.run("SELECT * FROM users WHERE admin = 0") + try! db.run("SELECT * FROM users WHERE admin = ?", 0) + try! db.run("SELECT * FROM users WHERE admin = ?", [0]) + try! db.run("SELECT * FROM users WHERE admin = $admin", ["$admin": 0]) + AssertSQL("SELECT * FROM users WHERE admin = 0", 4) + } + + func test_scalar_preparesRunsAndReturnsScalarValues() { + XCTAssertEqual(0, try! db.scalar("SELECT count(*) FROM users WHERE admin = 0") as? Int64) + XCTAssertEqual(0, try! db.scalar("SELECT count(*) FROM users WHERE admin = ?", 0) as? Int64) + XCTAssertEqual(0, try! db.scalar("SELECT count(*) FROM users WHERE admin = ?", [0]) as? Int64) + XCTAssertEqual(0, try! db.scalar("SELECT count(*) FROM users WHERE admin = $admin", ["$admin": 0]) as? Int64) + AssertSQL("SELECT count(*) FROM users WHERE admin = 0", 4) + } + + func test_execute_comment() { + try! db.run("-- this is a comment\nSELECT 1") + AssertSQL("-- this is a comment", 0) + AssertSQL("SELECT 1", 0) + } + + func test_transaction_executesBeginDeferred() { + try! db.transaction(.deferred) {} + + AssertSQL("BEGIN DEFERRED TRANSACTION") + } + + func test_transaction_executesBeginImmediate() { + try! db.transaction(.immediate) {} + + AssertSQL("BEGIN IMMEDIATE TRANSACTION") + } + + func test_transaction_executesBeginExclusive() { + try! db.transaction(.exclusive) {} + + AssertSQL("BEGIN EXCLUSIVE TRANSACTION") + } + + func test_transaction_beginsAndCommitsTransactions() { + let stmt = try! db.prepare("INSERT INTO users (email) VALUES (?)", "alice@example.com") + + try! db.transaction { + try stmt.run() + } + + AssertSQL("BEGIN DEFERRED TRANSACTION") + AssertSQL("INSERT INTO users (email) VALUES ('alice@example.com')") + AssertSQL("COMMIT TRANSACTION") + AssertSQL("ROLLBACK TRANSACTION", 0) + } + + func test_transaction_beginsAndRollsTransactionsBack() { + let stmt = try! db.prepare("INSERT INTO users (email) VALUES (?)", "alice@example.com") + + do { + try db.transaction { + try stmt.run() + try stmt.run() + } + } catch { + } + + AssertSQL("BEGIN DEFERRED TRANSACTION") + AssertSQL("INSERT INTO users (email) VALUES ('alice@example.com')", 2) + AssertSQL("ROLLBACK TRANSACTION") + AssertSQL("COMMIT TRANSACTION", 0) + } + + func test_savepoint_beginsAndCommitsSavepoints() { + let db = self.db + + try! db.savepoint("1") { + try db.savepoint("2") { + try db.run("INSERT INTO users (email) VALUES (?)", "alice@example.com") + } + } + + AssertSQL("SAVEPOINT '1'") + AssertSQL("SAVEPOINT '2'") + AssertSQL("INSERT INTO users (email) VALUES ('alice@example.com')") + AssertSQL("RELEASE SAVEPOINT '2'") + AssertSQL("RELEASE SAVEPOINT '1'") + AssertSQL("ROLLBACK TO SAVEPOINT '2'", 0) + AssertSQL("ROLLBACK TO SAVEPOINT '1'", 0) + } + + func test_savepoint_beginsAndRollsSavepointsBack() { + let db = self.db + let stmt = try! db.prepare("INSERT INTO users (email) VALUES (?)", "alice@example.com") + + do { + try db.savepoint("1") { + try db.savepoint("2") { + try stmt.run() + try stmt.run() + try stmt.run() + } + try db.savepoint("2") { + try stmt.run() + try stmt.run() + try stmt.run() + } + } + } catch { + } + + AssertSQL("SAVEPOINT '1'") + AssertSQL("SAVEPOINT '2'") + AssertSQL("INSERT INTO users (email) VALUES ('alice@example.com')", 2) + AssertSQL("ROLLBACK TO SAVEPOINT '2'") + AssertSQL("ROLLBACK TO SAVEPOINT '1'") + AssertSQL("RELEASE SAVEPOINT '2'", 0) + AssertSQL("RELEASE SAVEPOINT '1'", 0) + } + + func test_updateHook_setsUpdateHook_withInsert() { + async { done in + db.updateHook { operation, db, table, rowid in + XCTAssertEqual(Connection.Operation.insert, operation) + XCTAssertEqual("main", db) + XCTAssertEqual("users", table) + XCTAssertEqual(1, rowid) + done() + } + try! InsertUser("alice") + } + } + + func test_updateHook_setsUpdateHook_withUpdate() { + try! InsertUser("alice") + async { done in + db.updateHook { operation, db, table, rowid in + XCTAssertEqual(Connection.Operation.update, operation) + XCTAssertEqual("main", db) + XCTAssertEqual("users", table) + XCTAssertEqual(1, rowid) + done() + } + try! db.run("UPDATE users SET email = 'alice@example.com'") + } + } + + func test_updateHook_setsUpdateHook_withDelete() { + try! InsertUser("alice") + async { done in + db.updateHook { operation, db, table, rowid in + XCTAssertEqual(Connection.Operation.delete, operation) + XCTAssertEqual("main", db) + XCTAssertEqual("users", table) + XCTAssertEqual(1, rowid) + done() + } + try! db.run("DELETE FROM users WHERE id = 1") + } + } + + func test_commitHook_setsCommitHook() { + async { done in + db.commitHook { + done() + } + try! db.transaction { + try self.InsertUser("alice") + } + XCTAssertEqual(1, try! db.scalar("SELECT count(*) FROM users") as? Int64) + } + } + + func test_rollbackHook_setsRollbackHook() { + async { done in + db.rollbackHook(done) + do { + try db.transaction { + try self.InsertUser("alice") + try self.InsertUser("alice") // throw + } + } catch { + } + XCTAssertEqual(0, try! db.scalar("SELECT count(*) FROM users") as? Int64) + } + } + + func test_commitHook_withRollback_rollsBack() { + async { done in + db.commitHook { + throw NSError(domain: "com.stephencelis.SQLiteTests", code: 1, userInfo: nil) + } + db.rollbackHook(done) + do { + try db.transaction { + try self.InsertUser("alice") + } + } catch { + } + XCTAssertEqual(0, try! db.scalar("SELECT count(*) FROM users") as? Int64) + } + } + + func test_createFunction_withArrayArguments() { + db.createFunction("hello") { $0[0].map { "Hello, \($0)!" } } + + XCTAssertEqual("Hello, world!", try! db.scalar("SELECT hello('world')") as? String) + XCTAssert(try! db.scalar("SELECT hello(NULL)") == nil) + } + + func test_createFunction_createsQuotableFunction() { + db.createFunction("hello world") { $0[0].map { "Hello, \($0)!" } } + + XCTAssertEqual("Hello, world!", try! db.scalar("SELECT \"hello world\"('world')") as? String) + XCTAssert(try! db.scalar("SELECT \"hello world\"(NULL)") == nil) + } + + func test_createCollation_createsCollation() { + try! db.createCollation("NODIACRITIC") { lhs, rhs in + return lhs.compare(rhs, options: .diacriticInsensitive) + } + XCTAssertEqual(1, try! db.scalar("SELECT ? = ? COLLATE NODIACRITIC", "cafe", "café") as? Int64) + } + + func test_createCollation_createsQuotableCollation() { + try! db.createCollation("NO DIACRITIC") { lhs, rhs in + return lhs.compare(rhs, options: .diacriticInsensitive) + } + XCTAssertEqual(1, try! db.scalar("SELECT ? = ? COLLATE \"NO DIACRITIC\"", "cafe", "café") as? Int64) + } + + func test_interrupt_interruptsLongRunningQuery() { + try! InsertUsers("abcdefghijklmnopqrstuvwxyz".characters.map { String($0) }) + db.createFunction("sleep") { args in + usleep(UInt32((args[0] as? Double ?? Double(args[0] as? Int64 ?? 1)) * 1_000_000)) + return nil + } + + let stmt = try! db.prepare("SELECT *, sleep(?) FROM users", 0.1) + try! stmt.run() + + let deadline = DispatchTime.now() + Double(Int64(10 * NSEC_PER_MSEC)) / Double(NSEC_PER_SEC) + _ = DispatchQueue.global(priority: .background).asyncAfter(deadline: deadline, execute: db.interrupt) + AssertThrows(try stmt.run()) + } + +} + + +class ResultTests : XCTestCase { + let connection = try! Connection(.inMemory) + + func test_init_with_ok_code_returns_nil() { + XCTAssertNil(Result(errorCode: SQLITE_OK, connection: connection, statement: nil) as Result?) + } + + func test_init_with_row_code_returns_nil() { + XCTAssertNil(Result(errorCode: SQLITE_ROW, connection: connection, statement: nil) as Result?) + } + + func test_init_with_done_code_returns_nil() { + XCTAssertNil(Result(errorCode: SQLITE_DONE, connection: connection, statement: nil) as Result?) + } + + func test_init_with_other_code_returns_error() { + if case .some(.error(let message, let code, let statement)) = + Result(errorCode: SQLITE_MISUSE, connection: connection, statement: nil) { + XCTAssertEqual("not an error", message) + XCTAssertEqual(SQLITE_MISUSE, code) + XCTAssertNil(statement) + XCTAssert(self.connection === connection) + } else { + XCTFail() + } + } + + func test_description_contains_error_code() { + XCTAssertEqual("not an error (code: 21)", + Result(errorCode: SQLITE_MISUSE, connection: connection, statement: nil)?.description) + } + + func test_description_contains_statement_and_error_code() { + let statement = try! Statement(connection, "SELECT 1") + XCTAssertEqual("not an error (SELECT 1) (code: 21)", + Result(errorCode: SQLITE_MISUSE, connection: connection, statement: statement)?.description) + } +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/CoreFunctionsTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/CoreFunctionsTests.swift new file mode 100644 index 0000000..db37ff7 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/CoreFunctionsTests.swift @@ -0,0 +1,136 @@ +import XCTest +import SQLite + +class CoreFunctionsTests : XCTestCase { + + func test_round_wrapsDoubleExpressionsWithRoundFunction() { + AssertSQL("round(\"double\")", double.round()) + AssertSQL("round(\"doubleOptional\")", doubleOptional.round()) + + AssertSQL("round(\"double\", 1)", double.round(1)) + AssertSQL("round(\"doubleOptional\", 2)", doubleOptional.round(2)) + } + + func test_random_generatesExpressionWithRandomFunction() { + AssertSQL("random()", Expression.random()) + AssertSQL("random()", Expression.random()) + } + + func test_length_wrapsStringExpressionWithLengthFunction() { + AssertSQL("length(\"string\")", string.length) + AssertSQL("length(\"stringOptional\")", stringOptional.length) + } + + func test_lowercaseString_wrapsStringExpressionWithLowerFunction() { + AssertSQL("lower(\"string\")", string.lowercaseString) + AssertSQL("lower(\"stringOptional\")", stringOptional.lowercaseString) + } + + func test_uppercaseString_wrapsStringExpressionWithUpperFunction() { + AssertSQL("upper(\"string\")", string.uppercaseString) + AssertSQL("upper(\"stringOptional\")", stringOptional.uppercaseString) + } + + func test_like_buildsExpressionWithLikeOperator() { + AssertSQL("(\"string\" LIKE 'a%')", string.like("a%")) + AssertSQL("(\"stringOptional\" LIKE 'b%')", stringOptional.like("b%")) + + AssertSQL("(\"string\" LIKE '%\\%' ESCAPE '\\')", string.like("%\\%", escape: "\\")) + AssertSQL("(\"stringOptional\" LIKE '_\\_' ESCAPE '\\')", stringOptional.like("_\\_", escape: "\\")) + } + + func test_glob_buildsExpressionWithGlobOperator() { + AssertSQL("(\"string\" GLOB 'a*')", string.glob("a*")) + AssertSQL("(\"stringOptional\" GLOB 'b*')", stringOptional.glob("b*")) + } + + func test_match_buildsExpressionWithMatchOperator() { + AssertSQL("(\"string\" MATCH 'a*')", string.match("a*")) + AssertSQL("(\"stringOptional\" MATCH 'b*')", stringOptional.match("b*")) + } + + func test_regexp_buildsExpressionWithRegexpOperator() { + AssertSQL("(\"string\" REGEXP '^.+@.+\\.com$')", string.regexp("^.+@.+\\.com$")) + AssertSQL("(\"stringOptional\" REGEXP '^.+@.+\\.net$')", stringOptional.regexp("^.+@.+\\.net$")) + } + + func test_collate_buildsExpressionWithCollateOperator() { + AssertSQL("(\"string\" COLLATE BINARY)", string.collate(.binary)) + AssertSQL("(\"string\" COLLATE NOCASE)", string.collate(.nocase)) + AssertSQL("(\"string\" COLLATE RTRIM)", string.collate(.rtrim)) + AssertSQL("(\"string\" COLLATE \"CUSTOM\")", string.collate(.custom("CUSTOM"))) + + AssertSQL("(\"stringOptional\" COLLATE BINARY)", stringOptional.collate(.binary)) + AssertSQL("(\"stringOptional\" COLLATE NOCASE)", stringOptional.collate(.nocase)) + AssertSQL("(\"stringOptional\" COLLATE RTRIM)", stringOptional.collate(.rtrim)) + AssertSQL("(\"stringOptional\" COLLATE \"CUSTOM\")", stringOptional.collate(.custom("CUSTOM"))) + } + + func test_ltrim_wrapsStringWithLtrimFunction() { + AssertSQL("ltrim(\"string\")", string.ltrim()) + AssertSQL("ltrim(\"stringOptional\")", stringOptional.ltrim()) + + AssertSQL("ltrim(\"string\", ' ')", string.ltrim([" "])) + AssertSQL("ltrim(\"stringOptional\", ' ')", stringOptional.ltrim([" "])) + } + + func test_ltrim_wrapsStringWithRtrimFunction() { + AssertSQL("rtrim(\"string\")", string.rtrim()) + AssertSQL("rtrim(\"stringOptional\")", stringOptional.rtrim()) + + AssertSQL("rtrim(\"string\", ' ')", string.rtrim([" "])) + AssertSQL("rtrim(\"stringOptional\", ' ')", stringOptional.rtrim([" "])) + } + + func test_ltrim_wrapsStringWithTrimFunction() { + AssertSQL("trim(\"string\")", string.trim()) + AssertSQL("trim(\"stringOptional\")", stringOptional.trim()) + + AssertSQL("trim(\"string\", ' ')", string.trim([" "])) + AssertSQL("trim(\"stringOptional\", ' ')", stringOptional.trim([" "])) + } + + func test_replace_wrapsStringWithReplaceFunction() { + AssertSQL("replace(\"string\", '@example.com', '@example.net')", string.replace("@example.com", with: "@example.net")) + AssertSQL("replace(\"stringOptional\", '@example.net', '@example.com')", stringOptional.replace("@example.net", with: "@example.com")) + } + + func test_substring_wrapsStringWithSubstrFunction() { + AssertSQL("substr(\"string\", 1, 2)", string.substring(1, length: 2)) + AssertSQL("substr(\"stringOptional\", 2, 1)", stringOptional.substring(2, length: 1)) + } + + func test_subscriptWithRange_wrapsStringWithSubstrFunction() { + AssertSQL("substr(\"string\", 1, 2)", string[1..<3]) + AssertSQL("substr(\"stringOptional\", 2, 1)", stringOptional[2..<3]) + } + + func test_nilCoalescingOperator_wrapsOptionalsWithIfnullFunction() { + AssertSQL("ifnull(\"intOptional\", 1)", intOptional ?? 1) + // AssertSQL("ifnull(\"doubleOptional\", 1.0)", doubleOptional ?? 1) // rdar://problem/21677256 + XCTAssertEqual("ifnull(\"doubleOptional\", 1.0)", (doubleOptional ?? 1).asSQL()) + AssertSQL("ifnull(\"stringOptional\", 'literal')", stringOptional ?? "literal") + + AssertSQL("ifnull(\"intOptional\", \"int\")", intOptional ?? int) + AssertSQL("ifnull(\"doubleOptional\", \"double\")", doubleOptional ?? double) + AssertSQL("ifnull(\"stringOptional\", \"string\")", stringOptional ?? string) + + AssertSQL("ifnull(\"intOptional\", \"intOptional\")", intOptional ?? intOptional) + AssertSQL("ifnull(\"doubleOptional\", \"doubleOptional\")", doubleOptional ?? doubleOptional) + AssertSQL("ifnull(\"stringOptional\", \"stringOptional\")", stringOptional ?? stringOptional) + } + + func test_absoluteValue_wrapsNumberWithAbsFucntion() { + AssertSQL("abs(\"int\")", int.absoluteValue) + AssertSQL("abs(\"intOptional\")", intOptional.absoluteValue) + + AssertSQL("abs(\"double\")", double.absoluteValue) + AssertSQL("abs(\"doubleOptional\")", doubleOptional.absoluteValue) + } + + func test_contains_buildsExpressionWithInOperator() { + AssertSQL("(\"string\" IN ('hello', 'world'))", ["hello", "world"].contains(string)) + AssertSQL("(\"stringOptional\" IN ('hello', 'world'))", ["hello", "world"].contains(stringOptional)) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/CustomFunctionsTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/CustomFunctionsTests.swift new file mode 100644 index 0000000..67150cc --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/CustomFunctionsTests.swift @@ -0,0 +1,6 @@ +import XCTest +import SQLite + +class CustomFunctionsTests : XCTestCase { + +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/ExpressionTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/ExpressionTests.swift new file mode 100644 index 0000000..036e10c --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/ExpressionTests.swift @@ -0,0 +1,6 @@ +import XCTest +import SQLite + +class ExpressionTests : XCTestCase { + +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/FTS4Tests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/FTS4Tests.swift new file mode 100644 index 0000000..4373bf8 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/FTS4Tests.swift @@ -0,0 +1,208 @@ +import XCTest +import SQLite + +class FTS4Tests : XCTestCase { + + func test_create_onVirtualTable_withFTS4_compilesCreateVirtualTableExpression() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4()", + virtualTable.create(.FTS4()) + ) + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(\"string\")", + virtualTable.create(.FTS4(string)) + ) + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(tokenize=simple)", + virtualTable.create(.FTS4(tokenize: .Simple)) + ) + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(\"string\", tokenize=porter)", + virtualTable.create(.FTS4([string], tokenize: .Porter)) + ) + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(tokenize=unicode61 \"removeDiacritics=0\")", + virtualTable.create(.FTS4(tokenize: .Unicode61(removeDiacritics: false))) + ) + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(tokenize=unicode61 \"removeDiacritics=1\" \"tokenchars=.\" \"separators=X\")", + virtualTable.create(.FTS4(tokenize: .Unicode61(removeDiacritics: true, tokenchars: ["."], separators: ["X"]))) + ) + } + + func test_match_onVirtualTableAsExpression_compilesMatchExpression() { + AssertSQL("(\"virtual_table\" MATCH 'string')", virtualTable.match("string") as Expression) + AssertSQL("(\"virtual_table\" MATCH \"string\")", virtualTable.match(string) as Expression) + AssertSQL("(\"virtual_table\" MATCH \"stringOptional\")", virtualTable.match(stringOptional) as Expression) + } + + func test_match_onVirtualTableAsQueryType_compilesMatchExpression() { + AssertSQL("SELECT * FROM \"virtual_table\" WHERE (\"virtual_table\" MATCH 'string')", virtualTable.match("string") as QueryType) + AssertSQL("SELECT * FROM \"virtual_table\" WHERE (\"virtual_table\" MATCH \"string\")", virtualTable.match(string) as QueryType) + AssertSQL("SELECT * FROM \"virtual_table\" WHERE (\"virtual_table\" MATCH \"stringOptional\")", virtualTable.match(stringOptional) as QueryType) + } + +} + +class FTS4ConfigTests : XCTestCase { + var config: FTS4Config! + + override func setUp() { + super.setUp() + config = FTS4Config() + } + + func test_empty_config() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4()", + sql(config)) + } + + func test_config_column() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(\"string\")", + sql(config.column(string))) + } + + func test_config_columns() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(\"string\", \"int\")", + sql(config.columns([string, int]))) + } + + func test_config_unindexed_column() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(\"string\", notindexed=\"string\")", + sql(config.column(string, [.unindexed]))) + } + + func test_external_content_view() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(content=\"view\")", + sql(config.externalContent(_view ))) + } + + func test_external_content_virtual_table() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(content=\"virtual_table\")", + sql(config.externalContent(virtualTable))) + } + + func test_tokenizer_simple() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(tokenize=simple)", + sql(config.tokenizer(.Simple))) + } + + func test_tokenizer_porter() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(tokenize=porter)", + sql(config.tokenizer(.Porter))) + } + + func test_tokenizer_unicode61() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(tokenize=unicode61)", + sql(config.tokenizer(.Unicode61()))) + } + + func test_tokenizer_unicode61_with_options() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(tokenize=unicode61 \"removeDiacritics=1\" \"tokenchars=.\" \"separators=X\")", + sql(config.tokenizer(.Unicode61(removeDiacritics: true, tokenchars: ["."], separators: ["X"])))) + } + + func test_content_less() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(content=\"\")", + sql(config.contentless())) + } + + func test_config_matchinfo() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(matchinfo=\"fts3\")", + sql(config.matchInfo(.fts3))) + } + + func test_config_order_asc() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(order=\"asc\")", + sql(config.order(.asc))) + } + + func test_config_order_desc() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(order=\"desc\")", + sql(config.order(.desc))) + } + + func test_config_compress() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(compress=\"compress_foo\")", + sql(config.compress("compress_foo"))) + } + + func test_config_uncompress() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(uncompress=\"uncompress_foo\")", + sql(config.uncompress("uncompress_foo"))) + } + + func test_config_languageId() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(languageid=\"lid\")", + sql(config.languageId("lid"))) + } + + func test_config_all() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts4(\"int\", \"string\", \"date\", tokenize=porter, prefix=\"2,4\", content=\"table\", notindexed=\"string\", notindexed=\"date\", languageid=\"lid\", matchinfo=\"fts3\", order=\"desc\")", + sql(config + .tokenizer(.Porter) + .column(int) + .column(string, [.unindexed]) + .column(date, [.unindexed]) + .externalContent(table) + .matchInfo(.fts3) + .languageId("lid") + .order(.desc) + .prefix([2, 4])) + ) + } + + func sql(_ config: FTS4Config) -> String { + return virtualTable.create(.FTS4(config)) + } +} + +class FTS4IntegrationTests : SQLiteTestCase { +#if !SQLITE_SWIFT_STANDALONE && !SQLITE_SWIFT_SQLCIPHER + func test_registerTokenizer_registersTokenizer() { + let emails = VirtualTable("emails") + let subject = Expression("subject") + let body = Expression("body") + + let locale = CFLocaleCopyCurrent() + let tokenizerName = "tokenizer" + let tokenizer = CFStringTokenizerCreate(nil, "" as CFString!, CFRangeMake(0, 0), UInt(kCFStringTokenizerUnitWord), locale) + try! db.registerTokenizer(tokenizerName) { string in + CFStringTokenizerSetString(tokenizer, string as CFString, CFRangeMake(0, CFStringGetLength(string as CFString))) + if CFStringTokenizerAdvanceToNextToken(tokenizer).isEmpty { + return nil + } + let range = CFStringTokenizerGetCurrentTokenRange(tokenizer) + let input = CFStringCreateWithSubstring(kCFAllocatorDefault, string as CFString, range)! + let token = CFStringCreateMutableCopy(nil, range.length, input)! + CFStringLowercase(token, locale) + CFStringTransform(token, nil, kCFStringTransformStripDiacritics, false) + return (token as String, string.range(of: input as String)!) + } + + try! db.run(emails.create(.FTS4([subject, body], tokenize: .Custom(tokenizerName)))) + AssertSQL("CREATE VIRTUAL TABLE \"emails\" USING fts4(\"subject\", \"body\", tokenize=\"SQLite.swift\" \"tokenizer\")") + + try! _ = db.run(emails.insert(subject <- "Aún más cáfe!")) + XCTAssertEqual(1, try! db.scalar(emails.filter(emails.match("aun")).count)) + } +#endif +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/FTS5Tests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/FTS5Tests.swift new file mode 100644 index 0000000..63d8dc4 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/FTS5Tests.swift @@ -0,0 +1,124 @@ +import XCTest +import SQLite + +class FTS5Tests: XCTestCase { + var config: FTS5Config! + + override func setUp() { + super.setUp() + config = FTS5Config() + } + + func test_empty_config() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5()", + sql(config)) + } + + func test_config_column() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(\"string\")", + sql(config.column(string))) + } + + func test_config_columns() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(\"string\", \"int\")", + sql(config.columns([string, int]))) + } + + func test_config_unindexed_column() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(\"string\" UNINDEXED)", + sql(config.column(string, [.unindexed]))) + } + + func test_external_content_table() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(content=\"table\")", + sql(config.externalContent(table))) + } + + func test_external_content_view() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(content=\"view\")", + sql(config.externalContent(_view))) + } + + func test_external_content_virtual_table() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(content=\"virtual_table\")", + sql(config.externalContent(virtualTable))) + } + + func test_content_less() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(content=\"\")", + sql(config.contentless())) + } + + func test_content_rowid() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(content_rowid=\"string\")", + sql(config.contentRowId(string))) + } + + func test_tokenizer_porter() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(tokenize=porter)", + sql(config.tokenizer(.Porter))) + } + + func test_tokenizer_unicode61() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(tokenize=unicode61)", + sql(config.tokenizer(.Unicode61()))) + } + + func test_tokenizer_unicode61_with_options() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(tokenize=unicode61 \"removeDiacritics=1\" \"tokenchars=.\" \"separators=X\")", + sql(config.tokenizer(.Unicode61(removeDiacritics: true, tokenchars: ["."], separators: ["X"])))) + } + + func test_column_size() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(columnsize=1)", + sql(config.columnSize(1))) + } + + func test_detail_full() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(detail=\"full\")", + sql(config.detail(.full))) + } + + func test_detail_column() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(detail=\"column\")", + sql(config.detail(.column))) + } + + func test_detail_none() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(detail=\"none\")", + sql(config.detail(.none))) + } + + func test_fts5_config_all() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING fts5(\"int\", \"string\" UNINDEXED, \"date\" UNINDEXED, tokenize=porter, prefix=\"2,4\", content=\"table\")", + sql(config + .tokenizer(.Porter) + .column(int) + .column(string, [.unindexed]) + .column(date, [.unindexed]) + .externalContent(table) + .prefix([2, 4])) + ) + } + + func sql(_ config: FTS5Config) -> String { + return virtualTable.create(.FTS5(config)) + } +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/Fixtures.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/Fixtures.swift new file mode 100644 index 0000000..13f83f7 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/Fixtures.swift @@ -0,0 +1,8 @@ +import Foundation + +func fixture(_ name: String, withExtension: String?) -> String { + let testBundle = Bundle(for: SQLiteTestCase.self) + return testBundle.url( + forResource: URL(string: "fixtures")?.appendingPathComponent(name).path, + withExtension: withExtension)!.path +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/FoundationTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/FoundationTests.swift new file mode 100644 index 0000000..0df746d --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/FoundationTests.swift @@ -0,0 +1,16 @@ +import XCTest +import SQLite + +class FoundationTests : XCTestCase { + func testDataFromBlob() { + let data = Data(bytes: [1, 2, 3]) + let blob = data.datatypeValue + XCTAssertEqual([1, 2, 3], blob.bytes) + } + + func testBlobToData() { + let blob = Blob(bytes: [1, 2, 3]) + let data = Data.fromDatatypeValue(blob) + XCTAssertEqual(Data(bytes: [1, 2, 3]), data) + } +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/Info.plist b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/OperatorsTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/OperatorsTests.swift new file mode 100644 index 0000000..f0e585c --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/OperatorsTests.swift @@ -0,0 +1,296 @@ +import XCTest +import SQLite + +class OperatorsTests : XCTestCase { + + func test_stringExpressionPlusStringExpression_buildsConcatenatingStringExpression() { + AssertSQL("(\"string\" || \"string\")", string + string) + AssertSQL("(\"string\" || \"stringOptional\")", string + stringOptional) + AssertSQL("(\"stringOptional\" || \"string\")", stringOptional + string) + AssertSQL("(\"stringOptional\" || \"stringOptional\")", stringOptional + stringOptional) + AssertSQL("(\"string\" || 'literal')", string + "literal") + AssertSQL("(\"stringOptional\" || 'literal')", stringOptional + "literal") + AssertSQL("('literal' || \"string\")", "literal" + string) + AssertSQL("('literal' || \"stringOptional\")", "literal" + stringOptional) + } + + func test_numberExpression_plusNumberExpression_buildsAdditiveNumberExpression() { + AssertSQL("(\"int\" + \"int\")", int + int) + AssertSQL("(\"int\" + \"intOptional\")", int + intOptional) + AssertSQL("(\"intOptional\" + \"int\")", intOptional + int) + AssertSQL("(\"intOptional\" + \"intOptional\")", intOptional + intOptional) + AssertSQL("(\"int\" + 1)", int + 1) + AssertSQL("(\"intOptional\" + 1)", intOptional + 1) + AssertSQL("(1 + \"int\")", 1 + int) + AssertSQL("(1 + \"intOptional\")", 1 + intOptional) + + AssertSQL("(\"double\" + \"double\")", double + double) + AssertSQL("(\"double\" + \"doubleOptional\")", double + doubleOptional) + AssertSQL("(\"doubleOptional\" + \"double\")", doubleOptional + double) + AssertSQL("(\"doubleOptional\" + \"doubleOptional\")", doubleOptional + doubleOptional) + AssertSQL("(\"double\" + 1.0)", double + 1) + AssertSQL("(\"doubleOptional\" + 1.0)", doubleOptional + 1) + AssertSQL("(1.0 + \"double\")", 1 + double) + AssertSQL("(1.0 + \"doubleOptional\")", 1 + doubleOptional) + } + + func test_numberExpression_minusNumberExpression_buildsSubtractiveNumberExpression() { + AssertSQL("(\"int\" - \"int\")", int - int) + AssertSQL("(\"int\" - \"intOptional\")", int - intOptional) + AssertSQL("(\"intOptional\" - \"int\")", intOptional - int) + AssertSQL("(\"intOptional\" - \"intOptional\")", intOptional - intOptional) + AssertSQL("(\"int\" - 1)", int - 1) + AssertSQL("(\"intOptional\" - 1)", intOptional - 1) + AssertSQL("(1 - \"int\")", 1 - int) + AssertSQL("(1 - \"intOptional\")", 1 - intOptional) + + AssertSQL("(\"double\" - \"double\")", double - double) + AssertSQL("(\"double\" - \"doubleOptional\")", double - doubleOptional) + AssertSQL("(\"doubleOptional\" - \"double\")", doubleOptional - double) + AssertSQL("(\"doubleOptional\" - \"doubleOptional\")", doubleOptional - doubleOptional) + AssertSQL("(\"double\" - 1.0)", double - 1) + AssertSQL("(\"doubleOptional\" - 1.0)", doubleOptional - 1) + AssertSQL("(1.0 - \"double\")", 1 - double) + AssertSQL("(1.0 - \"doubleOptional\")", 1 - doubleOptional) + } + + func test_numberExpression_timesNumberExpression_buildsMultiplicativeNumberExpression() { + AssertSQL("(\"int\" * \"int\")", int * int) + AssertSQL("(\"int\" * \"intOptional\")", int * intOptional) + AssertSQL("(\"intOptional\" * \"int\")", intOptional * int) + AssertSQL("(\"intOptional\" * \"intOptional\")", intOptional * intOptional) + AssertSQL("(\"int\" * 1)", int * 1) + AssertSQL("(\"intOptional\" * 1)", intOptional * 1) + AssertSQL("(1 * \"int\")", 1 * int) + AssertSQL("(1 * \"intOptional\")", 1 * intOptional) + + AssertSQL("(\"double\" * \"double\")", double * double) + AssertSQL("(\"double\" * \"doubleOptional\")", double * doubleOptional) + AssertSQL("(\"doubleOptional\" * \"double\")", doubleOptional * double) + AssertSQL("(\"doubleOptional\" * \"doubleOptional\")", doubleOptional * doubleOptional) + AssertSQL("(\"double\" * 1.0)", double * 1) + AssertSQL("(\"doubleOptional\" * 1.0)", doubleOptional * 1) + AssertSQL("(1.0 * \"double\")", 1 * double) + AssertSQL("(1.0 * \"doubleOptional\")", 1 * doubleOptional) + } + + func test_numberExpression_dividedByNumberExpression_buildsDivisiveNumberExpression() { + AssertSQL("(\"int\" / \"int\")", int / int) + AssertSQL("(\"int\" / \"intOptional\")", int / intOptional) + AssertSQL("(\"intOptional\" / \"int\")", intOptional / int) + AssertSQL("(\"intOptional\" / \"intOptional\")", intOptional / intOptional) + AssertSQL("(\"int\" / 1)", int / 1) + AssertSQL("(\"intOptional\" / 1)", intOptional / 1) + AssertSQL("(1 / \"int\")", 1 / int) + AssertSQL("(1 / \"intOptional\")", 1 / intOptional) + + AssertSQL("(\"double\" / \"double\")", double / double) + AssertSQL("(\"double\" / \"doubleOptional\")", double / doubleOptional) + AssertSQL("(\"doubleOptional\" / \"double\")", doubleOptional / double) + AssertSQL("(\"doubleOptional\" / \"doubleOptional\")", doubleOptional / doubleOptional) + AssertSQL("(\"double\" / 1.0)", double / 1) + AssertSQL("(\"doubleOptional\" / 1.0)", doubleOptional / 1) + AssertSQL("(1.0 / \"double\")", 1 / double) + AssertSQL("(1.0 / \"doubleOptional\")", 1 / doubleOptional) + } + + func test_numberExpression_prefixedWithMinus_buildsInvertedNumberExpression() { + AssertSQL("-(\"int\")", -int) + AssertSQL("-(\"intOptional\")", -intOptional) + + AssertSQL("-(\"double\")", -double) + AssertSQL("-(\"doubleOptional\")", -doubleOptional) + } + + func test_integerExpression_moduloIntegerExpression_buildsModuloIntegerExpression() { + AssertSQL("(\"int\" % \"int\")", int % int) + AssertSQL("(\"int\" % \"intOptional\")", int % intOptional) + AssertSQL("(\"intOptional\" % \"int\")", intOptional % int) + AssertSQL("(\"intOptional\" % \"intOptional\")", intOptional % intOptional) + AssertSQL("(\"int\" % 1)", int % 1) + AssertSQL("(\"intOptional\" % 1)", intOptional % 1) + AssertSQL("(1 % \"int\")", 1 % int) + AssertSQL("(1 % \"intOptional\")", 1 % intOptional) + } + + func test_integerExpression_bitShiftLeftIntegerExpression_buildsLeftShiftedIntegerExpression() { + AssertSQL("(\"int\" << \"int\")", int << int) + AssertSQL("(\"int\" << \"intOptional\")", int << intOptional) + AssertSQL("(\"intOptional\" << \"int\")", intOptional << int) + AssertSQL("(\"intOptional\" << \"intOptional\")", intOptional << intOptional) + AssertSQL("(\"int\" << 1)", int << 1) + AssertSQL("(\"intOptional\" << 1)", intOptional << 1) + AssertSQL("(1 << \"int\")", 1 << int) + AssertSQL("(1 << \"intOptional\")", 1 << intOptional) + } + + func test_integerExpression_bitShiftRightIntegerExpression_buildsRightShiftedIntegerExpression() { + AssertSQL("(\"int\" >> \"int\")", int >> int) + AssertSQL("(\"int\" >> \"intOptional\")", int >> intOptional) + AssertSQL("(\"intOptional\" >> \"int\")", intOptional >> int) + AssertSQL("(\"intOptional\" >> \"intOptional\")", intOptional >> intOptional) + AssertSQL("(\"int\" >> 1)", int >> 1) + AssertSQL("(\"intOptional\" >> 1)", intOptional >> 1) + AssertSQL("(1 >> \"int\")", 1 >> int) + AssertSQL("(1 >> \"intOptional\")", 1 >> intOptional) + } + + func test_integerExpression_bitwiseAndIntegerExpression_buildsAndedIntegerExpression() { + AssertSQL("(\"int\" & \"int\")", int & int) + AssertSQL("(\"int\" & \"intOptional\")", int & intOptional) + AssertSQL("(\"intOptional\" & \"int\")", intOptional & int) + AssertSQL("(\"intOptional\" & \"intOptional\")", intOptional & intOptional) + AssertSQL("(\"int\" & 1)", int & 1) + AssertSQL("(\"intOptional\" & 1)", intOptional & 1) + AssertSQL("(1 & \"int\")", 1 & int) + AssertSQL("(1 & \"intOptional\")", 1 & intOptional) + } + + func test_integerExpression_bitwiseOrIntegerExpression_buildsOredIntegerExpression() { + AssertSQL("(\"int\" | \"int\")", int | int) + AssertSQL("(\"int\" | \"intOptional\")", int | intOptional) + AssertSQL("(\"intOptional\" | \"int\")", intOptional | int) + AssertSQL("(\"intOptional\" | \"intOptional\")", intOptional | intOptional) + AssertSQL("(\"int\" | 1)", int | 1) + AssertSQL("(\"intOptional\" | 1)", intOptional | 1) + AssertSQL("(1 | \"int\")", 1 | int) + AssertSQL("(1 | \"intOptional\")", 1 | intOptional) + } + + func test_integerExpression_bitwiseExclusiveOrIntegerExpression_buildsOredIntegerExpression() { + AssertSQL("(~((\"int\" & \"int\")) & (\"int\" | \"int\"))", int ^ int) + AssertSQL("(~((\"int\" & \"intOptional\")) & (\"int\" | \"intOptional\"))", int ^ intOptional) + AssertSQL("(~((\"intOptional\" & \"int\")) & (\"intOptional\" | \"int\"))", intOptional ^ int) + AssertSQL("(~((\"intOptional\" & \"intOptional\")) & (\"intOptional\" | \"intOptional\"))", intOptional ^ intOptional) + AssertSQL("(~((\"int\" & 1)) & (\"int\" | 1))", int ^ 1) + AssertSQL("(~((\"intOptional\" & 1)) & (\"intOptional\" | 1))", intOptional ^ 1) + AssertSQL("(~((1 & \"int\")) & (1 | \"int\"))", 1 ^ int) + AssertSQL("(~((1 & \"intOptional\")) & (1 | \"intOptional\"))", 1 ^ intOptional) + } + + func test_bitwiseNot_integerExpression_buildsComplementIntegerExpression() { + AssertSQL("~(\"int\")", ~int) + AssertSQL("~(\"intOptional\")", ~intOptional) + } + + func test_equalityOperator_withEquatableExpressions_buildsBooleanExpression() { + AssertSQL("(\"bool\" = \"bool\")", bool == bool) + AssertSQL("(\"bool\" = \"boolOptional\")", bool == boolOptional) + AssertSQL("(\"boolOptional\" = \"bool\")", boolOptional == bool) + AssertSQL("(\"boolOptional\" = \"boolOptional\")", boolOptional == boolOptional) + AssertSQL("(\"bool\" = 1)", bool == true) + AssertSQL("(\"boolOptional\" = 1)", boolOptional == true) + AssertSQL("(1 = \"bool\")", true == bool) + AssertSQL("(1 = \"boolOptional\")", true == boolOptional) + + AssertSQL("(\"boolOptional\" IS NULL)", boolOptional == nil) + AssertSQL("(NULL IS \"boolOptional\")", nil == boolOptional) + } + + func test_inequalityOperator_withEquatableExpressions_buildsBooleanExpression() { + AssertSQL("(\"bool\" != \"bool\")", bool != bool) + AssertSQL("(\"bool\" != \"boolOptional\")", bool != boolOptional) + AssertSQL("(\"boolOptional\" != \"bool\")", boolOptional != bool) + AssertSQL("(\"boolOptional\" != \"boolOptional\")", boolOptional != boolOptional) + AssertSQL("(\"bool\" != 1)", bool != true) + AssertSQL("(\"boolOptional\" != 1)", boolOptional != true) + AssertSQL("(1 != \"bool\")", true != bool) + AssertSQL("(1 != \"boolOptional\")", true != boolOptional) + + AssertSQL("(\"boolOptional\" IS NOT NULL)", boolOptional != nil) + AssertSQL("(NULL IS NOT \"boolOptional\")", nil != boolOptional) + } + + func test_greaterThanOperator_withComparableExpressions_buildsBooleanExpression() { + AssertSQL("(\"bool\" > \"bool\")", bool > bool) + AssertSQL("(\"bool\" > \"boolOptional\")", bool > boolOptional) + AssertSQL("(\"boolOptional\" > \"bool\")", boolOptional > bool) + AssertSQL("(\"boolOptional\" > \"boolOptional\")", boolOptional > boolOptional) + AssertSQL("(\"bool\" > 1)", bool > true) + AssertSQL("(\"boolOptional\" > 1)", boolOptional > true) + AssertSQL("(1 > \"bool\")", true > bool) + AssertSQL("(1 > \"boolOptional\")", true > boolOptional) + } + + func test_greaterThanOrEqualToOperator_withComparableExpressions_buildsBooleanExpression() { + AssertSQL("(\"bool\" >= \"bool\")", bool >= bool) + AssertSQL("(\"bool\" >= \"boolOptional\")", bool >= boolOptional) + AssertSQL("(\"boolOptional\" >= \"bool\")", boolOptional >= bool) + AssertSQL("(\"boolOptional\" >= \"boolOptional\")", boolOptional >= boolOptional) + AssertSQL("(\"bool\" >= 1)", bool >= true) + AssertSQL("(\"boolOptional\" >= 1)", boolOptional >= true) + AssertSQL("(1 >= \"bool\")", true >= bool) + AssertSQL("(1 >= \"boolOptional\")", true >= boolOptional) + } + + func test_lessThanOperator_withComparableExpressions_buildsBooleanExpression() { + AssertSQL("(\"bool\" < \"bool\")", bool < bool) + AssertSQL("(\"bool\" < \"boolOptional\")", bool < boolOptional) + AssertSQL("(\"boolOptional\" < \"bool\")", boolOptional < bool) + AssertSQL("(\"boolOptional\" < \"boolOptional\")", boolOptional < boolOptional) + AssertSQL("(\"bool\" < 1)", bool < true) + AssertSQL("(\"boolOptional\" < 1)", boolOptional < true) + AssertSQL("(1 < \"bool\")", true < bool) + AssertSQL("(1 < \"boolOptional\")", true < boolOptional) + } + + func test_lessThanOrEqualToOperator_withComparableExpressions_buildsBooleanExpression() { + AssertSQL("(\"bool\" <= \"bool\")", bool <= bool) + AssertSQL("(\"bool\" <= \"boolOptional\")", bool <= boolOptional) + AssertSQL("(\"boolOptional\" <= \"bool\")", boolOptional <= bool) + AssertSQL("(\"boolOptional\" <= \"boolOptional\")", boolOptional <= boolOptional) + AssertSQL("(\"bool\" <= 1)", bool <= true) + AssertSQL("(\"boolOptional\" <= 1)", boolOptional <= true) + AssertSQL("(1 <= \"bool\")", true <= bool) + AssertSQL("(1 <= \"boolOptional\")", true <= boolOptional) + } + + func test_patternMatchingOperator_withComparableCountableClosedRange_buildsBetweenBooleanExpression() { + AssertSQL("\"int\" BETWEEN 0 AND 5", 0...5 ~= int) + AssertSQL("\"intOptional\" BETWEEN 0 AND 5", 0...5 ~= intOptional) + } + + func test_patternMatchingOperator_withComparableClosedRange_buildsBetweenBooleanExpression() { + AssertSQL("\"double\" BETWEEN 1.2 AND 4.5", 1.2...4.5 ~= double) + AssertSQL("\"doubleOptional\" BETWEEN 1.2 AND 4.5", 1.2...4.5 ~= doubleOptional) + } + + func test_patternMatchingOperator_withomparableClosedRangeString_buildsBetweenBooleanExpression() { + AssertSQL("\"string\" BETWEEN 'a' AND 'b'", "a"..."b" ~= string) + AssertSQL("\"stringOptional\" BETWEEN 'a' AND 'b'", "a"..."b" ~= stringOptional) + } + + func test_doubleAndOperator_withBooleanExpressions_buildsCompoundExpression() { + AssertSQL("(\"bool\" AND \"bool\")", bool && bool) + AssertSQL("(\"bool\" AND \"boolOptional\")", bool && boolOptional) + AssertSQL("(\"boolOptional\" AND \"bool\")", boolOptional && bool) + AssertSQL("(\"boolOptional\" AND \"boolOptional\")", boolOptional && boolOptional) + AssertSQL("(\"bool\" AND 1)", bool && true) + AssertSQL("(\"boolOptional\" AND 1)", boolOptional && true) + AssertSQL("(1 AND \"bool\")", true && bool) + AssertSQL("(1 AND \"boolOptional\")", true && boolOptional) + } + + func test_doubleOrOperator_withBooleanExpressions_buildsCompoundExpression() { + AssertSQL("(\"bool\" OR \"bool\")", bool || bool) + AssertSQL("(\"bool\" OR \"boolOptional\")", bool || boolOptional) + AssertSQL("(\"boolOptional\" OR \"bool\")", boolOptional || bool) + AssertSQL("(\"boolOptional\" OR \"boolOptional\")", boolOptional || boolOptional) + AssertSQL("(\"bool\" OR 1)", bool || true) + AssertSQL("(\"boolOptional\" OR 1)", boolOptional || true) + AssertSQL("(1 OR \"bool\")", true || bool) + AssertSQL("(1 OR \"boolOptional\")", true || boolOptional) + } + + func test_unaryNotOperator_withBooleanExpressions_buildsNotExpression() { + AssertSQL("NOT (\"bool\")", !bool) + AssertSQL("NOT (\"boolOptional\")", !boolOptional) + } + + func test_precedencePreserved() { + let n = Expression(value: 1) + AssertSQL("(((1 = 1) AND (1 = 1)) OR (1 = 1))", (n == n && n == n) || n == n) + AssertSQL("((1 = 1) AND ((1 = 1) OR (1 = 1)))", n == n && (n == n || n == n)) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/QueryTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/QueryTests.swift new file mode 100644 index 0000000..2cf164c --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/QueryTests.swift @@ -0,0 +1,365 @@ +import XCTest +import SQLite + +class QueryTests : XCTestCase { + + let users = Table("users") + let id = Expression("id") + let email = Expression("email") + let age = Expression("age") + let admin = Expression("admin") + let optionalAdmin = Expression("admin") + + let posts = Table("posts") + let userId = Expression("user_id") + let categoryId = Expression("category_id") + let published = Expression("published") + + let categories = Table("categories") + let tag = Expression("tag") + + func test_select_withExpression_compilesSelectClause() { + AssertSQL("SELECT \"email\" FROM \"users\"", users.select(email)) + } + + func test_select_withStarExpression_compilesSelectClause() { + AssertSQL("SELECT * FROM \"users\"", users.select(*)) + } + + func test_select_withNamespacedStarExpression_compilesSelectClause() { + AssertSQL("SELECT \"users\".* FROM \"users\"", users.select(users[*])) + } + + func test_select_withVariadicExpressions_compilesSelectClause() { + AssertSQL("SELECT \"email\", count(*) FROM \"users\"", users.select(email, count(*))) + } + + func test_select_withExpressions_compilesSelectClause() { + AssertSQL("SELECT \"email\", count(*) FROM \"users\"", users.select([email, count(*)])) + } + + func test_selectDistinct_withExpression_compilesSelectClause() { + AssertSQL("SELECT DISTINCT \"age\" FROM \"users\"", users.select(distinct: age)) + } + + func test_selectDistinct_withExpressions_compilesSelectClause() { + AssertSQL("SELECT DISTINCT \"age\", \"admin\" FROM \"users\"", users.select(distinct: [age, admin])) + } + + func test_selectDistinct_withStar_compilesSelectClause() { + AssertSQL("SELECT DISTINCT * FROM \"users\"", users.select(distinct: *)) + } + + func test_join_compilesJoinClause() { + AssertSQL( + "SELECT * FROM \"users\" INNER JOIN \"posts\" ON (\"posts\".\"user_id\" = \"users\".\"id\")", + users.join(posts, on: posts[userId] == users[id]) + ) + } + + func test_join_withExplicitType_compilesJoinClauseWithType() { + AssertSQL( + "SELECT * FROM \"users\" LEFT OUTER JOIN \"posts\" ON (\"posts\".\"user_id\" = \"users\".\"id\")", + users.join(.leftOuter, posts, on: posts[userId] == users[id]) + ) + + AssertSQL( + "SELECT * FROM \"users\" CROSS JOIN \"posts\" ON (\"posts\".\"user_id\" = \"users\".\"id\")", + users.join(.cross, posts, on: posts[userId] == users[id]) + ) + } + + func test_join_withTableCondition_compilesJoinClauseWithTableCondition() { + AssertSQL( + "SELECT * FROM \"users\" INNER JOIN \"posts\" ON ((\"posts\".\"user_id\" = \"users\".\"id\") AND \"published\")", + users.join(posts.filter(published), on: posts[userId] == users[id]) + ) + } + + func test_join_whenChained_compilesAggregateJoinClause() { + AssertSQL( + "SELECT * FROM \"users\" " + + "INNER JOIN \"posts\" ON (\"posts\".\"user_id\" = \"users\".\"id\") " + + "INNER JOIN \"categories\" ON (\"categories\".\"id\" = \"posts\".\"category_id\")", + users.join(posts, on: posts[userId] == users[id]).join(categories, on: categories[id] == posts[categoryId]) + ) + } + + func test_filter_compilesWhereClause() { + AssertSQL("SELECT * FROM \"users\" WHERE (\"admin\" = 1)", users.filter(admin == true)) + } + + func test_filter_compilesWhereClause_false() { + AssertSQL("SELECT * FROM \"users\" WHERE (\"admin\" = 0)", users.filter(admin == false)) + } + + func test_filter_compilesWhereClause_optional() { + AssertSQL("SELECT * FROM \"users\" WHERE (\"admin\" = 1)", users.filter(optionalAdmin == true)) + } + + func test_filter_compilesWhereClause_optional_false() { + AssertSQL("SELECT * FROM \"users\" WHERE (\"admin\" = 0)", users.filter(optionalAdmin == false)) + } + + func test_where_compilesWhereClause() { + AssertSQL("SELECT * FROM \"users\" WHERE (\"admin\" = 1)", users.where(admin == true)) + } + + func test_where_compilesWhereClause_false() { + AssertSQL("SELECT * FROM \"users\" WHERE (\"admin\" = 0)", users.where(admin == false)) + } + + func test_where_compilesWhereClause_optional() { + AssertSQL("SELECT * FROM \"users\" WHERE (\"admin\" = 1)", users.where(optionalAdmin == true)) + } + + func test_where_compilesWhereClause_optional_false() { + AssertSQL("SELECT * FROM \"users\" WHERE (\"admin\" = 0)", users.where(optionalAdmin == false)) + } + + func test_filter_whenChained_compilesAggregateWhereClause() { + AssertSQL( + "SELECT * FROM \"users\" WHERE ((\"age\" >= 35) AND \"admin\")", + users.filter(age >= 35).filter(admin) + ) + } + + func test_group_withSingleExpressionName_compilesGroupClause() { + AssertSQL("SELECT * FROM \"users\" GROUP BY \"age\"", + users.group(age)) + } + + func test_group_withVariadicExpressionNames_compilesGroupClause() { + AssertSQL("SELECT * FROM \"users\" GROUP BY \"age\", \"admin\"", users.group(age, admin)) + } + + func test_group_withExpressionNameAndHavingBindings_compilesGroupClause() { + AssertSQL("SELECT * FROM \"users\" GROUP BY \"age\" HAVING \"admin\"", users.group(age, having: admin)) + AssertSQL("SELECT * FROM \"users\" GROUP BY \"age\" HAVING (\"age\" >= 30)", users.group(age, having: age >= 30)) + } + + func test_group_withExpressionNamesAndHavingBindings_compilesGroupClause() { + AssertSQL( + "SELECT * FROM \"users\" GROUP BY \"age\", \"admin\" HAVING \"admin\"", + users.group([age, admin], having: admin) + ) + AssertSQL( + "SELECT * FROM \"users\" GROUP BY \"age\", \"admin\" HAVING (\"age\" >= 30)", + users.group([age, admin], having: age >= 30) + ) + } + + func test_order_withSingleExpressionName_compilesOrderClause() { + AssertSQL("SELECT * FROM \"users\" ORDER BY \"age\"", users.order(age)) + } + + func test_order_withVariadicExpressionNames_compilesOrderClause() { + AssertSQL("SELECT * FROM \"users\" ORDER BY \"age\", \"email\"", users.order(age, email)) + } + + func test_order_withArrayExpressionNames_compilesOrderClause() { + AssertSQL("SELECT * FROM \"users\" ORDER BY \"age\", \"email\"", users.order([age, email])) + } + + func test_order_withExpressionAndSortDirection_compilesOrderClause() { +// AssertSQL("SELECT * FROM \"users\" ORDER BY \"age\" DESC, \"email\" ASC", users.order(age.desc, email.asc)) + } + + func test_order_whenChained_resetsOrderClause() { + AssertSQL("SELECT * FROM \"users\" ORDER BY \"age\"", users.order(email).order(age)) + } + + func test_reverse_withoutOrder_ordersByRowIdDescending() { +// AssertSQL("SELECT * FROM \"users\" ORDER BY \"ROWID\" DESC", users.reverse()) + } + + func test_reverse_withOrder_reversesOrder() { +// AssertSQL("SELECT * FROM \"users\" ORDER BY \"age\" DESC, \"email\" ASC", users.order(age, email.desc).reverse()) + } + + func test_limit_compilesLimitClause() { + AssertSQL("SELECT * FROM \"users\" LIMIT 5", users.limit(5)) + } + + func test_limit_withOffset_compilesOffsetClause() { + AssertSQL("SELECT * FROM \"users\" LIMIT 5 OFFSET 5", users.limit(5, offset: 5)) + } + + func test_limit_whenChained_overridesLimit() { + let query = users.limit(5) + + AssertSQL("SELECT * FROM \"users\" LIMIT 10", query.limit(10)) + AssertSQL("SELECT * FROM \"users\"", query.limit(nil)) + } + + func test_limit_whenChained_withOffset_overridesOffset() { + let query = users.limit(5, offset: 5) + + AssertSQL("SELECT * FROM \"users\" LIMIT 10 OFFSET 20", query.limit(10, offset: 20)) + AssertSQL("SELECT * FROM \"users\"", query.limit(nil)) + } + + func test_alias_aliasesTable() { + let managerId = Expression("manager_id") + + let managers = users.alias("managers") + + AssertSQL( + "SELECT * FROM \"users\" " + + "INNER JOIN \"users\" AS \"managers\" ON (\"managers\".\"id\" = \"users\".\"manager_id\")", + users.join(managers, on: managers[id] == users[managerId]) + ) + } + + func test_insert_compilesInsertExpression() { + AssertSQL( + "INSERT INTO \"users\" (\"email\", \"age\") VALUES ('alice@example.com', 30)", + users.insert(email <- "alice@example.com", age <- 30) + ) + } + + func test_insert_withOnConflict_compilesInsertOrOnConflictExpression() { + AssertSQL( + "INSERT OR REPLACE INTO \"users\" (\"email\", \"age\") VALUES ('alice@example.com', 30)", + users.insert(or: .replace, email <- "alice@example.com", age <- 30) + ) + } + + func test_insert_compilesInsertExpressionWithDefaultValues() { + AssertSQL("INSERT INTO \"users\" DEFAULT VALUES", users.insert()) + } + + func test_insert_withQuery_compilesInsertExpressionWithSelectStatement() { + let emails = Table("emails") + + AssertSQL( + "INSERT INTO \"emails\" SELECT \"email\" FROM \"users\" WHERE \"admin\"", + emails.insert(users.select(email).filter(admin)) + ) + } + + func test_update_compilesUpdateExpression() { + AssertSQL( + "UPDATE \"users\" SET \"age\" = 30, \"admin\" = 1 WHERE (\"id\" = 1)", + users.filter(id == 1).update(age <- 30, admin <- true) + ) + } + + func test_delete_compilesDeleteExpression() { + AssertSQL( + "DELETE FROM \"users\" WHERE (\"id\" = 1)", + users.filter(id == 1).delete() + ) + } + + func test_delete_compilesExistsExpression() { + AssertSQL( + "SELECT EXISTS (SELECT * FROM \"users\")", + users.exists + ) + } + + func test_count_returnsCountExpression() { + AssertSQL("SELECT count(*) FROM \"users\"", users.count) + } + + func test_scalar_returnsScalarExpression() { + AssertSQL("SELECT \"int\" FROM \"table\"", table.select(int) as ScalarQuery) + AssertSQL("SELECT \"intOptional\" FROM \"table\"", table.select(intOptional) as ScalarQuery) + AssertSQL("SELECT DISTINCT \"int\" FROM \"table\"", table.select(distinct: int) as ScalarQuery) + AssertSQL("SELECT DISTINCT \"intOptional\" FROM \"table\"", table.select(distinct: intOptional) as ScalarQuery) + } + + func test_subscript_withExpression_returnsNamespacedExpression() { + let query = Table("query") + + AssertSQL("\"query\".\"blob\"", query[data]) + AssertSQL("\"query\".\"blobOptional\"", query[dataOptional]) + + AssertSQL("\"query\".\"bool\"", query[bool]) + AssertSQL("\"query\".\"boolOptional\"", query[boolOptional]) + + AssertSQL("\"query\".\"date\"", query[date]) + AssertSQL("\"query\".\"dateOptional\"", query[dateOptional]) + + AssertSQL("\"query\".\"double\"", query[double]) + AssertSQL("\"query\".\"doubleOptional\"", query[doubleOptional]) + + AssertSQL("\"query\".\"int\"", query[int]) + AssertSQL("\"query\".\"intOptional\"", query[intOptional]) + + AssertSQL("\"query\".\"int64\"", query[int64]) + AssertSQL("\"query\".\"int64Optional\"", query[int64Optional]) + + AssertSQL("\"query\".\"string\"", query[string]) + AssertSQL("\"query\".\"stringOptional\"", query[stringOptional]) + + AssertSQL("\"query\".*", query[*]) + } + + func test_tableNamespacedByDatabase() { + let table = Table("table", database: "attached") + + AssertSQL("SELECT * FROM \"attached\".\"table\"", table) + } + +} + +class QueryIntegrationTests : SQLiteTestCase { + + let id = Expression("id") + let email = Expression("email") + + override func setUp() { + super.setUp() + + CreateUsersTable() + } + + // MARK: - + + func test_select() { + for _ in try! db.prepare(users) { + // FIXME + } + + let managerId = Expression("manager_id") + let managers = users.alias("managers") + + let alice = try! db.run(users.insert(email <- "alice@example.com")) + _ = try! db.run(users.insert(email <- "betsy@example.com", managerId <- alice)) + + for user in try! db.prepare(users.join(managers, on: managers[id] == users[managerId])) { + _ = user[users[managerId]] + } + } + + func test_scalar() { + XCTAssertEqual(0, try! db.scalar(users.count)) + XCTAssertEqual(false, try! db.scalar(users.exists)) + + try! InsertUsers("alice") + XCTAssertEqual(1, try! db.scalar(users.select(id.average))) + } + + func test_pluck() { + let rowid = try! db.run(users.insert(email <- "alice@example.com")) + XCTAssertEqual(rowid, try! db.pluck(users)![id]) + } + + func test_insert() { + let id = try! db.run(users.insert(email <- "alice@example.com")) + XCTAssertEqual(1, id) + } + + func test_update() { + let changes = try! db.run(users.update(email <- "alice@example.com")) + XCTAssertEqual(0, changes) + } + + func test_delete() { + let changes = try! db.run(users.delete()) + XCTAssertEqual(0, changes) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/RTreeTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/RTreeTests.swift new file mode 100644 index 0000000..7147533 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/RTreeTests.swift @@ -0,0 +1,17 @@ +import XCTest +import SQLite + +class RTreeTests : XCTestCase { + + func test_create_onVirtualTable_withRTree_createVirtualTableExpression() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING rtree(\"int64\", \"double\", \"double\")", + virtualTable.create(.RTree(int64, (double, double))) + ) + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING rtree(\"int64\", \"double\", \"double\", \"double\", \"double\")", + virtualTable.create(.RTree(int64, (double, double), (double, double))) + ) + } + +} \ No newline at end of file diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/SchemaTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/SchemaTests.swift new file mode 100644 index 0000000..371459c --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/SchemaTests.swift @@ -0,0 +1,775 @@ +import XCTest +import SQLite + +class SchemaTests : XCTestCase { + + func test_drop_compilesDropTableExpression() { + XCTAssertEqual("DROP TABLE \"table\"", table.drop()) + XCTAssertEqual("DROP TABLE IF EXISTS \"table\"", table.drop(ifExists: true)) + } + + func test_drop_compilesDropVirtualTableExpression() { + XCTAssertEqual("DROP TABLE \"virtual_table\"", virtualTable.drop()) + XCTAssertEqual("DROP TABLE IF EXISTS \"virtual_table\"", virtualTable.drop(ifExists: true)) + } + + func test_drop_compilesDropViewExpression() { + XCTAssertEqual("DROP VIEW \"view\"", _view.drop()) + XCTAssertEqual("DROP VIEW IF EXISTS \"view\"", _view.drop(ifExists: true)) + } + + func test_create_withBuilder_compilesCreateTableExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" (" + + "\"blob\" BLOB NOT NULL, " + + "\"blobOptional\" BLOB, " + + "\"double\" REAL NOT NULL, " + + "\"doubleOptional\" REAL, " + + "\"int64\" INTEGER NOT NULL, " + + "\"int64Optional\" INTEGER, " + + "\"string\" TEXT NOT NULL, " + + "\"stringOptional\" TEXT" + + ")", + table.create { t in + t.column(data) + t.column(dataOptional) + t.column(double) + t.column(doubleOptional) + t.column(int64) + t.column(int64Optional) + t.column(string) + t.column(stringOptional) + } + ) + XCTAssertEqual( + "CREATE TEMPORARY TABLE \"table\" (\"int64\" INTEGER NOT NULL)", + table.create(temporary: true) { $0.column(int64) } + ) + XCTAssertEqual( + "CREATE TABLE IF NOT EXISTS \"table\" (\"int64\" INTEGER NOT NULL)", + table.create(ifNotExists: true) { $0.column(int64) } + ) + XCTAssertEqual( + "CREATE TEMPORARY TABLE IF NOT EXISTS \"table\" (\"int64\" INTEGER NOT NULL)", + table.create(temporary: true, ifNotExists: true) { $0.column(int64) } + ) + } + + func test_create_withQuery_compilesCreateTableExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" AS SELECT \"int64\" FROM \"view\"", + table.create(_view.select(int64)) + ) + } + + // thoroughness test for ambiguity + func test_column_compilesColumnDefinitionExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL)", + table.create { t in t.column(int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE)", + table.create { t in t.column(int64, unique: true) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL CHECK (\"int64\" > 0))", + table.create { t in t.column(int64, check: int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL CHECK (\"int64Optional\" > 0))", + table.create { t in t.column(int64, check: int64Optional > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL DEFAULT (\"int64\"))", + table.create { t in t.column(int64, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL DEFAULT (0))", + table.create { t in t.column(int64, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64\" > 0))", + table.create { t in t.column(int64, unique: true, check: int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64Optional\" > 0))", + table.create { t in t.column(int64, unique: true, check: int64Optional > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE DEFAULT (\"int64\"))", + table.create { t in t.column(int64, unique: true, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE DEFAULT (0))", + table.create { t in t.column(int64, unique: true, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64\" > 0))", + table.create { t in t.column(int64, unique: true, check: int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64Optional\" > 0))", + table.create { t in t.column(int64, unique: true, check: int64Optional > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64, unique: true, check: int64 > 0, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64Optional\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64, unique: true, check: int64Optional > 0, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64\" > 0) DEFAULT (0))", + table.create { t in t.column(int64, unique: true, check: int64 > 0, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64Optional\" > 0) DEFAULT (0))", + table.create { t in t.column(int64, unique: true, check: int64Optional > 0, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL CHECK (\"int64\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64, check: int64 > 0, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL CHECK (\"int64Optional\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64, check: int64Optional > 0, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL CHECK (\"int64\" > 0) DEFAULT (0))", + table.create { t in t.column(int64, check: int64 > 0, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL CHECK (\"int64Optional\" > 0) DEFAULT (0))", + table.create { t in t.column(int64, check: int64Optional > 0, defaultValue: 0) } + ) + + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY NOT NULL CHECK (\"int64\" > 0))", + table.create { t in t.column(int64, primaryKey: true, check: int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY NOT NULL CHECK (\"int64Optional\" > 0))", + table.create { t in t.column(int64, primaryKey: true, check: int64Optional > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY NOT NULL DEFAULT (\"int64\"))", + table.create { t in t.column(int64, primaryKey: true, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY NOT NULL CHECK (\"int64\" > 0))", + table.create { t in t.column(int64, primaryKey: true, check: int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY NOT NULL CHECK (\"int64Optional\" > 0))", + table.create { t in t.column(int64, primaryKey: true, check: int64Optional > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY NOT NULL CHECK (\"int64\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64, primaryKey: true, check: int64 > 0, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY NOT NULL CHECK (\"int64Optional\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64, primaryKey: true, check: int64Optional > 0, defaultValue: int64) } + ) + + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER)", + table.create { t in t.column(int64Optional) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE)", + table.create { t in t.column(int64Optional, unique: true) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64\" > 0))", + table.create { t in t.column(int64Optional, check: int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64Optional\" > 0))", + table.create { t in t.column(int64Optional, check: int64Optional > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER DEFAULT (\"int64\"))", + table.create { t in t.column(int64Optional, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER DEFAULT (\"int64Optional\"))", + table.create { t in t.column(int64Optional, defaultValue: int64Optional) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER DEFAULT (0))", + table.create { t in t.column(int64Optional, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64\" > 0))", + table.create { t in t.column(int64Optional, unique: true, check: int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64Optional\" > 0))", + table.create { t in t.column(int64Optional, unique: true, check: int64Optional > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE DEFAULT (\"int64\"))", + table.create { t in t.column(int64Optional, unique: true, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE DEFAULT (\"int64Optional\"))", + table.create { t in t.column(int64Optional, unique: true, defaultValue: int64Optional) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE DEFAULT (0))", + table.create { t in t.column(int64Optional, unique: true, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64\" > 0))", + table.create { t in t.column(int64Optional, unique: true, check: int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64Optional\" > 0))", + table.create { t in t.column(int64Optional, unique: true, check: int64Optional > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64Optional, unique: true, check: int64 > 0, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64\" > 0) DEFAULT (\"int64Optional\"))", + table.create { t in t.column(int64Optional, unique: true, check: int64 > 0, defaultValue: int64Optional) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64Optional\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64Optional, unique: true, check: int64Optional > 0, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64Optional\" > 0) DEFAULT (\"int64Optional\"))", + table.create { t in t.column(int64Optional, unique: true, check: int64Optional > 0, defaultValue: int64Optional) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64\" > 0) DEFAULT (0))", + table.create { t in t.column(int64Optional, unique: true, check: int64 > 0, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64Optional\" > 0) DEFAULT (0))", + table.create { t in t.column(int64Optional, unique: true, check: int64Optional > 0, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64Optional, check: int64 > 0, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64Optional\" > 0) DEFAULT (\"int64\"))", + table.create { t in t.column(int64Optional, check: int64Optional > 0, defaultValue: int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64\" > 0) DEFAULT (\"int64Optional\"))", + table.create { t in t.column(int64Optional, check: int64 > 0, defaultValue: int64Optional) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64Optional\" > 0) DEFAULT (\"int64Optional\"))", + table.create { t in t.column(int64Optional, check: int64Optional > 0, defaultValue: int64Optional) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64\" > 0) DEFAULT (0))", + table.create { t in t.column(int64Optional, check: int64 > 0, defaultValue: 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64Optional\" > 0) DEFAULT (0))", + table.create { t in t.column(int64Optional, check: int64Optional > 0, defaultValue: 0) } + ) + } + + func test_column_withIntegerExpression_compilesPrimaryKeyAutoincrementColumnDefinitionExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + table.create { t in t.column(int64, primaryKey: .autoincrement) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK (\"int64\" > 0))", + table.create { t in t.column(int64, primaryKey: .autoincrement, check: int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK (\"int64Optional\" > 0))", + table.create { t in t.column(int64, primaryKey: .autoincrement, check: int64Optional > 0) } + ) + } + + func test_column_withIntegerExpression_compilesReferentialColumnDefinitionExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64, references: qualifiedTable, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64, unique: true, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL CHECK (\"int64\" > 0) REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64, check: int64 > 0, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL CHECK (\"int64Optional\" > 0) REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64, check: int64Optional > 0, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64\" > 0) REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64, unique: true, check: int64 > 0, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64Optional\" > 0) REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64, unique: true, check: int64Optional > 0, references: table, int64) } + ) + + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64Optional, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64Optional, unique: true, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64\" > 0) REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64Optional, check: int64 > 0, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER CHECK (\"int64Optional\" > 0) REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64Optional, check: int64Optional > 0, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64\" > 0) REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64Optional, unique: true, check: int64 > 0, references: table, int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"int64Optional\" INTEGER UNIQUE CHECK (\"int64Optional\" > 0) REFERENCES \"table\" (\"int64\"))", + table.create { t in t.column(int64Optional, unique: true, check: int64Optional > 0, references: table, int64) } + ) + } + + func test_column_withStringExpression_compilesCollatedColumnDefinitionExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL COLLATE RTRIM)", + table.create { t in t.column(string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE COLLATE RTRIM)", + table.create { t in t.column(string, unique: true, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"string\" != '') COLLATE RTRIM)", + table.create { t in t.column(string, check: string != "", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"stringOptional\" != '') COLLATE RTRIM)", + table.create { t in t.column(string, check: stringOptional != "", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(string, defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(string, defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') COLLATE RTRIM)", + table.create { t in t.column(string, unique: true, check: string != "", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') COLLATE RTRIM)", + table.create { t in t.column(string, unique: true, check: stringOptional != "", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(string, unique: true, defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(string, unique: true, defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(string, unique: true, check: string != "", defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(string, unique: true, check: stringOptional != "", defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(string, unique: true, check: string != "", defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(string, unique: true, check: stringOptional != "", defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(string, check: string != "", defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(string, check: stringOptional != "", defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(string, check: string != "", defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"string\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(string, check: stringOptional != "", defaultValue: "string", collate: .rtrim) } + ) + + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL COLLATE RTRIM)", + table.create { t in t.column(stringOptional, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"string\" != '') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, check: string != "", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"stringOptional\" != '') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, check: stringOptional != "", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL DEFAULT (\"stringOptional\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, defaultValue: stringOptional, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, check: string != "", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE DEFAULT (\"stringOptional\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, defaultValue: stringOptional, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, check: string != "", defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT (\"stringOptional\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, check: string != "", defaultValue: stringOptional, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT (\"stringOptional\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", defaultValue: stringOptional, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, check: string != "", defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL UNIQUE CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, unique: true, check: stringOptional != "", defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, check: string != "", defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT (\"string\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, check: stringOptional != "", defaultValue: string, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT (\"stringOptional\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, check: string != "", defaultValue: stringOptional, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT (\"stringOptional\") COLLATE RTRIM)", + table.create { t in t.column(stringOptional, check: stringOptional != "", defaultValue: stringOptional, collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, check: string != "", defaultValue: "string", collate: .rtrim) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (\"stringOptional\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM)", + table.create { t in t.column(stringOptional, check: stringOptional != "", defaultValue: "string", collate: .rtrim) } + ) + } + + func test_primaryKey_compilesPrimaryKeyExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" (PRIMARY KEY (\"int64\"))", + table.create { t in t.primaryKey(int64) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (PRIMARY KEY (\"int64\", \"string\"))", + table.create { t in t.primaryKey(int64, string) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (PRIMARY KEY (\"int64\", \"string\", \"double\"))", + table.create { t in t.primaryKey(int64, string, double) } + ) + } + + func test_unique_compilesUniqueExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" (UNIQUE (\"int64\"))", + table.create { t in t.unique(int64) } + ) + } + + func test_check_compilesCheckExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" (CHECK ((\"int64\" > 0)))", + table.create { t in t.check(int64 > 0) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (CHECK ((\"int64Optional\" > 0)))", + table.create { t in t.check(int64Optional > 0) } + ) + } + + func test_foreignKey_compilesForeignKeyExpression() { + XCTAssertEqual( + "CREATE TABLE \"table\" (FOREIGN KEY (\"string\") REFERENCES \"table\" (\"string\"))", + table.create { t in t.foreignKey(string, references: table, string) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (FOREIGN KEY (\"stringOptional\") REFERENCES \"table\" (\"string\"))", + table.create { t in t.foreignKey(stringOptional, references: table, string) } + ) + + XCTAssertEqual( + "CREATE TABLE \"table\" (FOREIGN KEY (\"string\") REFERENCES \"table\" (\"string\") ON UPDATE CASCADE ON DELETE SET NULL)", + table.create { t in t.foreignKey(string, references: table, string, update: .cascade, delete: .setNull) } + ) + + XCTAssertEqual( + "CREATE TABLE \"table\" (FOREIGN KEY (\"string\", \"string\") REFERENCES \"table\" (\"string\", \"string\"))", + table.create { t in t.foreignKey((string, string), references: table, (string, string)) } + ) + XCTAssertEqual( + "CREATE TABLE \"table\" (FOREIGN KEY (\"string\", \"string\", \"string\") REFERENCES \"table\" (\"string\", \"string\", \"string\"))", + table.create { t in t.foreignKey((string, string, string), references: table, (string, string, string)) } + ) + } + + func test_addColumn_compilesAlterTableExpression() { + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64\" INTEGER NOT NULL DEFAULT (1)", + table.addColumn(int64, defaultValue: 1) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64\" INTEGER NOT NULL CHECK (\"int64\" > 0) DEFAULT (1)", + table.addColumn(int64, check: int64 > 0, defaultValue: 1) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64\" INTEGER NOT NULL CHECK (\"int64Optional\" > 0) DEFAULT (1)", + table.addColumn(int64, check: int64Optional > 0, defaultValue: 1) + ) + + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER", + table.addColumn(int64Optional) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER CHECK (\"int64\" > 0)", + table.addColumn(int64Optional, check: int64 > 0) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER CHECK (\"int64Optional\" > 0)", + table.addColumn(int64Optional, check: int64Optional > 0) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER DEFAULT (1)", + table.addColumn(int64Optional, defaultValue: 1) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER CHECK (\"int64\" > 0) DEFAULT (1)", + table.addColumn(int64Optional, check: int64 > 0, defaultValue: 1) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER CHECK (\"int64Optional\" > 0) DEFAULT (1)", + table.addColumn(int64Optional, check: int64Optional > 0, defaultValue: 1) + ) + } + + func test_addColumn_withIntegerExpression_compilesReferentialAlterTableExpression() { + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64\" INTEGER NOT NULL REFERENCES \"table\" (\"int64\")", + table.addColumn(int64, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64\" INTEGER NOT NULL UNIQUE REFERENCES \"table\" (\"int64\")", + table.addColumn(int64, unique: true, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64\" INTEGER NOT NULL CHECK (\"int64\" > 0) REFERENCES \"table\" (\"int64\")", + table.addColumn(int64, check: int64 > 0, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64\" INTEGER NOT NULL CHECK (\"int64Optional\" > 0) REFERENCES \"table\" (\"int64\")", + table.addColumn(int64, check: int64Optional > 0, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64\" > 0) REFERENCES \"table\" (\"int64\")", + table.addColumn(int64, unique: true, check: int64 > 0, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64\" INTEGER NOT NULL UNIQUE CHECK (\"int64Optional\" > 0) REFERENCES \"table\" (\"int64\")", + table.addColumn(int64, unique: true, check: int64Optional > 0, references: table, int64) + ) + + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER REFERENCES \"table\" (\"int64\")", + table.addColumn(int64Optional, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER UNIQUE REFERENCES \"table\" (\"int64\")", + table.addColumn(int64Optional, unique: true, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER CHECK (\"int64\" > 0) REFERENCES \"table\" (\"int64\")", + table.addColumn(int64Optional, check: int64 > 0, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER CHECK (\"int64Optional\" > 0) REFERENCES \"table\" (\"int64\")", + table.addColumn(int64Optional, check: int64Optional > 0, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER UNIQUE CHECK (\"int64\" > 0) REFERENCES \"table\" (\"int64\")", + table.addColumn(int64Optional, unique: true, check: int64 > 0, references: table, int64) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"int64Optional\" INTEGER UNIQUE CHECK (\"int64Optional\" > 0) REFERENCES \"table\" (\"int64\")", + table.addColumn(int64Optional, unique: true, check: int64Optional > 0, references: table, int64) + ) + } + + func test_addColumn_withStringExpression_compilesCollatedAlterTableExpression() { + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"string\" TEXT NOT NULL DEFAULT ('string') COLLATE RTRIM", + table.addColumn(string, defaultValue: "string", collate: .rtrim) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"string\" TEXT NOT NULL CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM", + table.addColumn(string, check: string != "", defaultValue: "string", collate: .rtrim) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"string\" TEXT NOT NULL CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM", + table.addColumn(string, check: stringOptional != "", defaultValue: "string", collate: .rtrim) + ) + + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT COLLATE RTRIM", + table.addColumn(stringOptional, collate: .rtrim) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT CHECK (\"string\" != '') COLLATE RTRIM", + table.addColumn(stringOptional, check: string != "", collate: .rtrim) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT CHECK (\"stringOptional\" != '') COLLATE RTRIM", + table.addColumn(stringOptional, check: stringOptional != "", collate: .rtrim) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT CHECK (\"string\" != '') DEFAULT ('string') COLLATE RTRIM", + table.addColumn(stringOptional, check: string != "", defaultValue: "string", collate: .rtrim) + ) + XCTAssertEqual( + "ALTER TABLE \"table\" ADD COLUMN \"stringOptional\" TEXT CHECK (\"stringOptional\" != '') DEFAULT ('string') COLLATE RTRIM", + table.addColumn(stringOptional, check: stringOptional != "", defaultValue: "string", collate: .rtrim) + ) + } + + func test_rename_compilesAlterTableRenameToExpression() { + XCTAssertEqual("ALTER TABLE \"old\" RENAME TO \"table\"", Table("old").rename(table)) + } + + func test_createIndex_compilesCreateIndexExpression() { + XCTAssertEqual("CREATE INDEX \"index_table_on_int64\" ON \"table\" (\"int64\")", table.createIndex(int64)) + + XCTAssertEqual( + "CREATE UNIQUE INDEX \"index_table_on_int64\" ON \"table\" (\"int64\")", + table.createIndex([int64], unique: true) + ) + XCTAssertEqual( + "CREATE INDEX IF NOT EXISTS \"index_table_on_int64\" ON \"table\" (\"int64\")", + table.createIndex([int64], ifNotExists: true) + ) + XCTAssertEqual( + "CREATE UNIQUE INDEX IF NOT EXISTS \"index_table_on_int64\" ON \"table\" (\"int64\")", + table.createIndex([int64], unique: true, ifNotExists: true) + ) + XCTAssertEqual( + "CREATE UNIQUE INDEX IF NOT EXISTS \"main\".\"index_table_on_int64\" ON \"table\" (\"int64\")", + qualifiedTable.createIndex([int64], unique: true, ifNotExists: true) + ) + } + + func test_dropIndex_compilesCreateIndexExpression() { + XCTAssertEqual("DROP INDEX \"index_table_on_int64\"", table.dropIndex(int64)) + XCTAssertEqual("DROP INDEX IF EXISTS \"index_table_on_int64\"", table.dropIndex([int64], ifExists: true)) + } + + func test_create_onView_compilesCreateViewExpression() { + XCTAssertEqual( + "CREATE VIEW \"view\" AS SELECT \"int64\" FROM \"table\"", + _view.create(table.select(int64)) + ) + XCTAssertEqual( + "CREATE TEMPORARY VIEW \"view\" AS SELECT \"int64\" FROM \"table\"", + _view.create(table.select(int64), temporary: true) + ) + XCTAssertEqual( + "CREATE VIEW IF NOT EXISTS \"view\" AS SELECT \"int64\" FROM \"table\"", + _view.create(table.select(int64), ifNotExists: true) + ) + XCTAssertEqual( + "CREATE TEMPORARY VIEW IF NOT EXISTS \"view\" AS SELECT \"int64\" FROM \"table\"", + _view.create(table.select(int64), temporary: true, ifNotExists: true) + ) + } + + func test_create_onVirtualTable_compilesCreateVirtualTableExpression() { + XCTAssertEqual( + "CREATE VIRTUAL TABLE \"virtual_table\" USING \"custom\"('foo', 'bar')", + virtualTable.create(Module("custom", ["foo", "bar"])) + ) + } + + func test_rename_onVirtualTable_compilesAlterTableRenameToExpression() { + XCTAssertEqual( + "ALTER TABLE \"old\" RENAME TO \"virtual_table\"", + VirtualTable("old").rename(virtualTable) + ) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/SetterTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/SetterTests.swift new file mode 100644 index 0000000..d4f189d --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/SetterTests.swift @@ -0,0 +1,137 @@ +import XCTest +import SQLite + +class SetterTests : XCTestCase { + + func test_setterAssignmentOperator_buildsSetter() { + AssertSQL("\"int\" = \"int\"", int <- int) + AssertSQL("\"int\" = 1", int <- 1) + AssertSQL("\"intOptional\" = \"int\"", intOptional <- int) + AssertSQL("\"intOptional\" = \"intOptional\"", intOptional <- intOptional) + AssertSQL("\"intOptional\" = 1", intOptional <- 1) + AssertSQL("\"intOptional\" = NULL", intOptional <- nil) + } + + func test_plusEquals_withStringExpression_buildsSetter() { + AssertSQL("\"string\" = (\"string\" || \"string\")", string += string) + AssertSQL("\"string\" = (\"string\" || 'literal')", string += "literal") + AssertSQL("\"stringOptional\" = (\"stringOptional\" || \"string\")", stringOptional += string) + AssertSQL("\"stringOptional\" = (\"stringOptional\" || \"stringOptional\")", stringOptional += stringOptional) + AssertSQL("\"stringOptional\" = (\"stringOptional\" || 'literal')", stringOptional += "literal") + } + + func test_plusEquals_withNumberExpression_buildsSetter() { + AssertSQL("\"int\" = (\"int\" + \"int\")", int += int) + AssertSQL("\"int\" = (\"int\" + 1)", int += 1) + AssertSQL("\"intOptional\" = (\"intOptional\" + \"int\")", intOptional += int) + AssertSQL("\"intOptional\" = (\"intOptional\" + \"intOptional\")", intOptional += intOptional) + AssertSQL("\"intOptional\" = (\"intOptional\" + 1)", intOptional += 1) + + AssertSQL("\"double\" = (\"double\" + \"double\")", double += double) + AssertSQL("\"double\" = (\"double\" + 1.0)", double += 1) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" + \"double\")", doubleOptional += double) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" + \"doubleOptional\")", doubleOptional += doubleOptional) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" + 1.0)", doubleOptional += 1) + } + + func test_minusEquals_withNumberExpression_buildsSetter() { + AssertSQL("\"int\" = (\"int\" - \"int\")", int -= int) + AssertSQL("\"int\" = (\"int\" - 1)", int -= 1) + AssertSQL("\"intOptional\" = (\"intOptional\" - \"int\")", intOptional -= int) + AssertSQL("\"intOptional\" = (\"intOptional\" - \"intOptional\")", intOptional -= intOptional) + AssertSQL("\"intOptional\" = (\"intOptional\" - 1)", intOptional -= 1) + + AssertSQL("\"double\" = (\"double\" - \"double\")", double -= double) + AssertSQL("\"double\" = (\"double\" - 1.0)", double -= 1) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" - \"double\")", doubleOptional -= double) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" - \"doubleOptional\")", doubleOptional -= doubleOptional) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" - 1.0)", doubleOptional -= 1) + } + + func test_timesEquals_withNumberExpression_buildsSetter() { + AssertSQL("\"int\" = (\"int\" * \"int\")", int *= int) + AssertSQL("\"int\" = (\"int\" * 1)", int *= 1) + AssertSQL("\"intOptional\" = (\"intOptional\" * \"int\")", intOptional *= int) + AssertSQL("\"intOptional\" = (\"intOptional\" * \"intOptional\")", intOptional *= intOptional) + AssertSQL("\"intOptional\" = (\"intOptional\" * 1)", intOptional *= 1) + + AssertSQL("\"double\" = (\"double\" * \"double\")", double *= double) + AssertSQL("\"double\" = (\"double\" * 1.0)", double *= 1) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" * \"double\")", doubleOptional *= double) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" * \"doubleOptional\")", doubleOptional *= doubleOptional) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" * 1.0)", doubleOptional *= 1) + } + + func test_dividedByEquals_withNumberExpression_buildsSetter() { + AssertSQL("\"int\" = (\"int\" / \"int\")", int /= int) + AssertSQL("\"int\" = (\"int\" / 1)", int /= 1) + AssertSQL("\"intOptional\" = (\"intOptional\" / \"int\")", intOptional /= int) + AssertSQL("\"intOptional\" = (\"intOptional\" / \"intOptional\")", intOptional /= intOptional) + AssertSQL("\"intOptional\" = (\"intOptional\" / 1)", intOptional /= 1) + + AssertSQL("\"double\" = (\"double\" / \"double\")", double /= double) + AssertSQL("\"double\" = (\"double\" / 1.0)", double /= 1) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" / \"double\")", doubleOptional /= double) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" / \"doubleOptional\")", doubleOptional /= doubleOptional) + AssertSQL("\"doubleOptional\" = (\"doubleOptional\" / 1.0)", doubleOptional /= 1) + } + + func test_moduloEquals_withIntegerExpression_buildsSetter() { + AssertSQL("\"int\" = (\"int\" % \"int\")", int %= int) + AssertSQL("\"int\" = (\"int\" % 1)", int %= 1) + AssertSQL("\"intOptional\" = (\"intOptional\" % \"int\")", intOptional %= int) + AssertSQL("\"intOptional\" = (\"intOptional\" % \"intOptional\")", intOptional %= intOptional) + AssertSQL("\"intOptional\" = (\"intOptional\" % 1)", intOptional %= 1) + } + + func test_leftShiftEquals_withIntegerExpression_buildsSetter() { + AssertSQL("\"int\" = (\"int\" << \"int\")", int <<= int) + AssertSQL("\"int\" = (\"int\" << 1)", int <<= 1) + AssertSQL("\"intOptional\" = (\"intOptional\" << \"int\")", intOptional <<= int) + AssertSQL("\"intOptional\" = (\"intOptional\" << \"intOptional\")", intOptional <<= intOptional) + AssertSQL("\"intOptional\" = (\"intOptional\" << 1)", intOptional <<= 1) + } + + func test_rightShiftEquals_withIntegerExpression_buildsSetter() { + AssertSQL("\"int\" = (\"int\" >> \"int\")", int >>= int) + AssertSQL("\"int\" = (\"int\" >> 1)", int >>= 1) + AssertSQL("\"intOptional\" = (\"intOptional\" >> \"int\")", intOptional >>= int) + AssertSQL("\"intOptional\" = (\"intOptional\" >> \"intOptional\")", intOptional >>= intOptional) + AssertSQL("\"intOptional\" = (\"intOptional\" >> 1)", intOptional >>= 1) + } + + func test_bitwiseAndEquals_withIntegerExpression_buildsSetter() { + AssertSQL("\"int\" = (\"int\" & \"int\")", int &= int) + AssertSQL("\"int\" = (\"int\" & 1)", int &= 1) + AssertSQL("\"intOptional\" = (\"intOptional\" & \"int\")", intOptional &= int) + AssertSQL("\"intOptional\" = (\"intOptional\" & \"intOptional\")", intOptional &= intOptional) + AssertSQL("\"intOptional\" = (\"intOptional\" & 1)", intOptional &= 1) + } + + func test_bitwiseOrEquals_withIntegerExpression_buildsSetter() { + AssertSQL("\"int\" = (\"int\" | \"int\")", int |= int) + AssertSQL("\"int\" = (\"int\" | 1)", int |= 1) + AssertSQL("\"intOptional\" = (\"intOptional\" | \"int\")", intOptional |= int) + AssertSQL("\"intOptional\" = (\"intOptional\" | \"intOptional\")", intOptional |= intOptional) + AssertSQL("\"intOptional\" = (\"intOptional\" | 1)", intOptional |= 1) + } + + func test_bitwiseExclusiveOrEquals_withIntegerExpression_buildsSetter() { + AssertSQL("\"int\" = (~((\"int\" & \"int\")) & (\"int\" | \"int\"))", int ^= int) + AssertSQL("\"int\" = (~((\"int\" & 1)) & (\"int\" | 1))", int ^= 1) + AssertSQL("\"intOptional\" = (~((\"intOptional\" & \"int\")) & (\"intOptional\" | \"int\"))", intOptional ^= int) + AssertSQL("\"intOptional\" = (~((\"intOptional\" & \"intOptional\")) & (\"intOptional\" | \"intOptional\"))", intOptional ^= intOptional) + AssertSQL("\"intOptional\" = (~((\"intOptional\" & 1)) & (\"intOptional\" | 1))", intOptional ^= 1) + } + + func test_postfixPlus_withIntegerValue_buildsSetter() { + AssertSQL("\"int\" = (\"int\" + 1)", int++) + AssertSQL("\"intOptional\" = (\"intOptional\" + 1)", intOptional++) + } + + func test_postfixMinus_withIntegerValue_buildsSetter() { + AssertSQL("\"int\" = (\"int\" - 1)", int--) + AssertSQL("\"intOptional\" = (\"intOptional\" - 1)", intOptional--) + } + +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/StatementTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/StatementTests.swift new file mode 100644 index 0000000..326259b --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/StatementTests.swift @@ -0,0 +1,26 @@ +import XCTest +import SQLite + +class StatementTests : SQLiteTestCase { + override func setUp() { + super.setUp() + CreateUsersTable() + } + + func test_cursor_to_blob() { + try! InsertUsers("alice") + let statement = try! db.prepare("SELECT email FROM users") + XCTAssert(try! statement.step()) + let blob = statement.row[0] as Blob + XCTAssertEqual("alice@example.com", String(bytes: blob.bytes, encoding: .utf8)!) + } + + func test_zero_sized_blob_returns_null() { + let blobs = Table("blobs") + let blobColumn = Expression("blob_column") + try! db.run(blobs.create { $0.column(blobColumn) }) + try! db.run(blobs.insert(blobColumn <- Blob(bytes: []))) + let blobValue = try! db.scalar(blobs.select(blobColumn).limit(1, offset: 0)) + XCTAssertEqual([], blobValue.bytes) + } +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/TestHelpers.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/TestHelpers.swift new file mode 100644 index 0000000..8c33bf6 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/TestHelpers.swift @@ -0,0 +1,115 @@ +import XCTest +import SQLite + +class SQLiteTestCase : XCTestCase { + + var trace = [String: Int]() + + let db = try! Connection() + + let users = Table("users") + + override func setUp() { + super.setUp() + + db.trace { SQL in + print(SQL) + self.trace[SQL] = (self.trace[SQL] ?? 0) + 1 + } + } + + func CreateUsersTable() { + try! db.execute( + "CREATE TABLE \"users\" (" + + "id INTEGER PRIMARY KEY, " + + "email TEXT NOT NULL UNIQUE, " + + "age INTEGER, " + + "salary REAL, " + + "admin BOOLEAN NOT NULL DEFAULT 0 CHECK (admin IN (0, 1)), " + + "manager_id INTEGER, " + + "FOREIGN KEY(manager_id) REFERENCES users(id)" + + ")" + ) + } + + func InsertUsers(_ names: String...) throws { + try InsertUsers(names) + } + + func InsertUsers(_ names: [String]) throws { + for name in names { try InsertUser(name) } + } + + @discardableResult func InsertUser(_ name: String, age: Int? = nil, admin: Bool = false) throws -> Statement { + return try db.run( + "INSERT INTO \"users\" (email, age, admin) values (?, ?, ?)", + "\(name)@example.com", age?.datatypeValue, admin.datatypeValue + ) + } + + func AssertSQL(_ SQL: String, _ executions: Int = 1, _ message: String? = nil, file: StaticString = #file, line: UInt = #line) { + XCTAssertEqual( + executions, trace[SQL] ?? 0, + message ?? SQL, + file: file, line: line + ) + } + + func AssertSQL(_ SQL: String, _ statement: Statement, _ message: String? = nil, file: StaticString = #file, line: UInt = #line) { + try! statement.run() + AssertSQL(SQL, 1, message, file: file, line: line) + if let count = trace[SQL] { trace[SQL] = count - 1 } + } + +// func AssertSQL(SQL: String, _ query: Query, _ message: String? = nil, file: String = __FILE__, line: UInt = __LINE__) { +// for _ in query {} +// AssertSQL(SQL, 1, message, file: file, line: line) +// if let count = trace[SQL] { trace[SQL] = count - 1 } +// } + + func async(expect description: String = "async", timeout: Double = 5, block: (@escaping () -> Void) -> Void) { + let expectation = self.expectation(description: description) + block(expectation.fulfill) + waitForExpectations(timeout: timeout, handler: nil) + } + +} + +let bool = Expression("bool") +let boolOptional = Expression("boolOptional") + +let data = Expression("blob") +let dataOptional = Expression("blobOptional") + +let date = Expression("date") +let dateOptional = Expression("dateOptional") + +let double = Expression("double") +let doubleOptional = Expression("doubleOptional") + +let int = Expression("int") +let intOptional = Expression("intOptional") + +let int64 = Expression("int64") +let int64Optional = Expression("int64Optional") + +let string = Expression("string") +let stringOptional = Expression("stringOptional") + +func AssertSQL(_ expression1: @autoclosure () -> String, _ expression2: @autoclosure () -> Expressible, file: StaticString = #file, line: UInt = #line) { + XCTAssertEqual(expression1(), expression2().asSQL(), file: file, line: line) +} + +func AssertThrows(_ expression: @autoclosure () throws -> T, file: StaticString = #file, line: UInt = #line) { + do { + _ = try expression() + XCTFail("expression expected to throw", file: file, line: line) + } catch { + XCTAssert(true, file: file, line: line) + } +} + +let table = Table("table") +let qualifiedTable = Table("table", database: "main") +let virtualTable = VirtualTable("virtual_table") +let _view = View("view") // avoid Mac XCTestCase collision diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/ValueTests.swift b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/ValueTests.swift new file mode 100644 index 0000000..bda2b4b --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/ValueTests.swift @@ -0,0 +1,6 @@ +import XCTest +import SQLite + +class ValueTests : XCTestCase { + +} diff --git a/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/fixtures/encrypted.sqlite b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/fixtures/encrypted.sqlite new file mode 100644 index 0000000..4b3c4d0 Binary files /dev/null and b/Carthage/Checkouts/SQLite.swift/Tests/SQLiteTests/fixtures/encrypted.sqlite differ diff --git a/Carthage/Checkouts/SQLite.swift/run-tests.sh b/Carthage/Checkouts/SQLite.swift/run-tests.sh new file mode 100755 index 0000000..ddd7d67 --- /dev/null +++ b/Carthage/Checkouts/SQLite.swift/run-tests.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -ev +if [ -n "$BUILD_SCHEME" ]; then + if [ -n "$IOS_SIMULATOR" ]; then + make test BUILD_SCHEME="$BUILD_SCHEME" IOS_SIMULATOR="$IOS_SIMULATOR" + else + make test BUILD_SCHEME="$BUILD_SCHEME" + fi +elif [ -n "$VALIDATOR_SUBSPEC" ]; then + cd Tests/CocoaPods && make test +elif [ -n "$CARTHAGE_PLATFORM" ]; then + cd Tests/Carthage && make test CARTHAGE_PLATFORM="$CARTHAGE_PLATFORM" +elif [ -n "${PACKAGE_MANAGER_COMMAND}" ]; then + swift ${PACKAGE_MANAGER_COMMAND} +fi diff --git a/Carthage/Checkouts/SwViewCapture/.gitignore b/Carthage/Checkouts/SwViewCapture/.gitignore new file mode 100644 index 0000000..5e5d5ce --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/.gitignore @@ -0,0 +1,63 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md + +fastlane/report.xml +fastlane/screenshots diff --git a/Carthage/Checkouts/SwViewCapture/CHANGELOG.md b/Carthage/Checkouts/SwViewCapture/CHANGELOG.md new file mode 100755 index 0000000..c3d40a2 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/CHANGELOG.md @@ -0,0 +1,25 @@ +1.0.0 + +* init project +* support capture UIScrollView & UIWebView & WKWebView content + +1.0.1 + +* fixed device scale problem + +1.0.2 + +* WKWebView Screenshots perfect support +* WKWebView support two difference method to capture (scroll & not scroll) + +1.0.3 + +* optimize WKWebView Screenshots, fixed NavigationBar offset problem + +1.0.4 + +* Fix Crash Bug with nil return + +1.0.5 + +* Compatible to Swift 3.0 which contributed by [Lafree317](https://github.com/Lafree317). \ No newline at end of file diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example.xcodeproj/project.pbxproj b/Carthage/Checkouts/SwViewCapture/Example/Example.xcodeproj/project.pbxproj new file mode 100755 index 0000000..c5239d7 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example.xcodeproj/project.pbxproj @@ -0,0 +1,400 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 394BA34D1C71B6BF0012FCB5 /* SwViewCapture.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39D667C51BE2053600BF0BD7 /* SwViewCapture.framework */; }; + 394BA34F1C71B7300012FCB5 /* SwViewCapture.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 39D667C51BE2053600BF0BD7 /* SwViewCapture.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 394BA3541C71D1120012FCB5 /* STUIWebViewDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 394BA3531C71D1120012FCB5 /* STUIWebViewDemoController.swift */; }; + 394BA3611C7461880012FCB5 /* ImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 394BA3601C7461880012FCB5 /* ImageViewController.swift */; }; + 39D667A11BE202AC00BF0BD7 /* STDemoAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39D667A01BE202AC00BF0BD7 /* STDemoAppDelegate.swift */; }; + 39D667A81BE202AC00BF0BD7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 39D667A71BE202AC00BF0BD7 /* Assets.xcassets */; }; + 39D667AB1BE202AC00BF0BD7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 39D667A91BE202AC00BF0BD7 /* LaunchScreen.storyboard */; }; + 39D667B91BE202FE00BF0BD7 /* STMenuDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39D667B41BE202FE00BF0BD7 /* STMenuDemoViewController.swift */; }; + 39D667BA1BE202FE00BF0BD7 /* STScrollViewDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39D667B51BE202FE00BF0BD7 /* STScrollViewDemoController.swift */; }; + 39D667BB1BE202FE00BF0BD7 /* STTableViewDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39D667B61BE202FE00BF0BD7 /* STTableViewDemoController.swift */; }; + 39D667BC1BE202FE00BF0BD7 /* STViewDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39D667B71BE202FE00BF0BD7 /* STViewDemoController.swift */; }; + 39D667BD1BE202FE00BF0BD7 /* STWKWebViewDemoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39D667B81BE202FE00BF0BD7 /* STWKWebViewDemoController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 394BA34A1C71B6A30012FCB5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 39D667C01BE2053600BF0BD7 /* SwViewCapture.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 39D667881BE2024900BF0BD7; + remoteInfo = SwViewCapture; + }; + 394BA3501C71B7300012FCB5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 39D667C01BE2053600BF0BD7 /* SwViewCapture.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 39D667881BE2024900BF0BD7; + remoteInfo = SwViewCapture; + }; + 39D667C41BE2053600BF0BD7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 39D667C01BE2053600BF0BD7 /* SwViewCapture.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 39D667891BE2024900BF0BD7; + remoteInfo = SwViewCapture; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 394BA3521C71B7300012FCB5 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 394BA34F1C71B7300012FCB5 /* SwViewCapture.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 394BA3531C71D1120012FCB5 /* STUIWebViewDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = STUIWebViewDemoController.swift; sourceTree = ""; }; + 394BA3601C7461880012FCB5 /* ImageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageViewController.swift; sourceTree = ""; }; + 39D6679D1BE202AC00BF0BD7 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 39D667A01BE202AC00BF0BD7 /* STDemoAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = STDemoAppDelegate.swift; sourceTree = ""; }; + 39D667A71BE202AC00BF0BD7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 39D667AA1BE202AC00BF0BD7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 39D667AC1BE202AC00BF0BD7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 39D667B41BE202FE00BF0BD7 /* STMenuDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = STMenuDemoViewController.swift; sourceTree = ""; }; + 39D667B51BE202FE00BF0BD7 /* STScrollViewDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = STScrollViewDemoController.swift; sourceTree = ""; }; + 39D667B61BE202FE00BF0BD7 /* STTableViewDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = STTableViewDemoController.swift; sourceTree = ""; }; + 39D667B71BE202FE00BF0BD7 /* STViewDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = STViewDemoController.swift; sourceTree = ""; }; + 39D667B81BE202FE00BF0BD7 /* STWKWebViewDemoController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = STWKWebViewDemoController.swift; sourceTree = ""; }; + 39D667C01BE2053600BF0BD7 /* SwViewCapture.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SwViewCapture.xcodeproj; path = ../SwViewCapture.xcodeproj; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 39D6679A1BE202AC00BF0BD7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 394BA34D1C71B6BF0012FCB5 /* SwViewCapture.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 39D667941BE202AC00BF0BD7 = { + isa = PBXGroup; + children = ( + 39D667C01BE2053600BF0BD7 /* SwViewCapture.xcodeproj */, + 39D6679F1BE202AC00BF0BD7 /* Example */, + 39D6679E1BE202AC00BF0BD7 /* Products */, + ); + sourceTree = ""; + }; + 39D6679E1BE202AC00BF0BD7 /* Products */ = { + isa = PBXGroup; + children = ( + 39D6679D1BE202AC00BF0BD7 /* Example.app */, + ); + name = Products; + sourceTree = ""; + }; + 39D6679F1BE202AC00BF0BD7 /* Example */ = { + isa = PBXGroup; + children = ( + 39D667A01BE202AC00BF0BD7 /* STDemoAppDelegate.swift */, + 39D667B41BE202FE00BF0BD7 /* STMenuDemoViewController.swift */, + 39D667B51BE202FE00BF0BD7 /* STScrollViewDemoController.swift */, + 39D667B61BE202FE00BF0BD7 /* STTableViewDemoController.swift */, + 39D667B71BE202FE00BF0BD7 /* STViewDemoController.swift */, + 39D667B81BE202FE00BF0BD7 /* STWKWebViewDemoController.swift */, + 394BA3531C71D1120012FCB5 /* STUIWebViewDemoController.swift */, + 394BA3601C7461880012FCB5 /* ImageViewController.swift */, + 39D667A71BE202AC00BF0BD7 /* Assets.xcassets */, + 39D667A91BE202AC00BF0BD7 /* LaunchScreen.storyboard */, + 39D667AC1BE202AC00BF0BD7 /* Info.plist */, + ); + path = Example; + sourceTree = ""; + }; + 39D667C11BE2053600BF0BD7 /* Products */ = { + isa = PBXGroup; + children = ( + 39D667C51BE2053600BF0BD7 /* SwViewCapture.framework */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 39D6679C1BE202AC00BF0BD7 /* Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 39D667AF1BE202AC00BF0BD7 /* Build configuration list for PBXNativeTarget "Example" */; + buildPhases = ( + 39D667991BE202AC00BF0BD7 /* Sources */, + 39D6679A1BE202AC00BF0BD7 /* Frameworks */, + 39D6679B1BE202AC00BF0BD7 /* Resources */, + 394BA3521C71B7300012FCB5 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 394BA34B1C71B6A30012FCB5 /* PBXTargetDependency */, + 394BA3511C71B7300012FCB5 /* PBXTargetDependency */, + ); + name = Example; + productName = Example; + productReference = 39D6679D1BE202AC00BF0BD7 /* Example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 39D667951BE202AC00BF0BD7 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0710; + LastUpgradeCheck = 0710; + ORGANIZATIONNAME = Startry; + TargetAttributes = { + 39D6679C1BE202AC00BF0BD7 = { + CreatedOnToolsVersion = 7.1; + LastSwiftMigration = 0800; + }; + }; + }; + buildConfigurationList = 39D667981BE202AC00BF0BD7 /* Build configuration list for PBXProject "Example" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 39D667941BE202AC00BF0BD7; + productRefGroup = 39D6679E1BE202AC00BF0BD7 /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 39D667C11BE2053600BF0BD7 /* Products */; + ProjectRef = 39D667C01BE2053600BF0BD7 /* SwViewCapture.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 39D6679C1BE202AC00BF0BD7 /* Example */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 39D667C51BE2053600BF0BD7 /* SwViewCapture.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = SwViewCapture.framework; + remoteRef = 39D667C41BE2053600BF0BD7 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 39D6679B1BE202AC00BF0BD7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 39D667AB1BE202AC00BF0BD7 /* LaunchScreen.storyboard in Resources */, + 39D667A81BE202AC00BF0BD7 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 39D667991BE202AC00BF0BD7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 39D667BC1BE202FE00BF0BD7 /* STViewDemoController.swift in Sources */, + 39D667BD1BE202FE00BF0BD7 /* STWKWebViewDemoController.swift in Sources */, + 394BA3541C71D1120012FCB5 /* STUIWebViewDemoController.swift in Sources */, + 39D667A11BE202AC00BF0BD7 /* STDemoAppDelegate.swift in Sources */, + 39D667BA1BE202FE00BF0BD7 /* STScrollViewDemoController.swift in Sources */, + 39D667B91BE202FE00BF0BD7 /* STMenuDemoViewController.swift in Sources */, + 394BA3611C7461880012FCB5 /* ImageViewController.swift in Sources */, + 39D667BB1BE202FE00BF0BD7 /* STTableViewDemoController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 394BA34B1C71B6A30012FCB5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwViewCapture; + targetProxy = 394BA34A1C71B6A30012FCB5 /* PBXContainerItemProxy */; + }; + 394BA3511C71B7300012FCB5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SwViewCapture; + targetProxy = 394BA3501C71B7300012FCB5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 39D667A91BE202AC00BF0BD7 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 39D667AA1BE202AC00BF0BD7 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 39D667AD1BE202AC00BF0BD7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 39D667AE1BE202AC00BF0BD7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 39D667B01BE202AC00BF0BD7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; + INFOPLIST_FILE = Example/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.startry.SwViewCapture.Example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 39D667B11BE202AC00BF0BD7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; + INFOPLIST_FILE = Example/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.startry.SwViewCapture.Example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 39D667981BE202AC00BF0BD7 /* Build configuration list for PBXProject "Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 39D667AD1BE202AC00BF0BD7 /* Debug */, + 39D667AE1BE202AC00BF0BD7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 39D667AF1BE202AC00BF0BD7 /* Build configuration list for PBXNativeTarget "Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 39D667B01BE202AC00BF0BD7 /* Debug */, + 39D667B11BE202AC00BF0BD7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 39D667951BE202AC00BF0BD7 /* Project object */; +} diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100755 index 0000000..eeea76c --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,73 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/Contents.json b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/Contents.json new file mode 100755 index 0000000..da4a164 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_1.imageset/Contents.json b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_1.imageset/Contents.json new file mode 100755 index 0000000..33b1b25 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "demo_1@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_1.imageset/demo_1@2x.png b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_1.imageset/demo_1@2x.png new file mode 100755 index 0000000..254bd5a Binary files /dev/null and b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_1.imageset/demo_1@2x.png differ diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_2.imageset/Contents.json b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_2.imageset/Contents.json new file mode 100755 index 0000000..d7d16d0 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "demo_2@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_2.imageset/demo_2@2x.png b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_2.imageset/demo_2@2x.png new file mode 100755 index 0000000..a00992e Binary files /dev/null and b/Carthage/Checkouts/SwViewCapture/Example/Example/Assets.xcassets/demo_2.imageset/demo_2@2x.png differ diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/Base.lproj/LaunchScreen.storyboard b/Carthage/Checkouts/SwViewCapture/Example/Example/Base.lproj/LaunchScreen.storyboard new file mode 100755 index 0000000..8326657 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/ImageViewController.swift b/Carthage/Checkouts/SwViewCapture/Example/Example/ImageViewController.swift new file mode 100755 index 0000000..24deff3 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/ImageViewController.swift @@ -0,0 +1,58 @@ +// +// ImageViewController.swift +// Example +// +// Created by chenxing.cx on 16/2/17. +// Copyright © 2016年 Startry. All rights reserved. +// + +import UIKit + +class ImageViewController: UIViewController { + + var scrollView: UIScrollView? + var imageView: UIImageView? + var image: UIImage? + + init(image: UIImage){ + self.image = image + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override func viewDidLoad() { + super.viewDidLoad() + + self.imageView = UIImageView() + self.imageView?.image = image + self.imageView?.contentMode = UIViewContentMode.scaleAspectFit + + + self.scrollView = UIScrollView() + + self.scrollView?.addSubview(self.imageView!) + self.view.addSubview(self.scrollView!) + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + if image?.size.height == UIScreen.main.bounds.height { + self.scrollView?.setContentOffset(CGPoint(x: 0, y: (self.scrollView?.contentSize.height)! - (self.scrollView?.frame.size.height)!), animated: true) + } + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + let height = (self.image?.size.height)! + let width = (self.image?.size.width)! + + self.scrollView?.frame = self.view.bounds + self.scrollView?.contentSize = CGSize(width: width, height: height) + + self.imageView?.frame = CGRect(x: 0, y: 0, width: width, height: height) + } +} diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/Info.plist b/Carthage/Checkouts/SwViewCapture/Example/Example/Info.plist new file mode 100755 index 0000000..a1bc787 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/Info.plist @@ -0,0 +1,52 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPhotoLibraryUsageDescription + 是否允许此App访问你的媒体资料库? + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/STDemoAppDelegate.swift b/Carthage/Checkouts/SwViewCapture/Example/Example/STDemoAppDelegate.swift new file mode 100755 index 0000000..f34c275 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/STDemoAppDelegate.swift @@ -0,0 +1,55 @@ +// +// STDemoAppDelegate.swift +// Example +// +// Created by chenxing.cx on 15/10/29. +// Copyright © 2015年 Startry. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class STDemoAppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + + self.window = UIWindow(frame: UIScreen.main.bounds) + + let vc = STMenuDemoViewController() + let navVc = UINavigationController(rootViewController: vc) + + self.window?.rootViewController = navVc + self.window?.makeKeyAndVisible() + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/STMenuDemoViewController.swift b/Carthage/Checkouts/SwViewCapture/Example/Example/STMenuDemoViewController.swift new file mode 100755 index 0000000..79e7bcd --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/STMenuDemoViewController.swift @@ -0,0 +1,112 @@ +// +// STMenuDemoViewController.swift +// STViewCapture +// +// Created by chenxing.cx on 15/10/28. +// Copyright © 2015年 startry.com All rights reserved. +// + +import UIKit + +class STMenuDemoViewController: UIViewController { + + fileprivate var viewBtn: UIButton? + fileprivate var scrollViewBtn: UIButton? + fileprivate var tableViewBtn: UIButton? + fileprivate var webViewBtn: UIButton? + fileprivate var oldWebViewBtn: UIButton? + +// MARK: Life Cycle + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + initViews(); + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + +// MARK: Private Methods + + fileprivate func initViews(){ + view.backgroundColor = UIColor.white + + let viewBtn = UIButton() + let scrollViewBtn = UIButton() + let tableViewBtn = UIButton() + let webViewBtn = UIButton() + let oldWebViewBtn = UIButton() + + viewBtn.setTitleColor(UIColor.black, for: UIControlState()) + scrollViewBtn.setTitleColor(UIColor.black, for: UIControlState()) + tableViewBtn.setTitleColor(UIColor.black, for: UIControlState()) + webViewBtn.setTitleColor(UIColor.black, for: UIControlState()) + oldWebViewBtn.setTitleColor(UIColor.black, for: UIControlState()) + + viewBtn.setTitle("View示例", for: UIControlState()) + scrollViewBtn.setTitle("ScrollView示例", for: UIControlState()) + tableViewBtn.setTitle("TableView示例", for: UIControlState()) + webViewBtn.setTitle("WKWebView示例", for: UIControlState()) + oldWebViewBtn.setTitle("UIWebView示例", for: UIControlState()) + + view.addSubview(viewBtn) + view.addSubview(scrollViewBtn) + view.addSubview(tableViewBtn) + view.addSubview(webViewBtn) + view.addSubview(oldWebViewBtn) + + let actionSel = #selector(STMenuDemoViewController.didBtnClicked(_:)) + + viewBtn.addTarget(self, action: actionSel, for: UIControlEvents.touchUpInside) + scrollViewBtn.addTarget(self, action: actionSel, for: UIControlEvents.touchUpInside) + tableViewBtn.addTarget(self, action: actionSel, for: UIControlEvents.touchUpInside) + webViewBtn.addTarget(self, action: actionSel, for: UIControlEvents.touchUpInside) + oldWebViewBtn.addTarget(self, action: actionSel, for: UIControlEvents.touchUpInside) + + self.viewBtn = viewBtn + self.scrollViewBtn = scrollViewBtn + self.tableViewBtn = tableViewBtn + self.webViewBtn = webViewBtn + self.oldWebViewBtn = oldWebViewBtn + } + +// MARK: Layout Views + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + let btnHeight:CGFloat = 30, btnWidth:CGFloat = 180.0, spanHeight:CGFloat = 20.0; + let btnX = view.frame.size.width / 2 - btnWidth / 2; + let midY = view.frame.size.height / 2; + viewBtn?.frame = CGRect(x: btnX, y: midY - 2 * spanHeight - btnHeight * 2.5, width: btnWidth, height: btnHeight) + scrollViewBtn?.frame = CGRect(x: btnX, y: midY - spanHeight - btnHeight * 1.5, width: btnWidth, height: btnHeight) + tableViewBtn?.frame = CGRect(x: btnX, y: midY - btnHeight * 0.5, width: btnWidth, height: btnHeight) + webViewBtn?.frame = CGRect(x: btnX, y: midY + spanHeight + btnHeight * 0.5, width: btnWidth, height: btnHeight) + oldWebViewBtn?.frame = CGRect(x: btnX, y: midY + spanHeight * 2 + btnHeight * 1.5, width: btnWidth, height: btnHeight) + } + +// MARK: Events + + func didBtnClicked(_ button: UIButton){ + if(button == viewBtn) { + let vc = STViewDemoController() + navigationController?.pushViewController(vc, animated: true) + }else if(button == scrollViewBtn) { + let vc = STScrollViewDemoController() + navigationController?.pushViewController(vc, animated: true) + }else if(button == tableViewBtn) { + let vc = STTableViewDemoController() + navigationController?.pushViewController(vc, animated: true) + }else if(button == webViewBtn) { + let vc = STWKWebViewDemoController() +// navigationController?.presentViewController(vc, animated: true, completion: nil) + navigationController?.pushViewController(vc, animated: true) + }else if(button == oldWebViewBtn) { + let vc = STUIWebViewDemoController() + navigationController?.pushViewController(vc, animated: true) + } + } +} diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/STScrollViewDemoController.swift b/Carthage/Checkouts/SwViewCapture/Example/Example/STScrollViewDemoController.swift new file mode 100755 index 0000000..5dbd5a6 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/STScrollViewDemoController.swift @@ -0,0 +1,83 @@ +// +// STScrollViewDemoController.swift +// STViewCapture +// +// Created by chenxing.cx on 15/10/28. +// Copyright © 2015年 startry.com All rights reserved. +// + +import UIKit +import WebKit + +class STScrollViewDemoController: UIViewController { + + // MARK: Life Cycle + + var scrollView: UIScrollView? + + override func viewDidLoad() { + super.viewDidLoad() + + navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Capture", style: UIBarButtonItemStyle.plain, target: self, action: #selector(STScrollViewDemoController.didCaptureBtnClicked(_:))) + + // Add Some Color View for Capture + let orangeView = UIView(frame: CGRect(x: 30, y: 100, width: 100, height: 100)) + let redView = UIView(frame: CGRect(x: 30, y: 200, width: 100, height: 100)) + + let headImage = UIImage(named: "demo_2") + let headImageView = UIImageView(frame: CGRect(x: 30, y: 300, width: headImage!.size.width / 2, height: headImage!.size.height / 2)) + headImageView.image = headImage + + let sceneImage = UIImage(named: "demo_1") + let sceneImageView = UIImageView(frame: CGRect(x: 30, y: 500, width: sceneImage!.size.width / 2, height: sceneImage!.size.height / 2)) + sceneImageView.image = sceneImage + + let url = URL(string: "http://www.startry.com") + let request = URLRequest(url: url!) + let webView = WKWebView(frame: CGRect(x: 0, y: 600, width: self.view.frame.size.width, height: 100)) + webView.load(request) + + orangeView.backgroundColor = UIColor.orange + redView.backgroundColor = UIColor.red + + scrollView = UIScrollView() + scrollView?.backgroundColor = UIColor.orange + scrollView?.contentSize = CGSize(width: view.bounds.width, height: 800) + + scrollView?.addSubview(orangeView) + scrollView?.addSubview(redView) + scrollView?.addSubview(headImageView) + scrollView?.addSubview(sceneImageView) + scrollView?.addSubview(webView) + + view.addSubview(scrollView!) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + scrollView?.frame = view.bounds + } + + // MARK: Events + + func didCaptureBtnClicked(_ button: UIButton){ + + scrollView?.swContentCapture({ (capturedImage) -> Void in + + UIImageWriteToSavedPhotosAlbum(capturedImage!, self, nil, nil) + + let vc = ImageViewController(image: capturedImage!) + self.navigationController?.pushViewController(vc, animated: true) + }) + +// scrollView?.swContentScrollCapture({ (capturedImage) -> Void in +// +// UIImageWriteToSavedPhotosAlbum(capturedImage!, self, nil, nil) +// +// let vc = ImageViewController(image: capturedImage!) +// self.navigationController?.pushViewController(vc, animated: true) +// }) + } + +} diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/STTableViewDemoController.swift b/Carthage/Checkouts/SwViewCapture/Example/Example/STTableViewDemoController.swift new file mode 100755 index 0000000..5e5867d --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/STTableViewDemoController.swift @@ -0,0 +1,69 @@ +// +// STTableViewDemoController.swift +// STViewCapture +// +// Created by chenxing.cx on 15/10/28. +// Copyright © 2015年 startry.com All rights reserved. +// + +import UIKit + +class STTableViewDemoController: UIViewController, UITableViewDelegate, UITableViewDataSource { + + let cellIdentify = "resuseableCellIdentify" + + var tableView: UITableView? + + override func viewDidLoad() { + super.viewDidLoad() + + navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Capture", style: UIBarButtonItemStyle.plain, target: self, action: #selector(STTableViewDemoController.didCaptureBtnClicked(_:))) + + tableView = UITableView() // tableView + + tableView?.dataSource = self + tableView?.delegate = self + + tableView?.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentify) + + view.addSubview(tableView!) + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + tableView?.frame = view.bounds + } + + // MARK: TableView DataSource + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 100 + } + + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentify) + + cell?.textLabel?.text = "show cell \((indexPath as NSIndexPath).row)" + + return cell! + } + + // MARK : Events + func didCaptureBtnClicked(_ button: UIButton){ + + tableView?.swContentCapture({ (capturedImage) -> Void in + let vc = ImageViewController(image: capturedImage!) + self.navigationController?.pushViewController(vc, animated: true) + }) + +// tableView?.swContentScrollCapture({ (capturedImage) -> Void in +// let vc = ImageViewController(image: capturedImage!) +// self.navigationController?.pushViewController(vc, animated: true) +// }) + } + +} diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/STUIWebViewDemoController.swift b/Carthage/Checkouts/SwViewCapture/Example/Example/STUIWebViewDemoController.swift new file mode 100755 index 0000000..6c794ec --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/STUIWebViewDemoController.swift @@ -0,0 +1,49 @@ +// +// STUIWebViewDemoController.swift +// Example +// +// Created by chenxing.cx on 16/2/15. +// Copyright © 2016年 Startry. All rights reserved. +// + +import UIKit + +class STUIWebViewDemoController: UIViewController { + + var webView: UIWebView? + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = UIColor.red + + navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Capture", style: UIBarButtonItemStyle.plain, target: self, action: #selector(STUIWebViewDemoController.didCaptureBtnClicked(_:))) + + webView = UIWebView(frame: view.bounds) + let url = URL(string: "http://www.startry.com") + let request = URLRequest(url: url!) + webView?.loadRequest(request) + + view.addSubview(webView!) + } + + // MARK: Events + func didCaptureBtnClicked(_ button: UIButton){ + webView?.swContentCapture({ (capturedImage) -> Void in + + UIImageWriteToSavedPhotosAlbum(capturedImage!, self, nil, nil) +// +// let vc = ImageViewController(image: capturedImage!) +// self.navigationController?.pushViewController(vc, animated: true) + }) + +// webView?.swContentScrollCapture({ (capturedImage) -> Void in +// +// UIImageWriteToSavedPhotosAlbum(capturedImage!, self, nil, nil) +// +// let vc = ImageViewController(image: capturedImage!) +// self.navigationController?.pushViewController(vc, animated: true) +// }) + } + +} diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/STViewDemoController.swift b/Carthage/Checkouts/SwViewCapture/Example/Example/STViewDemoController.swift new file mode 100755 index 0000000..d507ae3 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/STViewDemoController.swift @@ -0,0 +1,48 @@ +// +// STViewDemoController.swift +// STViewCapture +// +// Created by chenxing.cx on 10/28/2015. +// Copyright (c) 2015 startry.com All rights reserved. +// + +import UIKit +import SwViewCapture + +class STViewDemoController: UIViewController { + +// MARK: Life Cycle + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = UIColor.yellow + navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Capture", style: UIBarButtonItemStyle.plain, target: self, action: #selector(STViewDemoController.didCaptureBtnClicked(_:))) + + // Add Some Color View for Capture + let orangeView = UIView(frame: CGRect(x: 100, y: 100, width: 20, height: 50)) + let redView = UIView(frame: CGRect(x: 150, y: 200, width: 100, height: 100)) + + let headImage = UIImage(named: "demo_2") + let headImageView = UIImageView(frame: CGRect(x: 30, y: 300, width: headImage!.size.width, height: headImage!.size.height)) + headImageView.image = headImage + + orangeView.backgroundColor = UIColor.orange + redView.backgroundColor = UIColor.red + + view.addSubview(orangeView) + view.addSubview(redView) + view.addSubview(headImageView) + } + +// MARK: Events + + func didCaptureBtnClicked(_ button: UIButton){ + + view.swCapture { (capturedImage) -> Void in + let vc = ImageViewController(image: capturedImage!) + self.navigationController?.pushViewController(vc, animated: true) + } + } +} + diff --git a/Carthage/Checkouts/SwViewCapture/Example/Example/STWKWebViewDemoController.swift b/Carthage/Checkouts/SwViewCapture/Example/Example/STWKWebViewDemoController.swift new file mode 100755 index 0000000..0fb1cd3 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/Example/Example/STWKWebViewDemoController.swift @@ -0,0 +1,63 @@ +// +// STWKWebViewDemoController.swift +// STViewCapture +// +// Created by chenxing.cx on 15/10/28. +// Copyright © 2015年 startry.com All rights reserved. +// + +import UIKit +import WebKit + +class STWKWebViewDemoController: UIViewController { + + var webView: WKWebView? + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = UIColor.red + + navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Capture", style: UIBarButtonItemStyle.plain, target: self, action: #selector(STWKWebViewDemoController.didCaptureBtnClicked(_:))) + + webView = WKWebView(frame: self.view.bounds) + let url = URL(string: "http://www.startry.com") + let request = URLRequest(url: url!) + webView?.load(request) + + view.addSubview(webView!) + } + +// override func viewWillAppear(animated: Bool) { +// self.navigationController?.setNavigationBarHidden(true, animated: animated) +// } + +// override func viewDidAppear(animated: Bool) { +// super.viewDidAppear(animated) +// self.didCaptureBtnClicked(nil) +// } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() +// webView?.frame = self.view.bounds + } + + // MARK: Events + func didCaptureBtnClicked(_ button: UIButton?){ + + webView?.swContentCapture({ (capturedImage) -> Void in + + UIImageWriteToSavedPhotosAlbum(capturedImage!, self, nil, nil) + + let vc = ImageViewController(image: capturedImage!) + self.navigationController?.pushViewController(vc, animated: true) + }) + +// webView?.swContentScrollCapture({ (capturedImage) -> Void in +// UIImageWriteToSavedPhotosAlbum(capturedImage!, self, nil, nil) +// +// let vc = ImageViewController(image: capturedImage!) +// self.navigationController?.pushViewController(vc, animated: true) +// }) + } +} diff --git a/Carthage/Checkouts/SwViewCapture/LICENSE b/Carthage/Checkouts/SwViewCapture/LICENSE new file mode 100755 index 0000000..de2f342 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Xing Chen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/SwViewCapture/README.md b/Carthage/Checkouts/SwViewCapture/README.md new file mode 100755 index 0000000..62fc764 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/README.md @@ -0,0 +1,118 @@ +# SwViewCapture + +A nice iOS View Capture Library which can capture all content. + +SwViewCapture could convert all content of UIWebView to a UIImage. + +一个用起来还不错的iOS截图库.(支持截取所有内容, 适用于所有ScrollView组成的视图, 包括WKWebView) + +SwViewCapture支持截取网页以及ScrollView的所有内容 + +Swift 3.0 still has flash problem now!! + +[![Version](https://img.shields.io/cocoapods/v/SwViewCapture.svg?style=flat)](http://cocoapods.org/pods/SwViewCapture) +[![License](https://img.shields.io/cocoapods/l/SwViewCapture.svg?style=flat)](http://cocoapods.org/pods/SwViewCapture) +[![Platform](https://img.shields.io/cocoapods/p/SwViewCapture.svg?style=flat)](http://cocoapods.org/pods/SwViewCapture) + + Example + +## Feature + +1. API is more easy to use. + * use swift extension +2. Support to capture all content of scrollView. + * eg: UIScrollView, UITableView, UIWebView +3. Support capture WKWebView. + * WKWebview is hard to capture; + * WKWebView could be capture like UIWebView +4. Flasing will not appear in the process of Screenshots. + * SwCaptureView use a fake screenshots as a cover which over target view. All the action of target will be hidden below the fake screenshots. + +###功能 + +1. API更容易使用. + * 使用Extension去封装API + +2. 支持截取滚动视图内的所有内容. + * 支持UIScrollView, UITableView, UIWebView + +3. 支持截取WKWebView的内容. + * 因为WKWebView的内部实现问题, WKWebView比较难去截屏 + * 目前SwViewCapture对WKWebView的支持比较完美, 已经提供了两种截图方法, 非滚动的截图方式已经解决了`position: fixed`的问题 + +4. 截图过程中不会出现视图闪烁. + * 截图过程中, 使用一张伪装截图遮盖屏幕, 底层截图活动不透明化。 + +## Usage + +1. Capture basic screenshots (size of view's frame) + +``` Swift +import SwViewCapture +// ... +view.swCapture { (capturedImage) -> Void in + // capturedImage is a UIImage. +} +``` + +2. Capture all content screenshots (size of content) + +``` Swift +import SwViewCapture +// ... +view.swContentCapture { (capturedImage) -> Void in + // capturedImage is a UIImage. +} +``` + +###用法 + +* 普通截屏(屏幕大小) + +``` Swift +import SwViewCapture +// ... +view.swCapture { (capturedImage) -> Void in + // capturedImage is a UIImage. +} +``` + +* 内容截屏(全部内容的大小) + +``` Swift +import SwViewCapture +// ... +view.swContentCapture { (capturedImage) -> Void in + // capturedImage is a UIImage. +} +``` + +* 滚动截屏 + +``` Swift +import SwViewCapture +// ... +view.swContentScrollCapture { (capturedImage) -> Void in + // capturedImage is a UIImage. +} +``` + +## Requirement + +iOS 8.0+, Swift 2.0+ or Swift 3.0(Compatiable) + +SwViewCapture is available through [CocoaPods](http://cocoapods.org) now. To Install it, simply and the following line to your Podfile: + +``` ruby +pod "SwViewCapture" +``` + +Or, if you’re using [Carthage](https://github.com/Carthage/Carthage), add SwViewCapture to your Cartfile: + +``` +github "startry/SwViewCapture" +``` + +## License + +SwViewCapture is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture.podspec b/Carthage/Checkouts/SwViewCapture/SwViewCapture.podspec new file mode 100755 index 0000000..f70b8e7 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture.podspec @@ -0,0 +1,22 @@ +Pod::Spec.new do |s| +s.name = "SwViewCapture" +s.version = "1.0.5" +s.summary = "A nice iOS View Capture Library which can capture all content." + +s.description = <<-DESC + A nice iOS View Capture Library. SwViewCapture could capture all content of UIWebView & UIScrollView. + DESC + +s.homepage = "https://github.com/startry/SwViewCapture" +s.license = 'MIT' +s.author = { "chenxing.cx" => "chenxingfl@gmail.com" } +s.source = { :git => "https://github.com/startry/SwViewCapture.git", :tag => "1.0.5" } +s.social_media_url = 'https://twitter.com/xStartry' + +s.platform = :ios, '8.0' +s.requires_arc = true + +s.source_files = ["SwViewCapture/*.swift", "SwViewCapture/SwViewCapture.h"] +s.public_header_files = ["SwViewCapture/SwViewCapture.h"] + +end diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcodeproj/project.pbxproj b/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcodeproj/project.pbxproj new file mode 100755 index 0000000..dac3d77 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcodeproj/project.pbxproj @@ -0,0 +1,316 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 394BA35F1C7451F60012FCB5 /* UIView+SwCapture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 394BA35E1C7451F60012FCB5 /* UIView+SwCapture.swift */; }; + 39CC90871C785ED60057B0CE /* WKWebView+SwCapture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC90861C785ED60057B0CE /* WKWebView+SwCapture.swift */; }; + 39CC90BF1C8033180057B0CE /* UIScrollView+SwCapture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC90BE1C8033180057B0CE /* UIScrollView+SwCapture.swift */; }; + 39D6678D1BE2024900BF0BD7 /* SwViewCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 39D6678C1BE2024900BF0BD7 /* SwViewCapture.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 394BA35E1C7451F60012FCB5 /* UIView+SwCapture.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+SwCapture.swift"; sourceTree = ""; }; + 39CC90861C785ED60057B0CE /* WKWebView+SwCapture.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "WKWebView+SwCapture.swift"; sourceTree = ""; }; + 39CC90BE1C8033180057B0CE /* UIScrollView+SwCapture.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScrollView+SwCapture.swift"; sourceTree = ""; }; + 39D667891BE2024900BF0BD7 /* SwViewCapture.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwViewCapture.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 39D6678C1BE2024900BF0BD7 /* SwViewCapture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwViewCapture.h; sourceTree = ""; }; + 39D6678E1BE2024900BF0BD7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 39D667851BE2024900BF0BD7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 39D6677F1BE2024900BF0BD7 = { + isa = PBXGroup; + children = ( + 39D6678B1BE2024900BF0BD7 /* SwViewCapture */, + 39D6678A1BE2024900BF0BD7 /* Products */, + ); + sourceTree = ""; + }; + 39D6678A1BE2024900BF0BD7 /* Products */ = { + isa = PBXGroup; + children = ( + 39D667891BE2024900BF0BD7 /* SwViewCapture.framework */, + ); + name = Products; + sourceTree = ""; + }; + 39D6678B1BE2024900BF0BD7 /* SwViewCapture */ = { + isa = PBXGroup; + children = ( + 39D6678C1BE2024900BF0BD7 /* SwViewCapture.h */, + 39D6678E1BE2024900BF0BD7 /* Info.plist */, + 394BA35E1C7451F60012FCB5 /* UIView+SwCapture.swift */, + 39CC90861C785ED60057B0CE /* WKWebView+SwCapture.swift */, + 39CC90BE1C8033180057B0CE /* UIScrollView+SwCapture.swift */, + ); + path = SwViewCapture; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 39D667861BE2024900BF0BD7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 39D6678D1BE2024900BF0BD7 /* SwViewCapture.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 39D667881BE2024900BF0BD7 /* SwViewCapture */ = { + isa = PBXNativeTarget; + buildConfigurationList = 39D667911BE2024900BF0BD7 /* Build configuration list for PBXNativeTarget "SwViewCapture" */; + buildPhases = ( + 39D667841BE2024900BF0BD7 /* Sources */, + 39D667851BE2024900BF0BD7 /* Frameworks */, + 39D667861BE2024900BF0BD7 /* Headers */, + 39D667871BE2024900BF0BD7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SwViewCapture; + productName = SwViewCapture; + productReference = 39D667891BE2024900BF0BD7 /* SwViewCapture.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 39D667801BE2024900BF0BD7 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0800; + ORGANIZATIONNAME = Startry; + TargetAttributes = { + 39D667881BE2024900BF0BD7 = { + CreatedOnToolsVersion = 7.1; + LastSwiftMigration = 0800; + }; + }; + }; + buildConfigurationList = 39D667831BE2024900BF0BD7 /* Build configuration list for PBXProject "SwViewCapture" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 39D6677F1BE2024900BF0BD7; + productRefGroup = 39D6678A1BE2024900BF0BD7 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 39D667881BE2024900BF0BD7 /* SwViewCapture */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 39D667871BE2024900BF0BD7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 39D667841BE2024900BF0BD7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 39CC90871C785ED60057B0CE /* WKWebView+SwCapture.swift in Sources */, + 394BA35F1C7451F60012FCB5 /* UIView+SwCapture.swift in Sources */, + 39CC90BF1C8033180057B0CE /* UIScrollView+SwCapture.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 39D6678F1BE2024900BF0BD7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 39D667901BE2024900BF0BD7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 39D667921BE2024900BF0BD7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = SwViewCapture/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.startry.SwViewCapture; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 39D667931BE2024900BF0BD7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = SwViewCapture/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.startry.SwViewCapture; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 39D667831BE2024900BF0BD7 /* Build configuration list for PBXProject "SwViewCapture" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 39D6678F1BE2024900BF0BD7 /* Debug */, + 39D667901BE2024900BF0BD7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 39D667911BE2024900BF0BD7 /* Build configuration list for PBXNativeTarget "SwViewCapture" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 39D667921BE2024900BF0BD7 /* Debug */, + 39D667931BE2024900BF0BD7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 39D667801BE2024900BF0BD7 /* Project object */; +} diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100755 index 0000000..a9b314e --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcodeproj/xcshareddata/xcschemes/SwViewCapture.xcscheme b/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcodeproj/xcshareddata/xcschemes/SwViewCapture.xcscheme new file mode 100644 index 0000000..1d69bfb --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcodeproj/xcshareddata/xcschemes/SwViewCapture.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcworkspace/contents.xcworkspacedata new file mode 100755 index 0000000..d8b5822 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture/Info.plist b/Carthage/Checkouts/SwViewCapture/SwViewCapture/Info.plist new file mode 100755 index 0000000..d3de8ee --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture/SwViewCapture.h b/Carthage/Checkouts/SwViewCapture/SwViewCapture/SwViewCapture.h new file mode 100755 index 0000000..0e883de --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture/SwViewCapture.h @@ -0,0 +1,19 @@ +// +// SwViewCapture.h +// SwViewCapture +// +// Created by chenxing.cx on 15/10/29. +// Copyright © 2015年 Startry. All rights reserved. +// + +#import + +//! Project version number for SwViewCapture. +FOUNDATION_EXPORT double SwViewCaptureVersionNumber; + +//! Project version string for SwViewCapture. +FOUNDATION_EXPORT const unsigned char SwViewCaptureVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture/UIScrollView+SwCapture.swift b/Carthage/Checkouts/SwViewCapture/SwViewCapture/UIScrollView+SwCapture.swift new file mode 100755 index 0000000..0a2d4bf --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture/UIScrollView+SwCapture.swift @@ -0,0 +1,150 @@ +// +// UIScrollView+SwCapture.swift +// SwViewCapture +// +// Created by chenxing.cx on 16/2/26. +// Copyright © 2016年 Startry. All rights reserved. +// + +import Foundation +import WebKit + +public extension UIScrollView { + + public func swContentCapture (_ completionHandler: @escaping (_ capturedImage: UIImage?) -> Void) { + + self.isCapturing = true + + // Put a fake Cover of View + let snapShotView = self.snapshotView(afterScreenUpdates: false) + snapShotView?.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: (snapShotView?.frame.size.width)!, height: (snapShotView?.frame.size.height)!) + self.superview?.addSubview(snapShotView!) + + // Backup all properties of scrollview if needed + let bakFrame = self.frame + let bakOffset = self.contentOffset + let bakSuperView = self.superview + let bakIndex = self.superview?.subviews.index(of: self) + + // Scroll To Bottom show all cached view + if self.frame.size.height < self.contentSize.height { + self.contentOffset = CGPoint(x: 0, y: self.contentSize.height - self.frame.size.height) + } + + self.swRenderImageView({ [weak self] (capturedImage) -> Void in + // Recover View + + let strongSelf = self! + + strongSelf.removeFromSuperview() + strongSelf.frame = bakFrame + strongSelf.contentOffset = bakOffset + bakSuperView?.insertSubview(strongSelf, at: bakIndex!) + + snapShotView?.removeFromSuperview() + + strongSelf.isCapturing = false + + completionHandler(capturedImage) + }) + + } + + fileprivate func swRenderImageView(_ completionHandler: @escaping (_ capturedImage: UIImage?) -> Void) { + // Rebuild scrollView superView and their hold relationship + let swTempRenderView = UIView(frame: CGRect(x: 0, y: 0, width: self.contentSize.width, height: self.contentSize.height)) + self.removeFromSuperview() + swTempRenderView.addSubview(self) + + self.contentOffset = CGPoint.zero + self.frame = swTempRenderView.bounds + + // Swizzling setFrame + let method: Method = class_getInstanceMethod(object_getClass(self), #selector(setter: UIView.frame)) + let swizzledMethod: Method = class_getInstanceMethod(object_getClass(self), Selector("swSetFrame:")) + method_exchangeImplementations(method, swizzledMethod) + + // Sometimes ScrollView will Capture nothing without defer; + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.3 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { () -> Void in + let bounds = self.bounds + UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale) + + if (self.swContainsWKWebView()) { + self.drawHierarchy(in: bounds, afterScreenUpdates: true) + }else{ + self.layer.render(in: UIGraphicsGetCurrentContext()!) + } + let capturedImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + method_exchangeImplementations(swizzledMethod, method) + + completionHandler(capturedImage) + } + } + + + // Simulate People Action, all the `fixed` element will be repeate + // SwContentCapture will capture all content without simulate people action, more perfect. + public func swContentScrollCapture (_ completionHandler: @escaping (_ capturedImage: UIImage?) -> Void) { + + self.isCapturing = true + + // Put a fake Cover of View + let snapShotView = self.snapshotView(afterScreenUpdates: true) + snapShotView?.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: (snapShotView?.frame.size.width)!, height: (snapShotView?.frame.size.height)!) + self.superview?.addSubview(snapShotView!) + + // Backup + let bakOffset = self.contentOffset + + // Divide + let page = floorf(Float(self.contentSize.height / self.bounds.height)) + + UIGraphicsBeginImageContextWithOptions(self.contentSize, false, UIScreen.main.scale) + + self.swContentScrollPageDraw(0, maxIndex: Int(page), drawCallback: { [weak self] () -> Void in + let strongSelf = self + + let capturedImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + // Recover + strongSelf?.setContentOffset(bakOffset, animated: false) + snapShotView?.removeFromSuperview() + + strongSelf?.isCapturing = false + + completionHandler(capturedImage) + }) + + } + + fileprivate func swContentScrollPageDraw (_ index: Int, maxIndex: Int, drawCallback: @escaping () -> Void) { + + self.setContentOffset(CGPoint(x: 0, y: CGFloat(index) * self.frame.size.height), animated: false) + let splitFrame = CGRect(x: 0, y: CGFloat(index) * self.frame.size.height, width: bounds.size.width, height: bounds.size.height) + + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.3 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { () -> Void in + self.drawHierarchy(in: splitFrame, afterScreenUpdates: true) + + if index < maxIndex { + self.swContentScrollPageDraw(index + 1, maxIndex: maxIndex, drawCallback: drawCallback) + }else{ + drawCallback() + } + } + } +} + +public extension UIWebView { + + public func swContentCapture (_ completionHandler: @escaping (_ capturedImage: UIImage?) -> Void) { + self.scrollView.swContentCapture(completionHandler) + } + + public func swContentScrollCapture (_ completionHandler: @escaping (_ capturedImage: UIImage?) -> Void) { + self.scrollView.swContentScrollCapture(completionHandler) + } + +} diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture/UIView+SwCapture.swift b/Carthage/Checkouts/SwViewCapture/SwViewCapture/UIView+SwCapture.swift new file mode 100755 index 0000000..c2ef844 --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture/UIView+SwCapture.swift @@ -0,0 +1,80 @@ +// +// UIView+SwCapture.swift +// SwViewCapture +// +// Created by chenxing.cx on 16/2/17. +// Copyright © 2016年 Startry. All rights reserved. +// + +import UIKit +import WebKit +import ObjectiveC + +private var SwViewCaptureKey_IsCapturing: String = "SwViewCapture_AssoKey_isCapturing" + +public extension UIView { + + public func swSetFrame(_ frame: CGRect) { + // Do nothing, use for swizzling + } + + var isCapturing:Bool! { + get { + let num = objc_getAssociatedObject(self, &SwViewCaptureKey_IsCapturing) + if num == nil { + return false + } + +// num as AnyObject .boolValue + return false + +// return num.boolValue + } + set(newValue) { + let num = NSNumber(value: newValue as Bool) + objc_setAssociatedObject(self, &SwViewCaptureKey_IsCapturing, num, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + // Ref: chromium source - snapshot_manager, fix wkwebview screenshot bug. + // https://chromium.googlesource.com/chromium/src.git/+/46.0.2478.0/ios/chrome/browser/snapshots/snapshot_manager.mm + public func swContainsWKWebView() -> Bool { + if self.isKind(of: WKWebView.self) { + return true + } + for subView in self.subviews { + if (subView.swContainsWKWebView()) { + return true + } + } + return false + } + + public func swCapture(_ completionHandler: (_ capturedImage: UIImage?) -> Void) { + + self.isCapturing = true + + let bounds = self.bounds + + UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale) + + let context = UIGraphicsGetCurrentContext() + context?.saveGState() + context?.translateBy(x: -self.frame.origin.x, y: -self.frame.origin.y); + + if (swContainsWKWebView()) { + self.drawHierarchy(in: bounds, afterScreenUpdates: true) + }else{ + self.layer.render(in: context!) + } + let capturedImage = UIGraphicsGetImageFromCurrentImageContext() + + context?.restoreGState(); + UIGraphicsEndImageContext() + + self.isCapturing = false + + completionHandler(capturedImage) + } +} + diff --git a/Carthage/Checkouts/SwViewCapture/SwViewCapture/WKWebView+SwCapture.swift b/Carthage/Checkouts/SwViewCapture/SwViewCapture/WKWebView+SwCapture.swift new file mode 100755 index 0000000..c9bd39f --- /dev/null +++ b/Carthage/Checkouts/SwViewCapture/SwViewCapture/WKWebView+SwCapture.swift @@ -0,0 +1,157 @@ +// +// WKWebView+SwCapture.swift +// SwViewCapture +// +// Created by chenxing.cx on 16/2/19. +// Copyright © 2016年 Startry. All rights reserved. +// + +import Foundation +import WebKit +import ObjectiveC + +public extension WKWebView { + + public func swContentCapture(_ completionHandler:@escaping (_ capturedImage: UIImage?) -> Void) { + + self.isCapturing = true + + let offset = self.scrollView.contentOffset + + // Put a fake Cover of View + let snapShotView = self.snapshotView(afterScreenUpdates: true) + snapShotView?.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: (snapShotView?.frame.size.width)!, height: (snapShotView?.frame.size.height)!) + self.superview?.addSubview(snapShotView!) + + if self.frame.size.height < self.scrollView.contentSize.height { + self.scrollView.contentOffset = CGPoint(x: 0, y: self.scrollView.contentSize.height - self.frame.size.height) + } + + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.3 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { () -> Void in + self.scrollView.contentOffset = CGPoint.zero + + self.swContentCaptureWithoutOffset({ [weak self] (capturedImage) -> Void in + let strongSelf = self! + + strongSelf.scrollView.contentOffset = offset + + snapShotView?.removeFromSuperview() + + strongSelf.isCapturing = false + + completionHandler(capturedImage) + }) + } + } + + fileprivate func swContentCaptureWithoutOffset(_ completionHandler:@escaping (_ capturedImage: UIImage?) -> Void) { + let containerView = UIView(frame: self.bounds) + + let bakFrame = self.frame + let bakSuperView = self.superview + let bakIndex = self.superview?.subviews.index(of: self) + + // remove WebView from superview & put container view + self.removeFromSuperview() + containerView.addSubview(self) + + let totalSize = self.scrollView.contentSize + + // Divide + let page = floorf(Float( totalSize.height / containerView.bounds.height)) + + self.frame = CGRect(x: 0, y: 0, width: containerView.bounds.size.width, height: self.scrollView.contentSize.height) + + UIGraphicsBeginImageContextWithOptions(totalSize, false, UIScreen.main.scale) + + self.swContentPageDraw(containerView, index: 0, maxIndex: Int(page), drawCallback: { [weak self] () -> Void in + let strongSelf = self! + + let capturedImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + // Recover + strongSelf.removeFromSuperview() + bakSuperView?.insertSubview(strongSelf, at: bakIndex!) + + strongSelf.frame = bakFrame + + containerView.removeFromSuperview() + + completionHandler(capturedImage) + }) + } + + fileprivate func swContentPageDraw (_ targetView: UIView, index: Int, maxIndex: Int, drawCallback: @escaping () -> Void) { + + // set up split frame of super view + let splitFrame = CGRect(x: 0, y: CGFloat(index) * targetView.frame.size.height, width: targetView.bounds.size.width, height: targetView.frame.size.height) + // set up webview frame + var myFrame = self.frame + myFrame.origin.y = -(CGFloat(index) * targetView.frame.size.height) + self.frame = myFrame + + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.3 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { () -> Void in + targetView.drawHierarchy(in: splitFrame, afterScreenUpdates: true) + + if index < maxIndex { + self.swContentPageDraw(targetView, index: index + 1, maxIndex: maxIndex, drawCallback: drawCallback) + }else{ + drawCallback() + } + } + } + + + // Simulate People Action, all the `fixed` element will be repeate + // SwContentCapture will capture all content without simulate people action, more perfect. + public func swContentScrollCapture (_ completionHandler: @escaping (_ capturedImage: UIImage?) -> Void) { + + self.isCapturing = true + + // Put a fake Cover of View + let snapShotView = self.snapshotView(afterScreenUpdates: true) + snapShotView?.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y, width: (snapShotView?.frame.size.width)!, height: (snapShotView?.frame.size.height)!) + self.superview?.addSubview(snapShotView!) + + // Backup + let bakOffset = self.scrollView.contentOffset + + // Divide + let page = floorf(Float(self.scrollView.contentSize.height / self.bounds.height)) + + UIGraphicsBeginImageContextWithOptions(self.scrollView.contentSize, false, UIScreen.main.scale) + + self.swContentScrollPageDraw(0, maxIndex: Int(page), drawCallback: { [weak self] () -> Void in + let strongSelf = self + + let capturedImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + // Recover + strongSelf?.scrollView.setContentOffset(bakOffset, animated: false) + snapShotView?.removeFromSuperview() + + strongSelf?.isCapturing = false + + completionHandler(capturedImage) + }) + + } + + fileprivate func swContentScrollPageDraw (_ index: Int, maxIndex: Int, drawCallback: @escaping () -> Void) { + + self.scrollView.setContentOffset(CGPoint(x: 0, y: CGFloat(index) * self.scrollView.frame.size.height), animated: false) + let splitFrame = CGRect(x: 0, y: CGFloat(index) * self.scrollView.frame.size.height, width: bounds.size.width, height: bounds.size.height) + + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.3 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { () -> Void in + self.drawHierarchy(in: splitFrame, afterScreenUpdates: true) + + if index < maxIndex { + self.swContentScrollPageDraw(index + 1, maxIndex: maxIndex, drawCallback: drawCallback) + }else{ + drawCallback() + } + } + } +} diff --git a/Carthage/Checkouts/SwViewCapture/capture_demo.gif b/Carthage/Checkouts/SwViewCapture/capture_demo.gif new file mode 100755 index 0000000..c8ce90a Binary files /dev/null and b/Carthage/Checkouts/SwViewCapture/capture_demo.gif differ diff --git a/Carthage/Checkouts/SystemEye/.gitignore b/Carthage/Checkouts/SystemEye/.gitignore new file mode 100644 index 0000000..1de2633 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/.gitignore @@ -0,0 +1,65 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output diff --git a/Carthage/Checkouts/SystemEye/Example/Podfile b/Carthage/Checkouts/SystemEye/Example/Podfile new file mode 100644 index 0000000..e603884 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/Podfile @@ -0,0 +1,11 @@ +use_frameworks! + +target 'SystemEye_Example' do + pod 'SystemEye', :path => '../' + + target 'SystemEye_Tests' do + inherit! :search_paths + + + end +end diff --git a/Carthage/Checkouts/SystemEye/Example/Podfile.lock b/Carthage/Checkouts/SystemEye/Example/Podfile.lock new file mode 100644 index 0000000..d881b44 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - SystemEye (0.1.0) + +DEPENDENCIES: + - SystemEye (from `../`) + +EXTERNAL SOURCES: + SystemEye: + :path: "../" + +SPEC CHECKSUMS: + SystemEye: 4696d336ca80ae08b91dda84b15c47460b332c93 + +PODFILE CHECKSUM: 91d4840090c988b9224eb1317c42eae41e1c9a03 + +COCOAPODS: 1.1.1 diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/project.pbxproj b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f897daf --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/project.pbxproj @@ -0,0 +1,815 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 95C02093DFD2AE544FC6074A /* Pods_SystemEye_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 024257553D44398B285EC809 /* Pods_SystemEye_Tests.framework */; }; + 9E24FACF1E8132CA001AD0D7 /* SystemEye.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24FACD1E8132CA001AD0D7 /* SystemEye.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FAD21E8132CA001AD0D7 /* SystemEye.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E24FACB1E8132CA001AD0D7 /* SystemEye.framework */; }; + 9E24FAD31E8132CA001AD0D7 /* SystemEye.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9E24FACB1E8132CA001AD0D7 /* SystemEye.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9E24FAE91E8132EF001AD0D7 /* CPU.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FADD1E8132EF001AD0D7 /* CPU.swift */; }; + 9E24FAEA1E8132EF001AD0D7 /* FPS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FADE1E8132EF001AD0D7 /* FPS.swift */; }; + 9E24FAEB1E8132EF001AD0D7 /* Hardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FADF1E8132EF001AD0D7 /* Hardware.swift */; }; + 9E24FAEC1E8132EF001AD0D7 /* Memory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FAE01E8132EF001AD0D7 /* Memory.swift */; }; + 9E24FAED1E8132EF001AD0D7 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FAE11E8132EF001AD0D7 /* Network.swift */; }; + 9E24FAEE1E8132EF001AD0D7 /* NetworkFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FAE21E8132EF001AD0D7 /* NetworkFlow.swift */; }; + 9E24FAEF1E8132EF001AD0D7 /* NetObjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 9E24FAE41E8132EF001AD0D7 /* NetObjc.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9E24FAF01E8132EF001AD0D7 /* NetObjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FAE51E8132EF001AD0D7 /* NetObjc.m */; }; + 9E24FAF11E8132EF001AD0D7 /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E24FAE61E8132EF001AD0D7 /* System.swift */; }; + CB65EAFFC64B1AF9AF0AA51E /* Pods_SystemEye_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F3A1373284687036A87FB38 /* Pods_SystemEye_Example.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 607FACCF1AFB9204008FA782; + remoteInfo = SystemEye; + }; + 9E24FAD01E8132CA001AD0D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 607FACC81AFB9204008FA782 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9E24FACA1E8132CA001AD0D7; + remoteInfo = SystemEye; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9E24FAD71E8132CA001AD0D7 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 9E24FAD31E8132CA001AD0D7 /* SystemEye.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 024257553D44398B285EC809 /* Pods_SystemEye_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SystemEye_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F3A1373284687036A87FB38 /* Pods_SystemEye_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SystemEye_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 48F1D213771D208E37D2D87A /* Pods-SystemEye_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SystemEye_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-SystemEye_Example/Pods-SystemEye_Example.release.xcconfig"; sourceTree = ""; }; + 575BA952EEE14F2397E838A0 /* Pods-SystemEye_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SystemEye_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SystemEye_Example/Pods-SystemEye_Example.debug.xcconfig"; sourceTree = ""; }; + 607FACD01AFB9204008FA782 /* SystemEye_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SystemEye_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 607FACE51AFB9204008FA782 /* SystemEye_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SystemEye_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + 6C7B2BFBBC3DA726548E1AD6 /* Pods-SystemEye_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SystemEye_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SystemEye_Tests/Pods-SystemEye_Tests.release.xcconfig"; sourceTree = ""; }; + 9E24FACB1E8132CA001AD0D7 /* SystemEye.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SystemEye.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9E24FACD1E8132CA001AD0D7 /* SystemEye.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemEye.h; sourceTree = ""; }; + 9E24FACE1E8132CA001AD0D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9E24FADD1E8132EF001AD0D7 /* CPU.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CPU.swift; sourceTree = ""; }; + 9E24FADE1E8132EF001AD0D7 /* FPS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FPS.swift; sourceTree = ""; }; + 9E24FADF1E8132EF001AD0D7 /* Hardware.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hardware.swift; sourceTree = ""; }; + 9E24FAE01E8132EF001AD0D7 /* Memory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Memory.swift; sourceTree = ""; }; + 9E24FAE11E8132EF001AD0D7 /* Network.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = ""; }; + 9E24FAE21E8132EF001AD0D7 /* NetworkFlow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkFlow.swift; sourceTree = ""; }; + 9E24FAE41E8132EF001AD0D7 /* NetObjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetObjc.h; sourceTree = ""; }; + 9E24FAE51E8132EF001AD0D7 /* NetObjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NetObjc.m; sourceTree = ""; }; + 9E24FAE61E8132EF001AD0D7 /* System.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = System.swift; sourceTree = ""; }; + CF2465B179DE0365AE0CDFAA /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; + F2A5156B64F06E499083A3A2 /* SystemEye.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = SystemEye.podspec; path = ../SystemEye.podspec; sourceTree = ""; }; + FAE3212067D5B3B1598AFAFA /* Pods-SystemEye_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SystemEye_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SystemEye_Tests/Pods-SystemEye_Tests.debug.xcconfig"; sourceTree = ""; }; + FB16F65204C141F72B9B974C /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 607FACCD1AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CB65EAFFC64B1AF9AF0AA51E /* Pods_SystemEye_Example.framework in Frameworks */, + 9E24FAD21E8132CA001AD0D7 /* SystemEye.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE21AFB9204008FA782 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 95C02093DFD2AE544FC6074A /* Pods_SystemEye_Tests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FAC71E8132CA001AD0D7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 352EF9046A923D0E21ADF89C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1F3A1373284687036A87FB38 /* Pods_SystemEye_Example.framework */, + 024257553D44398B285EC809 /* Pods_SystemEye_Tests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 607FACC71AFB9204008FA782 = { + isa = PBXGroup; + children = ( + 607FACF51AFB993E008FA782 /* Podspec Metadata */, + 607FACD21AFB9204008FA782 /* Example for SystemEye */, + 607FACE81AFB9204008FA782 /* Tests */, + 9E24FACC1E8132CA001AD0D7 /* SystemEye */, + 607FACD11AFB9204008FA782 /* Products */, + 6B3FC26EED4C4C8321C105A6 /* Pods */, + 352EF9046A923D0E21ADF89C /* Frameworks */, + ); + sourceTree = ""; + }; + 607FACD11AFB9204008FA782 /* Products */ = { + isa = PBXGroup; + children = ( + 607FACD01AFB9204008FA782 /* SystemEye_Example.app */, + 607FACE51AFB9204008FA782 /* SystemEye_Tests.xctest */, + 9E24FACB1E8132CA001AD0D7 /* SystemEye.framework */, + ); + name = Products; + sourceTree = ""; + }; + 607FACD21AFB9204008FA782 /* Example for SystemEye */ = { + isa = PBXGroup; + children = ( + 607FACD51AFB9204008FA782 /* AppDelegate.swift */, + 607FACD71AFB9204008FA782 /* ViewController.swift */, + 607FACD91AFB9204008FA782 /* Main.storyboard */, + 607FACDC1AFB9204008FA782 /* Images.xcassets */, + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, + 607FACD31AFB9204008FA782 /* Supporting Files */, + ); + name = "Example for SystemEye"; + path = SystemEye; + sourceTree = ""; + }; + 607FACD31AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACD41AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACE81AFB9204008FA782 /* Tests */ = { + isa = PBXGroup; + children = ( + 607FACEB1AFB9204008FA782 /* Tests.swift */, + 607FACE91AFB9204008FA782 /* Supporting Files */, + ); + path = Tests; + sourceTree = ""; + }; + 607FACE91AFB9204008FA782 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 607FACEA1AFB9204008FA782 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { + isa = PBXGroup; + children = ( + F2A5156B64F06E499083A3A2 /* SystemEye.podspec */, + FB16F65204C141F72B9B974C /* README.md */, + CF2465B179DE0365AE0CDFAA /* LICENSE */, + ); + name = "Podspec Metadata"; + sourceTree = ""; + }; + 6B3FC26EED4C4C8321C105A6 /* Pods */ = { + isa = PBXGroup; + children = ( + 575BA952EEE14F2397E838A0 /* Pods-SystemEye_Example.debug.xcconfig */, + 48F1D213771D208E37D2D87A /* Pods-SystemEye_Example.release.xcconfig */, + FAE3212067D5B3B1598AFAFA /* Pods-SystemEye_Tests.debug.xcconfig */, + 6C7B2BFBBC3DA726548E1AD6 /* Pods-SystemEye_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9E24FACC1E8132CA001AD0D7 /* SystemEye */ = { + isa = PBXGroup; + children = ( + 9E24FAD81E8132EF001AD0D7 /* SystemEye */, + 9E24FACD1E8132CA001AD0D7 /* SystemEye.h */, + 9E24FACE1E8132CA001AD0D7 /* Info.plist */, + ); + path = SystemEye; + sourceTree = ""; + }; + 9E24FAD81E8132EF001AD0D7 /* SystemEye */ = { + isa = PBXGroup; + children = ( + 9E24FADB1E8132EF001AD0D7 /* Classes */, + ); + name = SystemEye; + path = ../../SystemEye; + sourceTree = ""; + }; + 9E24FADB1E8132EF001AD0D7 /* Classes */ = { + isa = PBXGroup; + children = ( + 9E24FADD1E8132EF001AD0D7 /* CPU.swift */, + 9E24FADE1E8132EF001AD0D7 /* FPS.swift */, + 9E24FADF1E8132EF001AD0D7 /* Hardware.swift */, + 9E24FAE01E8132EF001AD0D7 /* Memory.swift */, + 9E24FAE11E8132EF001AD0D7 /* Network.swift */, + 9E24FAE21E8132EF001AD0D7 /* NetworkFlow.swift */, + 9E24FAE31E8132EF001AD0D7 /* OCBridge */, + 9E24FAE61E8132EF001AD0D7 /* System.swift */, + ); + path = Classes; + sourceTree = ""; + }; + 9E24FAE31E8132EF001AD0D7 /* OCBridge */ = { + isa = PBXGroup; + children = ( + 9E24FAE41E8132EF001AD0D7 /* NetObjc.h */, + 9E24FAE51E8132EF001AD0D7 /* NetObjc.m */, + ); + path = OCBridge; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 9E24FAC81E8132CA001AD0D7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FAEF1E8132EF001AD0D7 /* NetObjc.h in Headers */, + 9E24FACF1E8132CA001AD0D7 /* SystemEye.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 607FACCF1AFB9204008FA782 /* SystemEye_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SystemEye_Example" */; + buildPhases = ( + 3A1F4AEA3630617EB33C6CDF /* [CP] Check Pods Manifest.lock */, + 607FACCC1AFB9204008FA782 /* Sources */, + 607FACCD1AFB9204008FA782 /* Frameworks */, + 607FACCE1AFB9204008FA782 /* Resources */, + 049AB436E2AFEAB01D1ED343 /* [CP] Embed Pods Frameworks */, + 9110D1B9346D223B812C8312 /* [CP] Copy Pods Resources */, + 9E24FAD71E8132CA001AD0D7 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 9E24FAD11E8132CA001AD0D7 /* PBXTargetDependency */, + ); + name = SystemEye_Example; + productName = SystemEye; + productReference = 607FACD01AFB9204008FA782 /* SystemEye_Example.app */; + productType = "com.apple.product-type.application"; + }; + 607FACE41AFB9204008FA782 /* SystemEye_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SystemEye_Tests" */; + buildPhases = ( + 3869EC300926761D7BB21AF6 /* [CP] Check Pods Manifest.lock */, + 607FACE11AFB9204008FA782 /* Sources */, + 607FACE21AFB9204008FA782 /* Frameworks */, + 607FACE31AFB9204008FA782 /* Resources */, + 231A6E03B4BBA6420B101A06 /* [CP] Embed Pods Frameworks */, + 76833D663508F09000F9CFFD /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 607FACE71AFB9204008FA782 /* PBXTargetDependency */, + ); + name = SystemEye_Tests; + productName = Tests; + productReference = 607FACE51AFB9204008FA782 /* SystemEye_Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9E24FACA1E8132CA001AD0D7 /* SystemEye */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9E24FAD61E8132CA001AD0D7 /* Build configuration list for PBXNativeTarget "SystemEye" */; + buildPhases = ( + 9E24FAC61E8132CA001AD0D7 /* Sources */, + 9E24FAC71E8132CA001AD0D7 /* Frameworks */, + 9E24FAC81E8132CA001AD0D7 /* Headers */, + 9E24FAC91E8132CA001AD0D7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SystemEye; + productName = SystemEye; + productReference = 9E24FACB1E8132CA001AD0D7 /* SystemEye.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 607FACC81AFB9204008FA782 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0720; + ORGANIZATIONNAME = CocoaPods; + TargetAttributes = { + 607FACCF1AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + }; + 607FACE41AFB9204008FA782 = { + CreatedOnToolsVersion = 6.3.1; + LastSwiftMigration = 0810; + TestTargetID = 607FACCF1AFB9204008FA782; + }; + 9E24FACA1E8132CA001AD0D7 = { + CreatedOnToolsVersion = 8.2.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "SystemEye" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 607FACC71AFB9204008FA782; + productRefGroup = 607FACD11AFB9204008FA782 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 607FACCF1AFB9204008FA782 /* SystemEye_Example */, + 607FACE41AFB9204008FA782 /* SystemEye_Tests */, + 9E24FACA1E8132CA001AD0D7 /* SystemEye */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 607FACCE1AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, + 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, + 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE31AFB9204008FA782 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FAC91E8132CA001AD0D7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 049AB436E2AFEAB01D1ED343 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SystemEye_Example/Pods-SystemEye_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 231A6E03B4BBA6420B101A06 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SystemEye_Tests/Pods-SystemEye_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 3869EC300926761D7BB21AF6 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 3A1F4AEA3630617EB33C6CDF /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 76833D663508F09000F9CFFD /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SystemEye_Tests/Pods-SystemEye_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9110D1B9346D223B812C8312 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SystemEye_Example/Pods-SystemEye_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 607FACCC1AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 607FACE11AFB9204008FA782 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9E24FAC61E8132CA001AD0D7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9E24FAEE1E8132EF001AD0D7 /* NetworkFlow.swift in Sources */, + 9E24FAED1E8132EF001AD0D7 /* Network.swift in Sources */, + 9E24FAEC1E8132EF001AD0D7 /* Memory.swift in Sources */, + 9E24FAEB1E8132EF001AD0D7 /* Hardware.swift in Sources */, + 9E24FAF11E8132EF001AD0D7 /* System.swift in Sources */, + 9E24FAE91E8132EF001AD0D7 /* CPU.swift in Sources */, + 9E24FAF01E8132EF001AD0D7 /* NetObjc.m in Sources */, + 9E24FAEA1E8132EF001AD0D7 /* FPS.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 607FACCF1AFB9204008FA782 /* SystemEye_Example */; + targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; + }; + 9E24FAD11E8132CA001AD0D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9E24FACA1E8132CA001AD0D7 /* SystemEye */; + targetProxy = 9E24FAD01E8132CA001AD0D7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 607FACD91AFB9204008FA782 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 607FACDA1AFB9204008FA782 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 607FACDF1AFB9204008FA782 /* Base */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 607FACED1AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 607FACEE1AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 607FACF01AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 575BA952EEE14F2397E838A0 /* Pods-SystemEye_Example.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = SystemEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF11AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 48F1D213771D208E37D2D87A /* Pods-SystemEye_Example.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = SystemEye/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MODULE_NAME = ExampleApp; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 607FACF31AFB9204008FA782 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FAE3212067D5B3B1598AFAFA /* Pods-SystemEye_Tests.debug.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 607FACF41AFB9204008FA782 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6C7B2BFBBC3DA726548E1AD6 /* Pods-SystemEye_Tests.release.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 9E24FAD41E8132CA001AD0D7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = SystemEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.SystemEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9E24FAD51E8132CA001AD0D7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = SystemEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.SystemEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "SystemEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACED1AFB9204008FA782 /* Debug */, + 607FACEE1AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SystemEye_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF01AFB9204008FA782 /* Debug */, + 607FACF11AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SystemEye_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 607FACF31AFB9204008FA782 /* Debug */, + 607FACF41AFB9204008FA782 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9E24FAD61E8132CA001AD0D7 /* Build configuration list for PBXNativeTarget "SystemEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E24FAD41E8132CA001AD0D7 /* Debug */, + 9E24FAD51E8132CA001AD0D7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 607FACC81AFB9204008FA782 /* Project object */; +} diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c202192 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/project.xcworkspace/xcshareddata/SystemEye.xcscmblueprint b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/project.xcworkspace/xcshareddata/SystemEye.xcscmblueprint new file mode 100644 index 0000000..e276b0f --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/project.xcworkspace/xcshareddata/SystemEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "56522D567136C88654F246802FF041D305640A0C", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807, + "56522D567136C88654F246802FF041D305640A0C" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "D7489AF9-2273-49F0-BD77-54B9506CE7C8", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/..", + "56522D567136C88654F246802FF041D305640A0C" : "SystemEye\/" + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "SystemEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/SystemEye.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/SystemEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "56522D567136C88654F246802FF041D305640A0C" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + } + ] +} \ No newline at end of file diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/xcshareddata/xcschemes/SystemEye-Example.xcscheme b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/xcshareddata/xcschemes/SystemEye-Example.xcscheme new file mode 100644 index 0000000..c4ec471 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/xcshareddata/xcschemes/SystemEye-Example.xcscheme @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/xcshareddata/xcschemes/SystemEye.xcscheme b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/xcshareddata/xcschemes/SystemEye.xcscheme new file mode 100644 index 0000000..5af0aee --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcodeproj/xcshareddata/xcschemes/SystemEye.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..5f0c832 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye/AppDelegate.swift b/Carthage/Checkouts/SystemEye/Example/SystemEye/AppDelegate.swift new file mode 100644 index 0000000..1833bdc --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// SystemEye +// +// Created by zixun on 12/26/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye/Base.lproj/LaunchScreen.xib b/Carthage/Checkouts/SystemEye/Example/SystemEye/Base.lproj/LaunchScreen.xib new file mode 100644 index 0000000..d22d96a --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye/Base.lproj/LaunchScreen.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye/Base.lproj/Main.storyboard b/Carthage/Checkouts/SystemEye/Example/SystemEye/Base.lproj/Main.storyboard new file mode 100644 index 0000000..52ea29e --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye/Images.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/SystemEye/Example/SystemEye/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d3942e9 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye/Info.plist b/Carthage/Checkouts/SystemEye/Example/SystemEye/Info.plist new file mode 100644 index 0000000..fbe1e6b --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye/SystemEye.h b/Carthage/Checkouts/SystemEye/Example/SystemEye/SystemEye.h new file mode 100644 index 0000000..b6cffc0 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye/SystemEye.h @@ -0,0 +1,21 @@ +// +// SystemEye.h +// SystemEye +// +// Created by zixun on 2017/3/21. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for SystemEye. +FOUNDATION_EXPORT double SystemEyeVersionNumber; + +//! Project version string for SystemEye. +FOUNDATION_EXPORT const unsigned char SystemEyeVersionString[]; + +#import "NetObjc.h" + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/SystemEye/Example/SystemEye/ViewController.swift b/Carthage/Checkouts/SystemEye/Example/SystemEye/ViewController.swift new file mode 100644 index 0000000..b134184 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/SystemEye/ViewController.swift @@ -0,0 +1,14 @@ +// +// ViewController.swift +// SystemEye +// +// Created by zixun on 12/26/2016. +// Copyright (c) 2016 zixun. All rights reserved. +// + +import UIKit +import SystemEye + +class ViewController: UIViewController { + +} diff --git a/Carthage/Checkouts/SystemEye/Example/Tests/Info.plist b/Carthage/Checkouts/SystemEye/Example/Tests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/SystemEye/Example/Tests/Tests.swift b/Carthage/Checkouts/SystemEye/Example/Tests/Tests.swift new file mode 100644 index 0000000..eb28691 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/Example/Tests/Tests.swift @@ -0,0 +1,29 @@ +import UIKit +import XCTest +import SystemEye + +class Tests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + XCTAssert(true, "Pass") + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure() { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Carthage/Checkouts/SystemEye/LICENSE b/Carthage/Checkouts/SystemEye/LICENSE new file mode 100644 index 0000000..c316be9 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 陈奕龙(子循) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/SystemEye/README.md b/Carthage/Checkouts/SystemEye/README.md new file mode 100644 index 0000000..5ca2350 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/README.md @@ -0,0 +1,54 @@ +# SystemEye + +[![Version](https://img.shields.io/cocoapods/v/SystemEye.svg?style=flat)](http://cocoapods.org/pods/SystemEye) +[![License](https://img.shields.io/cocoapods/l/SystemEye.svg?style=flat)](http://cocoapods.org/pods/SystemEye) +[![Platform](https://img.shields.io/cocoapods/p/SystemEye.svg?style=flat)](http://cocoapods.org/pods/SystemEye) +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) + +SystemEye is a system monitor,automatic catch the infomation of cpu,memory,fps,netflow....etc. + +## Family +This library is derived from the [GodEye](https://github.com/zixun/GodEye) project which can automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code. Just like god opened his eyes + +## Book & Principle + +**I has wrote a book named [《iOS监控编程》](https://www.qingdan.us/product/25),each chapter records the course function of the implementation details and the way to explore.sorry for english friends,this book wrote by chineses.** + + +## Example + +To run the example project, clone the repo, and run `pod install` from the Example directory first. + + +## Installation + +### CocoaPods +SystemEye is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: + +```ruby +pod "SystemEye" +``` + +### Carthage +Or, if you’re using [Carthage](https://github.com/Carthage/Carthage), add SwViewCapture to your Cartfile: + +``` +github "zixun/SystemEye" +``` + +## Author + +name: 陈奕龙 + +twitter: [@zixun_](https://twitter.com/zixun_) + +email: chenyl.exe@gmail.com + +github: [zixun](https://github.com/zixun) + +blog: [子循(SubCycle)](http://zixun.github.io/) + +## License + +SystemEye is available under the MIT license. See the LICENSE file for more info. diff --git a/Carthage/Checkouts/SystemEye/SystemEye.podspec b/Carthage/Checkouts/SystemEye/SystemEye.podspec new file mode 100644 index 0000000..c5ba815 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye.podspec @@ -0,0 +1,33 @@ +# +# Be sure to run `pod lib lint SystemEye.podspec' to ensure this is a +# valid spec before submitting. +# +# Any lines starting with a # are optional, but their use is encouraged +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# + +Pod::Spec.new do |s| + s.name = 'SystemEye' + s.version = '0.2.0' + s.summary = 'SystemEye is a system monitor,automatic catch the infomation of cpu,memory,fps,netflow....etc.' + +# This description is used to generate tags and improve search results. +# * Think: What does it do? Why did you write it? What is the focus? +# * Try to keep it short, snappy and to the point. +# * Write the description between the DESC delimiters below. +# * Finally, don't worry about the indent, CocoaPods strips it! + + s.description = <<-DESC +SystemEye is a system monitor,automatic catch the infomation of cpu,memory,fps,netflow....etc.. + DESC + + s.homepage = 'https://github.com/zixun/SystemEye' + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { 'zixun' => 'chenyl.exe@gmail.com' } + s.source = { :git => 'https://github.com/zixun/SystemEye.git', :tag => s.version.to_s } + s.social_media_url = 'https://twitter.com/zixun_' + + s.ios.deployment_target = '8.0' + + s.source_files = 'SystemEye/Classes/**/*' +end diff --git a/Carthage/Checkouts/SystemEye/SystemEye/Classes/CPU.swift b/Carthage/Checkouts/SystemEye/SystemEye/Classes/CPU.swift new file mode 100644 index 0000000..070ed28 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye/Classes/CPU.swift @@ -0,0 +1,189 @@ +// +// CPU.swift +// Pods +// +// Created by zixun on 2016/12/5. +// +// + +import Foundation + +private let HOST_CPU_LOAD_INFO_COUNT : mach_msg_type_number_t = + UInt32(MemoryLayout.size / MemoryLayout.size) + +/// CPU Class +open class CPU: NSObject { + + //-------------------------------------------------------------------------- + // MARK: OPEN PROPERTY + //-------------------------------------------------------------------------- + + /// Number of physical cores on this machine. + open static var physicalCores: Int { + get { + return Int(System.hostBasicInfo.physical_cpu) + } + } + + /// Number of logical cores on this machine. Will be equal to physicalCores + /// unless it has hyper-threading, in which case it will be double. + open static var logicalCores: Int { + get { + return Int(System.hostBasicInfo.logical_cpu) + } + } + + //-------------------------------------------------------------------------- + // MARK: OPEN FUNCTIONS + //-------------------------------------------------------------------------- + + /// Get CPU usage of hole system (system, user, idle, nice). Determined by the delta between + /// the current and last call. + open static func systemUsage() -> (system: Double, + user: Double, + idle: Double, + nice: Double) { + let load = self.hostCPULoadInfo + + let userDiff = Double(load.cpu_ticks.0 - loadPrevious.cpu_ticks.0) + let sysDiff = Double(load.cpu_ticks.1 - loadPrevious.cpu_ticks.1) + let idleDiff = Double(load.cpu_ticks.2 - loadPrevious.cpu_ticks.2) + let niceDiff = Double(load.cpu_ticks.3 - loadPrevious.cpu_ticks.3) + + let totalTicks = sysDiff + userDiff + niceDiff + idleDiff + + let sys = sysDiff / totalTicks * 100.0 + let user = userDiff / totalTicks * 100.0 + let idle = idleDiff / totalTicks * 100.0 + let nice = niceDiff / totalTicks * 100.0 + + loadPrevious = load + + return (sys, user, idle, nice) + } + + + /// Get CPU usage of application,get from all thread + open class func applicationUsage() -> Double { + let threads = self.threadBasicInfos() + var result : Double = 0.0 + threads.forEach { (thread:thread_basic_info) in + if self.flag(thread) { + result += Double.init(thread.cpu_usage) / Double.init(TH_USAGE_SCALE); + } + } + return result * 100 + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE PROPERTY + //-------------------------------------------------------------------------- + + /// previous load of cpu + private static var loadPrevious = host_cpu_load_info() + + static var hostCPULoadInfo: host_cpu_load_info { + get { + var size = HOST_CPU_LOAD_INFO_COUNT + var hostInfo = host_cpu_load_info() + let result = withUnsafeMutablePointer(to: &hostInfo) { + $0.withMemoryRebound(to: integer_t.self, capacity: Int(size)) { + host_statistics(System.machHost, HOST_CPU_LOAD_INFO, $0, &size) + } + } + + #if DEBUG + if result != KERN_SUCCESS { + fatalError("ERROR - \(#file):\(#function) - kern_result_t = " + + "\(result)") + } + #endif + + return hostInfo + } + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE FUNCTION + //-------------------------------------------------------------------------- + + private class func flag(_ thread:thread_basic_info) -> Bool { + let foo = thread.flags & TH_FLAGS_IDLE + let number = NSNumber.init(value: foo) + return !Bool.init(number) + } + + private class func threadActPointers() -> [thread_act_t] { + var threads_act = [thread_act_t]() + + var threads_array: thread_act_array_t? = nil + var count = mach_msg_type_number_t() + + let result = task_threads(mach_task_self_, &(threads_array), &count) + + guard result == KERN_SUCCESS else { + return threads_act + } + + guard let array = threads_array else { + return threads_act + } + + for i in 0...size) + let kr = vm_deallocate(mach_task_self_, vm_address_t(array.pointee), vm_size_t(krsize)); + return threads_act + } + + private class func threadBasicInfos() -> [thread_basic_info] { + var result = [thread_basic_info]() + + var thinfo : thread_info_t = thread_info_t.allocate(capacity: Int(THREAD_INFO_MAX)) + var thread_info_count = UnsafeMutablePointer.allocate(capacity: 128) + var basic_info_th: thread_basic_info_t? = nil + + for act_t in self.threadActPointers() { + thread_info_count.pointee = UInt32(THREAD_INFO_MAX); + let kr = thread_info(act_t ,thread_flavor_t(THREAD_BASIC_INFO),thinfo, thread_info_count); + if (kr != KERN_SUCCESS) { + return [thread_basic_info](); + } + basic_info_th = withUnsafePointer(to: &thinfo.pointee, { (ptr) -> thread_basic_info_t in + let int8Ptr = unsafeBitCast(ptr, to: thread_basic_info_t.self) + return int8Ptr + }) + if basic_info_th != nil { + result.append(basic_info_th!.pointee) + } + } + + return result + } + + //TODO: this function is used for get cpu usage of all thread,and this is in developing + private class func threadIdentifierInfos() -> [thread_identifier_info] { + var result = [thread_identifier_info]() + var thinfo : thread_info_t = thread_info_t.allocate(capacity: Int(THREAD_INFO_MAX)) + var thread_info_count = UnsafeMutablePointer.allocate(capacity: 128) + var identifier_info_th: thread_identifier_info_t? = nil + + for act_t in self.threadActPointers() { + thread_info_count.pointee = UInt32(THREAD_INFO_MAX); + let kr = thread_info(act_t ,thread_flavor_t(THREAD_IDENTIFIER_INFO),thinfo, thread_info_count); + if (kr != KERN_SUCCESS) { + return [thread_identifier_info](); + } + identifier_info_th = withUnsafePointer(to: &thinfo.pointee, { (ptr) -> thread_identifier_info_t in + let int8Ptr = unsafeBitCast(ptr, to: thread_identifier_info_t.self) + return int8Ptr + }) + if identifier_info_th != nil { + result.append(identifier_info_th!.pointee) + } + } + return result + } +} diff --git a/Carthage/Checkouts/SystemEye/SystemEye/Classes/FPS.swift b/Carthage/Checkouts/SystemEye/SystemEye/Classes/FPS.swift new file mode 100644 index 0000000..f336a1d --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye/Classes/FPS.swift @@ -0,0 +1,93 @@ +// +// FPS.swift +// Pods +// +// Created by zixun on 16/12/26. +// +// + +import Foundation + +@objc public protocol FPSDelegate: class { + @objc optional func fps(fps:FPS, currentFPS:Double) +} + +open class FPS: NSObject { + + open var isEnable: Bool = true + + open var updateInterval: Double = 1.0 + + open weak var delegate: FPSDelegate? + + public override init() { + super.init() + NotificationCenter.default.addObserver(self, + selector: #selector(FPS.applicationWillResignActiveNotification), + name: NSNotification.Name.UIApplicationWillResignActive, + object: nil) + + NotificationCenter.default.addObserver(self, + selector: #selector(FPS.applicationDidBecomeActiveNotification), + name: NSNotification.Name.UIApplicationDidBecomeActive, + object: nil) + } + + open func open() { + guard self.isEnable == true else { + return + } + self.displayLink.isPaused = false + } + + open func close() { + guard self.isEnable == true else { + return + } + + self.displayLink.isPaused = true + } + + + @objc private func applicationWillResignActiveNotification() { + guard self.isEnable == true else { + return + } + + self.displayLink.isPaused = true + } + + @objc private func applicationDidBecomeActiveNotification() { + guard self.isEnable == true else { + return + } + self.displayLink.isPaused = false + } + + @objc private func displayLinkHandler() { + self.count += self.displayLink.frameInterval + let interval = self.displayLink.timestamp - self.lastTime + + guard interval >= self.updateInterval else { + return + } + + self.lastTime = self.displayLink.timestamp + let fps = Double(self.count) / interval + self.count = 0 + + self.delegate?.fps?(fps: self, currentFPS: round(fps)) + + } + + private lazy var displayLink:CADisplayLink = { [unowned self] in + let new = CADisplayLink(target: self, selector: #selector(FPS.displayLinkHandler)) + new.isPaused = true + new.add(to: RunLoop.main, forMode: .commonModes) + return new + }() + + private var count:Int = 0 + + private var lastTime: CFTimeInterval = 0.0 +} diff --git a/Carthage/Checkouts/SystemEye/SystemEye/Classes/Hardware.swift b/Carthage/Checkouts/SystemEye/SystemEye/Classes/Hardware.swift new file mode 100644 index 0000000..cc8788b --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye/Classes/Hardware.swift @@ -0,0 +1,146 @@ +// +// Hardware.swift +// Pods +// +// Created by zixun on 17/1/20. +// +// + +import Foundation + +open class Hardware: NSObject { + + //-------------------------------------------------------------------------- + // MARK: OPEN PROPERTY + //-------------------------------------------------------------------------- + + /// System uptime, you can get the components from the result + open static var uptime: Date { + get { + /// get the info about the process + let processsInfo = ProcessInfo.processInfo + /// get the uptime of the system + let timeInterval = processsInfo.systemUptime + /// create and return the date + return Date(timeIntervalSinceNow: -timeInterval) + } + } + /// model of the device, eg: "iPhone", "iPod touch" + open static let deviceModel: String = UIDevice.current.model + /// name of the device, eg: "My iPhone" + open static var deviceName: String = UIDevice.current.name + /// system name of the device, eg: "iOS" + open static let systemName: String = UIDevice.current.systemName + /// system version of the device, eg: "10.0" + open static let systemVersion: String = UIDevice.current.systemVersion + /// version code of device, eg: "iPhone7,1" + open static var deviceVersionCode: String { + get { + var systemInfo = utsname() + uname(&systemInfo) + + let versionCode: String = String(validatingUTF8: NSString(bytes: &systemInfo.machine, length: Int(_SYS_NAMELEN), encoding: String.Encoding.ascii.rawValue)!.utf8String!)! + + return versionCode + } + } + /// version of device, eg: "iPhone5" + open static var deviceVersion: String { + get { + switch self.deviceVersionCode { + /*** iPhone ***/ + case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone4" + case "iPhone4,1", "iPhone4,2", "iPhone4,3": return "iPhone4S" + case "iPhone5,1", "iPhone5,2": return "iPhone5" + case "iPhone5,3", "iPhone5,4": return "iPhone5C" + case "iPhone6,1", "iPhone6,2": return "iPhone5S" + case "iPhone7,2": return "iPhone6" + case "iPhone7,1": return "iPhone6Plus" + case "iPhone8,1": return "iPhone6S" + case "iPhone8,2": return "iPhone6SPlus" + case "iPhone8,4": return "iPhoneSE" + case "iPhone9,1", "iPhone9,3": return "iPhone7" + case "iPhone9,2", "iPhone9,4": return "iPhone7Plus" + + /*** iPad ***/ + case "iPad1,1": return "iPad1" + case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return "iPad2" + case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad3" + case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad4" + case "iPad4,1", "iPad4,2", "iPad4,3": return "iPadAir" + case "iPad5,3", "iPad5,4": return "iPadAir2" + case "iPad2,5", "iPad2,6", "iPad2,7": return "iPadMini" + case "iPad4,4", "iPad4,5", "iPad4,6": return "iPadMini2" + case "iPad4,7", "iPad4,8", "iPad4,9": return "iPadMini3" + case "iPad5,1", "iPad5,2": return "iPadMini4" + case "iPad6,3", "iPad6,4", "iPad6,7", "iPad6,8": return "iPadPro" + + /*** iPod ***/ + case "iPod1,1": return "iPodTouch1Gen" + case "iPod2,1": return "iPodTouch2Gen" + case "iPod3,1": return "iPodTouch3Gen" + case "iPod4,1": return "iPodTouch4Gen" + case "iPod5,1": return "iPodTouch5Gen" + case "iPod7,1": return "iPodTouch6Gen" + + /*** Simulator ***/ + case "i386", "x86_64": return "Simulator" + + default: return "Unknown" + } + } + } + /// get the screen width (x) + open static var screenWidth: CGFloat { + get { + return UIScreen.main.bounds.size.width + } + } + /// get the screen height (y) + open static var screenHeight: CGFloat { + get { + return UIScreen.main.bounds.size.height + } + } + /// get the brightness of screen + open static var screenBrightness: CGFloat { + get { + return UIScreen.main.brightness + } + } + + open static var isMultitaskingSupported: Bool { + get { + return UIDevice.current.isMultitaskingSupported + } + } + /// is the debugger attached + open static var isDebuggerAttached: Bool { + get { + var info = kinfo_proc() + var mib : [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()] + var size = MemoryLayout.stride(ofValue: info) + let junk = sysctl(&mib, UInt32(mib.count), &info, &size, nil, 0) + assert(junk == 0, "sysctl failed") + return (info.kp_proc.p_flag & P_TRACED) != 0 + } + } + + /// is the device plugged in + open static var isPluggedIn: Bool { + get { + let preEnable = UIDevice.current.isBatteryMonitoringEnabled + UIDevice.current.isBatteryMonitoringEnabled = true + let batteryState = UIDevice.current.batteryState + UIDevice.current.isBatteryMonitoringEnabled = preEnable + return (batteryState == .charging || batteryState == .full) + } + } + + /// is the device jailbrokened + open static var isJailbroken: Bool { + let cydiaURL = "/Applications/Cydia.app" + return FileManager.default.fileExists(atPath: cydiaURL) + } + +} diff --git a/Carthage/Checkouts/SystemEye/SystemEye/Classes/Memory.swift b/Carthage/Checkouts/SystemEye/SystemEye/Classes/Memory.swift new file mode 100644 index 0000000..5dfbb7d --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye/Classes/Memory.swift @@ -0,0 +1,84 @@ +// +// Memory.swift +// Pods +// +// Created by zixun on 2016/12/6. +// +// + +import Foundation + +private let HOST_VM_INFO64_COUNT: mach_msg_type_number_t = + UInt32(MemoryLayout.size / MemoryLayout.size) + +private let PAGE_SIZE : Double = Double(vm_kernel_page_size) + +open class Memory: NSObject { + + //-------------------------------------------------------------------------- + // MARK: OPEN FUNCTION + //-------------------------------------------------------------------------- + + /// Memory usage of application + open class func applicationUsage() -> (used: Double, + total: Double) { + var info = mach_task_basic_info() + var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout.size) + let kerr = withUnsafeMutablePointer(to: &info) { + return $0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { + return task_info(mach_task_self_,task_flavor_t(MACH_TASK_BASIC_INFO),$0,&count + ) + } + } + guard kerr == KERN_SUCCESS else { + return (0,self.totalBytes) + } + + return (Double(info.resident_size),self.totalBytes) + } + + /// Memory usage of system + open class func systemUsage() -> (free: Double, + active: Double, + inactive: Double, + wired: Double, + compressed: Double, + total: Double) { + let statistics = self.VMStatistics64() + + + let free = Double(statistics.free_count) * PAGE_SIZE + let active = Double(statistics.active_count) * PAGE_SIZE + let inactive = Double(statistics.inactive_count) * PAGE_SIZE + let wired = Double(statistics.wire_count) * PAGE_SIZE + let compressed = Double(statistics.compressor_page_count) * PAGE_SIZE + + return (free,active,inactive,wired,compressed,self.totalBytes) + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE PROPERTY + //-------------------------------------------------------------------------- + private static let totalBytes = Double(ProcessInfo.processInfo.physicalMemory) + + //-------------------------------------------------------------------------- + // MARK: PRIVATE FUNCTION + //-------------------------------------------------------------------------- + private static func VMStatistics64() -> vm_statistics64 { + var size = HOST_VM_INFO64_COUNT + var hostInfo = vm_statistics64() + + let result = withUnsafeMutablePointer(to: &hostInfo) { + $0.withMemoryRebound(to: integer_t.self, capacity: Int(size)) { + host_statistics64(System.machHost, HOST_VM_INFO64, $0, &size) + } + } + #if DEBUG + if result != KERN_SUCCESS { + print("ERROR - \(#file):\(#function) - kern_result_t = " + + "\(result)") + } + #endif + return hostInfo + } +} diff --git a/Carthage/Checkouts/SystemEye/SystemEye/Classes/Network.swift b/Carthage/Checkouts/SystemEye/SystemEye/Classes/Network.swift new file mode 100644 index 0000000..459b7f7 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye/Classes/Network.swift @@ -0,0 +1,142 @@ +// +// Network.swift +// Pods +// +// Created by zixun on 17/1/20. +// +// + +import Foundation +import CoreTelephony + +open class Network: NSObject { + + //-------------------------------------------------------------------------- + // MARK: OPEN PROPERTY + //-------------------------------------------------------------------------- + + //-------------------------------------------------------------------------- + // MARK: CTCarrier + //-------------------------------------------------------------------------- + + /// mobile carrier name + open static var carrierName: String? { + get { + return self.carrier?.carrierName + } + } + + /// mobile carrier country + open static var carrierCountry: String? { + get { + let currentCountry = Locale.current as NSLocale + return currentCountry.object(forKey: NSLocale.Key.countryCode) as? String + } + } + + /// mobile carrier country code + open static var carrierMobileCountryCode: String? { + get { + return self.carrier?.mobileCountryCode + } + } + + /// get the carrier iso country code + open static var carrierISOCountryCode: String? { + get { + return self.carrier?.isoCountryCode + } + } + /// get the carrier mobile network code + open static var carrierMobileNetworkCode: String? { + get { + return self.carrier?.mobileNetworkCode + } + } + + open static var carrierAllowVOIP: Bool { + get { + return self.carrier?.allowsVOIP ?? false + } + } + + //-------------------------------------------------------------------------- + // MARK: WIFI + //-------------------------------------------------------------------------- + + open static var isConnectedToWifi: Bool { + get { + guard let address = self.wifiIPAddress else { + return false + } + + guard address.characters.count <= 0 else { + return false + } + + return true + } + } + + open static var wifiIPAddress: String? { + get { + return NetObjc.wifiIPAddress() + } + } + + open static var wifiNetmaskAddress: String? { + get { + return NetObjc.wifiNetmaskAddress() + } + } + + //-------------------------------------------------------------------------- + // MARK: CELL + //-------------------------------------------------------------------------- + + open static var isConnectedToCell: Bool { + get { + guard let address = self.cellIPAddress else { + return false + } + + guard address.characters.count <= 0 else { + return false + } + + return true + } + } + + open static var cellIPAddress: String? { + get { + return NetObjc.cellIPAddress() + } + } + + open static var cellNetmaskAddress: String? { + get { + return NetObjc.cellNetmaskAddress() + } + } + //-------------------------------------------------------------------------- + // MARK: NETWORK FLOW + //-------------------------------------------------------------------------- + open static func flow() -> (wifiSend: UInt32, + wifiReceived: UInt32, + wwanSend: UInt32, + wwanReceived: UInt32) { + let flow = NetObjc.flow() + return (flow.wifiSend,flow.wifiReceived,flow.wwanSend,flow.wwanReceived) + } + + //-------------------------------------------------------------------------- + // MARK: PRIVATE PROPERTY + //-------------------------------------------------------------------------- + private static var carrier: CTCarrier? { + get { + return CTTelephonyNetworkInfo().subscriberCellularProvider + } + } + +} diff --git a/Carthage/Checkouts/SystemEye/SystemEye/Classes/NetworkFlow.swift b/Carthage/Checkouts/SystemEye/SystemEye/Classes/NetworkFlow.swift new file mode 100644 index 0000000..a841fa0 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye/Classes/NetworkFlow.swift @@ -0,0 +1,66 @@ +// +// Net.swift +// Pods +// +// Created by zixun on 16/12/26. +// +// + +import Foundation + +@objc public protocol NetDelegate: class { + @objc optional func networkFlow(networkFlow:NetworkFlow,catchWithWifiSend wifiSend:UInt32,wifiReceived:UInt32,wwanSend:UInt32,wwanReceived:UInt32) +} + +open class NetworkFlow: NSObject { + + open weak var delegate: NetDelegate? + + private var eyeThread: Thread? + private var timeInterval:TimeInterval! + + open func open(with timeInterval:TimeInterval = 1) { + self.timeInterval = timeInterval + self.close() + self.eyeThread = Thread(target: self, selector: #selector(NetworkFlow.eyeThreadHandler), object: nil) + self.eyeThread?.name = "SystemEye_Net"; + self.eyeThread?.start() + } + + open func close() { + self.eyeThread?.cancel() + self.eyeThread = nil + } + + + @objc private func eyeThreadHandler() { + while true { + if Thread.current.isCancelled { + Thread.exit() + } + self.execute() + Thread.sleep(forTimeInterval: self.timeInterval) + } + } + + func execute() { + + let model = NetObjc.flow() + + if self.first_model == nil { + self.first_model = model + }else { + model.wifiSend -= self.first_model!.wifiSend + model.wifiReceived -= self.first_model!.wifiReceived + model.wwanSend -= self.first_model!.wwanSend + model.wwanReceived -= self.first_model!.wwanReceived + } + self.delegate?.networkFlow?(networkFlow: self, + catchWithWifiSend: model.wifiSend, + wifiReceived: model.wifiReceived, + wwanSend: model.wwanSend, + wwanReceived: model.wwanReceived) + } + + private var first_model: NetModel? +} diff --git a/Carthage/Checkouts/SystemEye/SystemEye/Classes/OCBridge/NetObjc.h b/Carthage/Checkouts/SystemEye/SystemEye/Classes/OCBridge/NetObjc.h new file mode 100644 index 0000000..eb4013c --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye/Classes/OCBridge/NetObjc.h @@ -0,0 +1,32 @@ +// +// NetObjc.h +// Pods +// +// Created by zixun on 17/1/4. +// +// + +#import + +@class NetModel; +@interface NetObjc : NSObject + ++ (nonnull NetModel *)flow; + ++ (nullable NSString *)wifiIPAddress; + ++ (nullable NSString *)wifiNetmaskAddress; + ++ (nullable NSString *)cellIPAddress; + ++ (nullable NSString *)cellNetmaskAddress; +@end + +@interface NetModel : NSObject + +@property (nonatomic,assign) u_int32_t wifiSend; +@property (nonatomic,assign) u_int32_t wifiReceived; +@property (nonatomic,assign) u_int32_t wwanSend; +@property (nonatomic,assign) u_int32_t wwanReceived; + +@end diff --git a/Carthage/Checkouts/SystemEye/SystemEye/Classes/OCBridge/NetObjc.m b/Carthage/Checkouts/SystemEye/SystemEye/Classes/OCBridge/NetObjc.m new file mode 100644 index 0000000..f147eb6 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye/Classes/OCBridge/NetObjc.m @@ -0,0 +1,221 @@ +// +// NetObjc.m +// Pods +// +// Created by zixun on 17/1/4. +// +// + +#import "NetObjc.h" +#import +#import + +#import +#import +#import +#import +#import +#import +#import +#include + +@implementation NetModel + +@end + +@implementation NetObjc + ++ (nonnull NetModel *)flow { + NetModel *result = [[NetModel alloc] init]; + struct ifaddrs *addrs; + const struct ifaddrs *cursor; + const struct if_data *networkStatisc; + + if (getifaddrs(&addrs) == 0) { + + cursor = addrs; + while (cursor != NULL) + { + // names of interfaces: en0 is WiFi ,pdp_ip0 is WWAN + if (cursor->ifa_addr->sa_family == AF_LINK) + { + if (strcmp(cursor->ifa_name, "en0") == 0) { + networkStatisc = (const struct if_data *) cursor->ifa_data; + result.wifiSend += networkStatisc->ifi_obytes; + result.wifiReceived += networkStatisc->ifi_ibytes; + } + + if (strcmp(cursor->ifa_name, "pdp_ip0") == 0) { + networkStatisc = (const struct if_data *) cursor->ifa_data; + result.wwanSend += networkStatisc->ifi_obytes; + result.wwanReceived += networkStatisc->ifi_ibytes; + } + } + cursor = cursor->ifa_next; + } + freeifaddrs(addrs); + } + + return result; +} + ++ (nullable NSString *)wifiIPAddress { + // Set a string for the address + NSString *result; + // Set up structs to hold the interfaces and the temporary address + struct ifaddrs *interfaces; + struct ifaddrs *temp; + // Set up int for success or fail + int status = 0; + + // Get all the network interfaces + status = getifaddrs(&interfaces); + + // If it's 0, then it's good + if (status == 0) { + // Loop through the list of interfaces + temp = interfaces; + // Run through it while it's still available + while(temp != NULL) { + // If the temp interface is a valid interface + if(temp->ifa_addr->sa_family == AF_INET){ + // Check if the interface is WiFi + if([[NSString stringWithUTF8String:temp->ifa_name] isEqualToString:@"en0"]){ + // Get the WiFi IP Address + result = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp->ifa_addr)->sin_addr)]; + } + } + + // Set the temp value to the next interface + temp = temp->ifa_next; + } + } + + freeifaddrs(interfaces); + return result; +} + +// Get WiFi Netmask Address ++ (nullable NSString *)wifiNetmaskAddress { + // Set up the variable + struct ifreq afr; + // Copy the string + strncpy(afr.ifr_name, [@"en0" UTF8String], IFNAMSIZ-1); + // Open a socket + int afd = socket(AF_INET, SOCK_DGRAM, 0); + + // Check the socket + if (afd == -1) { + // Error, socket failed to open + return nil; + } + + // Check the netmask output + if (ioctl(afd, SIOCGIFNETMASK, &afr) == -1) { + // Error, netmask wasn't found + close(afd); + return nil; + } + + // Close the socket + close(afd); + + // Create a char for the netmask + char *netstring = inet_ntoa(((struct sockaddr_in *)&afr.ifr_addr)->sin_addr); + + // Create a string for the netmask + NSString *netmask = [NSString stringWithUTF8String:netstring]; + + // Return successful + return netmask; +} + + +// Get Cell IP Address ++ (nullable NSString *)cellIPAddress { + // Set a string for the address + NSString *IPAddress; + // Set up structs to hold the interfaces and the temporary address + struct ifaddrs *Interfaces; + struct ifaddrs *temp; + struct sockaddr_in *s4; + char buf[64]; + + // If it's 0, then it's good + if (!getifaddrs(&Interfaces)) { + // Loop through the list of interfaces + temp = Interfaces; + + // Run through it while it's still available + while(temp != NULL) { + // If the temp interface is a valid interface + if(temp->ifa_addr->sa_family == AF_INET) { + // Check if the interface is Cell + if([[NSString stringWithUTF8String:temp->ifa_name] isEqualToString:@"pdp_ip0"]) { + s4 = (struct sockaddr_in *)temp->ifa_addr; + + if (inet_ntop(temp->ifa_addr->sa_family, (void *)&(s4->sin_addr), buf, sizeof(buf)) == NULL) { + // Failed to find it + IPAddress = nil; + } else { + // Got the Cell IP Address + IPAddress = [NSString stringWithUTF8String:buf]; + } + } + } + + // Set the temp value to the next interface + temp = temp->ifa_next; + } + } + + // Free the memory of the interfaces + freeifaddrs(Interfaces); + + // Check to make sure it's not empty + if (IPAddress == nil || IPAddress.length <= 0) { + // Empty, return not found + return nil; + } + + // Return the IP Address of the WiFi + return IPAddress; +} + ++ (nullable NSString *)cellNetmaskAddress { + // Set up the variable + struct ifreq afr; + // Copy the string + strncpy(afr.ifr_name, [@"pdp_ip0" UTF8String], IFNAMSIZ-1); + // Open a socket + int afd = socket(AF_INET, SOCK_DGRAM, 0); + + // Check the socket + if (afd == -1) { + // Error, socket failed to open + return nil; + } + + // Check the netmask output + if (ioctl(afd, SIOCGIFNETMASK, &afr) == -1) { + // Error, netmask wasn't found + // Close the socket + close(afd); + // Return error + return nil; + } + + // Close the socket + close(afd); + + // Create a char for the netmask + char *netstring = inet_ntoa(((struct sockaddr_in *)&afr.ifr_addr)->sin_addr); + + // Create a string for the netmask + NSString *Netmask = [NSString stringWithUTF8String:netstring]; + + // Return successful + return Netmask; +} + +@end diff --git a/Carthage/Checkouts/SystemEye/SystemEye/Classes/System.swift b/Carthage/Checkouts/SystemEye/SystemEye/Classes/System.swift new file mode 100644 index 0000000..6284a75 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/SystemEye/Classes/System.swift @@ -0,0 +1,54 @@ +// +// System.swift +// Pods +// +// Created by zixun on 17/1/19. +// +// + +import Foundation +private let HOST_BASIC_INFO_COUNT : mach_msg_type_number_t = + UInt32(MemoryLayout.size / MemoryLayout.size) + +open class System: NSObject { + + //-------------------------------------------------------------------------- + // MARK: - OPEN PROPERTY + //-------------------------------------------------------------------------- + + open static let hardware = Hardware.classForCoder() as! Hardware.Type + + open static let cpu = CPU.classForCoder() as! CPU.Type + + open static let memory = Memory.classForCoder() as! Memory.Type + + open static let network = Network.classForCoder() as! Network.Type + + //-------------------------------------------------------------------------- + // MARK: - Internal PROPERTY + //-------------------------------------------------------------------------- + static var hostBasicInfo: host_basic_info { + get { + var size = HOST_BASIC_INFO_COUNT + var hostInfo = host_basic_info() + + let result = withUnsafeMutablePointer(to: &hostInfo) { + $0.withMemoryRebound(to: integer_t.self, capacity: Int(size), { + host_info(machHost, HOST_BASIC_INFO,$0,&size) + }) + } + #if DEBUG + if result != KERN_SUCCESS { + fatalError("ERROR - \(#file):\(#function) - kern_result_t = " + + "\(result)") + } + #endif + return hostInfo + } + } + + //-------------------------------------------------------------------------- + // MARK: - PRIVATE PROPERTY + //-------------------------------------------------------------------------- + static let machHost = mach_host_self() +} diff --git a/Carthage/Checkouts/SystemEye/_Pods.xcodeproj b/Carthage/Checkouts/SystemEye/_Pods.xcodeproj new file mode 120000 index 0000000..3c5a8e7 --- /dev/null +++ b/Carthage/Checkouts/SystemEye/_Pods.xcodeproj @@ -0,0 +1 @@ +Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/.gitignore b/Carthage/Checkouts/pull-to-refresh/.gitignore new file mode 100644 index 0000000..ee0c66d --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/.gitignore @@ -0,0 +1,178 @@ +reated by https://www.gitignore.io/api/xcode,objective-c,swift,osx + +### Xcode ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + + +### Objective-C ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md + +fastlane/report.xml +fastlane/screenshots + +### Objective-C Patch ### +*.xcscmblueprint + + +### Swift ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output + + +### OSX ### +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + diff --git a/Carthage/Checkouts/pull-to-refresh/.swift-version b/Carthage/Checkouts/pull-to-refresh/.swift-version new file mode 100644 index 0000000..9f55b2c --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/.swift-version @@ -0,0 +1 @@ +3.0 diff --git a/Carthage/Checkouts/pull-to-refresh/.travis.yml b/Carthage/Checkouts/pull-to-refresh/.travis.yml new file mode 100644 index 0000000..91c2bd2 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/.travis.yml @@ -0,0 +1,6 @@ +osx_image: xcode7.3 +language: swift + +xcode_project: ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj +xcode_scheme: ESPullToRefreshExample +xcode_sdk: iphonesimulator \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefresh.podspec b/Carthage/Checkouts/pull-to-refresh/ESPullToRefresh.podspec new file mode 100755 index 0000000..bb63c8e --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefresh.podspec @@ -0,0 +1,17 @@ + +Pod::Spec.new do |s| + s.name = 'ESPullToRefresh' + s.version = '2.6' + s.summary = 'An easy way to use pull-to-refresh and loading-more' + s.description = 'An easiest way to give pull-to-refresh and loading-more to any UIScrollView. Using swift!' + s.homepage = 'https://github.com/eggswift/pull-to-refresh' + + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.authors = { 'lihao' => 'lihao_ios@hotmail.com'} + s.social_media_url = 'https://github.com/eggswift' + s.platform = :ios, '8.0' + s.source = {:git => 'https://github.com/eggswift/pull-to-refresh.git', :tag => s.version} + s.source_files = ['Sources/**/*.{swift}'] + s.resource_bundles = { 'ESPullToRefresh' => 'Sources/Animator/*.png' } + s.requires_arc = true +end diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefresh/ESPullToRefresh.h b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefresh/ESPullToRefresh.h new file mode 100644 index 0000000..d981920 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefresh/ESPullToRefresh.h @@ -0,0 +1,19 @@ +// +// ESPullToRefresh.h +// ESPullToRefresh +// +// Created by lihao on 16/6/12. +// Copyright © 2016年 egg swift. All rights reserved. +// + +#import + +//! Project version number for ESPullToRefresh. +FOUNDATION_EXPORT double ESPullToRefreshVersionNumber; + +//! Project version string for ESPullToRefresh. +FOUNDATION_EXPORT const unsigned char ESPullToRefreshVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefresh/Info.plist b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefresh/Info.plist new file mode 100644 index 0000000..f4d50a8 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefresh/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.6 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj/project.pbxproj b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..bed72da --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj/project.pbxproj @@ -0,0 +1,639 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + F63613701CDD9CCD00AA9AF7 /* MTRefreshHeaderAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F636136F1CDD9CCD00AA9AF7 /* MTRefreshHeaderAnimator.swift */; }; + F63613721CDD9CD900AA9AF7 /* MTRefreshFooterAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F63613711CDD9CD900AA9AF7 /* MTRefreshFooterAnimator.swift */; }; + F64456001D65A2F10094D58E /* ESRefreshTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F64455FF1D65A2F10094D58E /* ESRefreshTableViewController.swift */; }; + F66B80331D86BE36006DDD16 /* ListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F66B80311D86BE36006DDD16 /* ListTableViewCell.swift */; }; + F66B80341D86BE36006DDD16 /* ListTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F66B80321D86BE36006DDD16 /* ListTableViewCell.xib */; }; + F690770B1D0D0A7F00BE91FE /* ESRefreshFooterAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077011D0D0A7F00BE91FE /* ESRefreshFooterAnimator.swift */; }; + F690770E1D0D0A7F00BE91FE /* ESRefreshHeaderAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077021D0D0A7F00BE91FE /* ESRefreshHeaderAnimator.swift */; }; + F69077111D0D0A7F00BE91FE /* icon_pull_to_refresh_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F69077031D0D0A7F00BE91FE /* icon_pull_to_refresh_arrow@2x.png */; }; + F69077141D0D0A7F00BE91FE /* ESPullToRefresh+Manager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077041D0D0A7F00BE91FE /* ESPullToRefresh+Manager.swift */; }; + F69077181D0D0A7F00BE91FE /* ESPullToRefresh.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077061D0D0A7F00BE91FE /* ESPullToRefresh.swift */; }; + F690771B1D0D0A7F00BE91FE /* ESRefreshAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077071D0D0A7F00BE91FE /* ESRefreshAnimator.swift */; }; + F690771E1D0D0A7F00BE91FE /* ESRefreshComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077081D0D0A7F00BE91FE /* ESRefreshComponent.swift */; }; + F69077211D0D0A7F00BE91FE /* ESRefreshProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077091D0D0A7F00BE91FE /* ESRefreshProtocol.swift */; }; + F69077301D0D0AE300BE91FE /* ESPullToRefresh.h in Headers */ = {isa = PBXBuildFile; fileRef = F690772F1D0D0AE300BE91FE /* ESPullToRefresh.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F69077351D0D0AF400BE91FE /* ESRefreshFooterAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077011D0D0A7F00BE91FE /* ESRefreshFooterAnimator.swift */; }; + F69077361D0D0AF400BE91FE /* ESRefreshHeaderAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077021D0D0A7F00BE91FE /* ESRefreshHeaderAnimator.swift */; }; + F69077381D0D0AF400BE91FE /* ESPullToRefresh+Manager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077041D0D0A7F00BE91FE /* ESPullToRefresh+Manager.swift */; }; + F69077391D0D0AF400BE91FE /* ESPullToRefresh.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077061D0D0A7F00BE91FE /* ESPullToRefresh.swift */; }; + F690773A1D0D0AF400BE91FE /* ESRefreshAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077071D0D0A7F00BE91FE /* ESRefreshAnimator.swift */; }; + F690773B1D0D0AF400BE91FE /* ESRefreshComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077081D0D0A7F00BE91FE /* ESRefreshComponent.swift */; }; + F690773C1D0D0AF400BE91FE /* ESRefreshProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69077091D0D0A7F00BE91FE /* ESRefreshProtocol.swift */; }; + F69200101CDB9A530029EF47 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F692000F1CDB9A530029EF47 /* AppDelegate.swift */; }; + F69200121CDB9A530029EF47 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F69200111CDB9A530029EF47 /* ViewController.swift */; }; + F69200151CDB9A530029EF47 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F69200131CDB9A530029EF47 /* Main.storyboard */; }; + F69200171CDB9A530029EF47 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F69200161CDB9A530029EF47 /* Assets.xcassets */; }; + F692001A1CDB9A530029EF47 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F69200181CDB9A530029EF47 /* LaunchScreen.storyboard */; }; + F6AA6C401CDC80DD00723622 /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6AA6C3E1CDC80DD00723622 /* WebViewController.swift */; }; + F6AA6C411CDC80DD00723622 /* WebViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6AA6C3F1CDC80DD00723622 /* WebViewController.xib */; }; + F6AB6EA51D6AF82100AC33BE /* ESRefreshTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6AB6EA31D6AF82100AC33BE /* ESRefreshTableViewCell.swift */; }; + F6AB6EA61D6AF82100AC33BE /* ESRefreshTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6AB6EA41D6AF82100AC33BE /* ESRefreshTableViewCell.xib */; }; + F6AE47331CE062F00006C017 /* WCRefreshHeaderAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6AE47321CE062F00006C017 /* WCRefreshHeaderAnimator.swift */; }; + F6AE47371CE089480006C017 /* WeChatTableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6AE47361CE089480006C017 /* WeChatTableHeaderView.swift */; }; + F6C5F2F61DD2C8C7001DEA80 /* ESPhotoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6C5F2F41DD2C8C7001DEA80 /* ESPhotoTableViewCell.swift */; }; + F6C5F2F71DD2C8C7001DEA80 /* ESPhotoTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F6C5F2F51DD2C8C7001DEA80 /* ESPhotoTableViewCell.xib */; }; + F6C5F2FB1DD31C1A001DEA80 /* CollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6C5F2FA1DD31C1A001DEA80 /* CollectionViewController.swift */; }; + F6C5F2FC1DD32225001DEA80 /* icon_pull_to_refresh_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F69077031D0D0A7F00BE91FE /* icon_pull_to_refresh_arrow@2x.png */; }; + F6E433C41D1BB36700307E8A /* TextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E433C31D1BB36700307E8A /* TextViewController.swift */; }; + F6F63A3F1D3C75750017F621 /* ESRefreshDayHeaderAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6F63A3E1D3C75750017F621 /* ESRefreshDayHeaderAnimator.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + F69076351D0D059B00BE91FE /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + F636136F1CDD9CCD00AA9AF7 /* MTRefreshHeaderAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTRefreshHeaderAnimator.swift; sourceTree = ""; }; + F63613711CDD9CD900AA9AF7 /* MTRefreshFooterAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTRefreshFooterAnimator.swift; sourceTree = ""; }; + F64455FF1D65A2F10094D58E /* ESRefreshTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESRefreshTableViewController.swift; sourceTree = ""; }; + F66B80311D86BE36006DDD16 /* ListTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTableViewCell.swift; sourceTree = ""; }; + F66B80321D86BE36006DDD16 /* ListTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ListTableViewCell.xib; sourceTree = ""; }; + F690763F1D0D065300BE91FE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + F69077011D0D0A7F00BE91FE /* ESRefreshFooterAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESRefreshFooterAnimator.swift; sourceTree = ""; }; + F69077021D0D0A7F00BE91FE /* ESRefreshHeaderAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESRefreshHeaderAnimator.swift; sourceTree = ""; }; + F69077031D0D0A7F00BE91FE /* icon_pull_to_refresh_arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_pull_to_refresh_arrow@2x.png"; sourceTree = ""; }; + F69077041D0D0A7F00BE91FE /* ESPullToRefresh+Manager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ESPullToRefresh+Manager.swift"; sourceTree = ""; }; + F69077061D0D0A7F00BE91FE /* ESPullToRefresh.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESPullToRefresh.swift; sourceTree = ""; }; + F69077071D0D0A7F00BE91FE /* ESRefreshAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESRefreshAnimator.swift; sourceTree = ""; }; + F69077081D0D0A7F00BE91FE /* ESRefreshComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESRefreshComponent.swift; sourceTree = ""; }; + F69077091D0D0A7F00BE91FE /* ESRefreshProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESRefreshProtocol.swift; sourceTree = ""; }; + F690772D1D0D0AE300BE91FE /* ESPullToRefresh.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ESPullToRefresh.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F690772F1D0D0AE300BE91FE /* ESPullToRefresh.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ESPullToRefresh.h; sourceTree = ""; }; + F69077311D0D0AE300BE91FE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F692000C1CDB9A530029EF47 /* ESRefresh.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ESRefresh.app; sourceTree = BUILT_PRODUCTS_DIR; }; + F692000F1CDB9A530029EF47 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + F69200111CDB9A530029EF47 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + F69200141CDB9A530029EF47 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + F69200161CDB9A530029EF47 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + F69200191CDB9A530029EF47 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + F692001B1CDB9A530029EF47 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F6AA6C3E1CDC80DD00723622 /* WebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebViewController.swift; sourceTree = ""; }; + F6AA6C3F1CDC80DD00723622 /* WebViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WebViewController.xib; sourceTree = ""; }; + F6AB6EA31D6AF82100AC33BE /* ESRefreshTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESRefreshTableViewCell.swift; sourceTree = ""; }; + F6AB6EA41D6AF82100AC33BE /* ESRefreshTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ESRefreshTableViewCell.xib; sourceTree = ""; }; + F6AE47321CE062F00006C017 /* WCRefreshHeaderAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WCRefreshHeaderAnimator.swift; sourceTree = ""; }; + F6AE47361CE089480006C017 /* WeChatTableHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeChatTableHeaderView.swift; sourceTree = ""; }; + F6C5F2F41DD2C8C7001DEA80 /* ESPhotoTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESPhotoTableViewCell.swift; sourceTree = ""; }; + F6C5F2F51DD2C8C7001DEA80 /* ESPhotoTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ESPhotoTableViewCell.xib; sourceTree = ""; }; + F6C5F2FA1DD31C1A001DEA80 /* CollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewController.swift; sourceTree = ""; }; + F6E433C31D1BB36700307E8A /* TextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextViewController.swift; sourceTree = ""; }; + F6F63A3E1D3C75750017F621 /* ESRefreshDayHeaderAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ESRefreshDayHeaderAnimator.swift; path = Day/ESRefreshDayHeaderAnimator.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + F69077291D0D0AE300BE91FE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F69200091CDB9A530029EF47 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + F636136D1CDD9C9100AA9AF7 /* Custom */ = { + isa = PBXGroup; + children = ( + F64455FF1D65A2F10094D58E /* ESRefreshTableViewController.swift */, + F6AB6EA31D6AF82100AC33BE /* ESRefreshTableViewCell.swift */, + F6AB6EA41D6AF82100AC33BE /* ESRefreshTableViewCell.xib */, + F6C5F2F41DD2C8C7001DEA80 /* ESPhotoTableViewCell.swift */, + F6C5F2F51DD2C8C7001DEA80 /* ESPhotoTableViewCell.xib */, + F6F63A3D1D3C75000017F621 /* Day */, + F636136E1CDD9CA000AA9AF7 /* Meituan */, + F6AE472F1CE0628B0006C017 /* WeChat */, + F6E433C21D1BB34800307E8A /* TextView */, + F6C5F2F91DD31C1A001DEA80 /* CollectionView */, + ); + path = Custom; + sourceTree = ""; + }; + F636136E1CDD9CA000AA9AF7 /* Meituan */ = { + isa = PBXGroup; + children = ( + F636136F1CDD9CCD00AA9AF7 /* MTRefreshHeaderAnimator.swift */, + F63613711CDD9CD900AA9AF7 /* MTRefreshFooterAnimator.swift */, + ); + path = Meituan; + sourceTree = ""; + }; + F69076FF1D0D0A7F00BE91FE /* Sources */ = { + isa = PBXGroup; + children = ( + F69077001D0D0A7F00BE91FE /* Animator */, + F69077041D0D0A7F00BE91FE /* ESPullToRefresh+Manager.swift */, + F69077061D0D0A7F00BE91FE /* ESPullToRefresh.swift */, + F69077081D0D0A7F00BE91FE /* ESRefreshComponent.swift */, + F69077071D0D0A7F00BE91FE /* ESRefreshAnimator.swift */, + F69077091D0D0A7F00BE91FE /* ESRefreshProtocol.swift */, + ); + name = Sources; + path = ../Sources; + sourceTree = ""; + }; + F69077001D0D0A7F00BE91FE /* Animator */ = { + isa = PBXGroup; + children = ( + F69077021D0D0A7F00BE91FE /* ESRefreshHeaderAnimator.swift */, + F69077011D0D0A7F00BE91FE /* ESRefreshFooterAnimator.swift */, + F69077031D0D0A7F00BE91FE /* icon_pull_to_refresh_arrow@2x.png */, + ); + path = Animator; + sourceTree = ""; + }; + F69077271D0D0AC400BE91FE /* Framework */ = { + isa = PBXGroup; + children = ( + F690763F1D0D065300BE91FE /* UIKit.framework */, + ); + name = Framework; + path = ESPullToRefreshExample; + sourceTree = ""; + }; + F690772E1D0D0AE300BE91FE /* ESPullToRefresh */ = { + isa = PBXGroup; + children = ( + F690772F1D0D0AE300BE91FE /* ESPullToRefresh.h */, + F69077311D0D0AE300BE91FE /* Info.plist */, + ); + path = ESPullToRefresh; + sourceTree = ""; + }; + F69200031CDB9A530029EF47 = { + isa = PBXGroup; + children = ( + F69076FF1D0D0A7F00BE91FE /* Sources */, + F692000E1CDB9A530029EF47 /* ESPullToRefreshExample */, + F69077271D0D0AC400BE91FE /* Framework */, + F690772E1D0D0AE300BE91FE /* ESPullToRefresh */, + F692000D1CDB9A530029EF47 /* Products */, + ); + sourceTree = ""; + }; + F692000D1CDB9A530029EF47 /* Products */ = { + isa = PBXGroup; + children = ( + F692000C1CDB9A530029EF47 /* ESRefresh.app */, + F690772D1D0D0AE300BE91FE /* ESPullToRefresh.framework */, + ); + name = Products; + sourceTree = ""; + }; + F692000E1CDB9A530029EF47 /* ESPullToRefreshExample */ = { + isa = PBXGroup; + children = ( + F692000F1CDB9A530029EF47 /* AppDelegate.swift */, + F69200111CDB9A530029EF47 /* ViewController.swift */, + F66B80311D86BE36006DDD16 /* ListTableViewCell.swift */, + F66B80321D86BE36006DDD16 /* ListTableViewCell.xib */, + F6AA6C3E1CDC80DD00723622 /* WebViewController.swift */, + F6AA6C3F1CDC80DD00723622 /* WebViewController.xib */, + F636136D1CDD9C9100AA9AF7 /* Custom */, + F69200131CDB9A530029EF47 /* Main.storyboard */, + F69200181CDB9A530029EF47 /* LaunchScreen.storyboard */, + F69200161CDB9A530029EF47 /* Assets.xcassets */, + F692001B1CDB9A530029EF47 /* Info.plist */, + ); + path = ESPullToRefreshExample; + sourceTree = ""; + }; + F6AE472F1CE0628B0006C017 /* WeChat */ = { + isa = PBXGroup; + children = ( + F6AE47321CE062F00006C017 /* WCRefreshHeaderAnimator.swift */, + F6AE47361CE089480006C017 /* WeChatTableHeaderView.swift */, + ); + path = WeChat; + sourceTree = ""; + }; + F6C5F2F91DD31C1A001DEA80 /* CollectionView */ = { + isa = PBXGroup; + children = ( + F6C5F2FA1DD31C1A001DEA80 /* CollectionViewController.swift */, + ); + path = CollectionView; + sourceTree = ""; + }; + F6E433C21D1BB34800307E8A /* TextView */ = { + isa = PBXGroup; + children = ( + F6E433C31D1BB36700307E8A /* TextViewController.swift */, + ); + path = TextView; + sourceTree = ""; + }; + F6F63A3D1D3C75000017F621 /* Day */ = { + isa = PBXGroup; + children = ( + F6F63A3E1D3C75750017F621 /* ESRefreshDayHeaderAnimator.swift */, + ); + name = Day; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + F690772A1D0D0AE300BE91FE /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F69077301D0D0AE300BE91FE /* ESPullToRefresh.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + F690772C1D0D0AE300BE91FE /* ESPullToRefresh */ = { + isa = PBXNativeTarget; + buildConfigurationList = F69077321D0D0AE300BE91FE /* Build configuration list for PBXNativeTarget "ESPullToRefresh" */; + buildPhases = ( + F69077281D0D0AE300BE91FE /* Sources */, + F69077291D0D0AE300BE91FE /* Frameworks */, + F690772A1D0D0AE300BE91FE /* Headers */, + F690772B1D0D0AE300BE91FE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ESPullToRefresh; + productName = ESPullToRefresh; + productReference = F690772D1D0D0AE300BE91FE /* ESPullToRefresh.framework */; + productType = "com.apple.product-type.framework"; + }; + F692000B1CDB9A530029EF47 /* ESPullToRefreshExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = F69200341CDB9A530029EF47 /* Build configuration list for PBXNativeTarget "ESPullToRefreshExample" */; + buildPhases = ( + F69200081CDB9A530029EF47 /* Sources */, + F69200091CDB9A530029EF47 /* Frameworks */, + F692000A1CDB9A530029EF47 /* Resources */, + F69076351D0D059B00BE91FE /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ESPullToRefreshExample; + productName = ESPullToRefreshExample; + productReference = F692000C1CDB9A530029EF47 /* ESRefresh.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F69200041CDB9A530029EF47 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0730; + LastUpgradeCheck = 0800; + ORGANIZATIONNAME = "egg swift"; + TargetAttributes = { + F690772C1D0D0AE300BE91FE = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + }; + F692000B1CDB9A530029EF47 = { + CreatedOnToolsVersion = 7.3; + DevelopmentTeam = 86WDX5W5SP; + LastSwiftMigration = 0800; + }; + }; + }; + buildConfigurationList = F69200071CDB9A530029EF47 /* Build configuration list for PBXProject "ESPullToRefreshExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = F69200031CDB9A530029EF47; + productRefGroup = F692000D1CDB9A530029EF47 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F692000B1CDB9A530029EF47 /* ESPullToRefreshExample */, + F690772C1D0D0AE300BE91FE /* ESPullToRefresh */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + F690772B1D0D0AE300BE91FE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F6C5F2FC1DD32225001DEA80 /* icon_pull_to_refresh_arrow@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F692000A1CDB9A530029EF47 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F692001A1CDB9A530029EF47 /* LaunchScreen.storyboard in Resources */, + F6AB6EA61D6AF82100AC33BE /* ESRefreshTableViewCell.xib in Resources */, + F69200171CDB9A530029EF47 /* Assets.xcassets in Resources */, + F69200151CDB9A530029EF47 /* Main.storyboard in Resources */, + F66B80341D86BE36006DDD16 /* ListTableViewCell.xib in Resources */, + F6AA6C411CDC80DD00723622 /* WebViewController.xib in Resources */, + F6C5F2F71DD2C8C7001DEA80 /* ESPhotoTableViewCell.xib in Resources */, + F69077111D0D0A7F00BE91FE /* icon_pull_to_refresh_arrow@2x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + F69077281D0D0AE300BE91FE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F69077351D0D0AF400BE91FE /* ESRefreshFooterAnimator.swift in Sources */, + F69077361D0D0AF400BE91FE /* ESRefreshHeaderAnimator.swift in Sources */, + F69077381D0D0AF400BE91FE /* ESPullToRefresh+Manager.swift in Sources */, + F69077391D0D0AF400BE91FE /* ESPullToRefresh.swift in Sources */, + F690773A1D0D0AF400BE91FE /* ESRefreshAnimator.swift in Sources */, + F690773B1D0D0AF400BE91FE /* ESRefreshComponent.swift in Sources */, + F690773C1D0D0AF400BE91FE /* ESRefreshProtocol.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F69200081CDB9A530029EF47 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F6C5F2F61DD2C8C7001DEA80 /* ESPhotoTableViewCell.swift in Sources */, + F690771B1D0D0A7F00BE91FE /* ESRefreshAnimator.swift in Sources */, + F63613721CDD9CD900AA9AF7 /* MTRefreshFooterAnimator.swift in Sources */, + F69077211D0D0A7F00BE91FE /* ESRefreshProtocol.swift in Sources */, + F6AB6EA51D6AF82100AC33BE /* ESRefreshTableViewCell.swift in Sources */, + F6AA6C401CDC80DD00723622 /* WebViewController.swift in Sources */, + F690770B1D0D0A7F00BE91FE /* ESRefreshFooterAnimator.swift in Sources */, + F6AE47371CE089480006C017 /* WeChatTableHeaderView.swift in Sources */, + F6F63A3F1D3C75750017F621 /* ESRefreshDayHeaderAnimator.swift in Sources */, + F64456001D65A2F10094D58E /* ESRefreshTableViewController.swift in Sources */, + F6C5F2FB1DD31C1A001DEA80 /* CollectionViewController.swift in Sources */, + F6AE47331CE062F00006C017 /* WCRefreshHeaderAnimator.swift in Sources */, + F69077141D0D0A7F00BE91FE /* ESPullToRefresh+Manager.swift in Sources */, + F690771E1D0D0A7F00BE91FE /* ESRefreshComponent.swift in Sources */, + F66B80331D86BE36006DDD16 /* ListTableViewCell.swift in Sources */, + F69200121CDB9A530029EF47 /* ViewController.swift in Sources */, + F63613701CDD9CCD00AA9AF7 /* MTRefreshHeaderAnimator.swift in Sources */, + F69077181D0D0A7F00BE91FE /* ESPullToRefresh.swift in Sources */, + F690770E1D0D0A7F00BE91FE /* ESRefreshHeaderAnimator.swift in Sources */, + F6E433C41D1BB36700307E8A /* TextViewController.swift in Sources */, + F69200101CDB9A530029EF47 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + F69200131CDB9A530029EF47 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + F69200141CDB9A530029EF47 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + F69200181CDB9A530029EF47 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + F69200191CDB9A530029EF47 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + F69077331D0D0AE300BE91FE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = ESPullToRefresh/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.eggswift.ESPullToRefresh; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + F69077341D0D0AE300BE91FE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = ESPullToRefresh/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.eggswift.ESPullToRefresh; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + F69200321CDB9A530029EF47 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F69200331CDB9A530029EF47 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + F69200351CDB9A530029EF47 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + DEVELOPMENT_TEAM = 86WDX5W5SP; + INFOPLIST_FILE = ESPullToRefreshExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.eggswift.ESPullToRefreshExample; + PRODUCT_NAME = ESRefresh; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + F69200361CDB9A530029EF47 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + DEVELOPMENT_TEAM = 86WDX5W5SP; + INFOPLIST_FILE = ESPullToRefreshExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.eggswift.ESPullToRefreshExample; + PRODUCT_NAME = ESRefresh; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + F69077321D0D0AE300BE91FE /* Build configuration list for PBXNativeTarget "ESPullToRefresh" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F69077331D0D0AE300BE91FE /* Debug */, + F69077341D0D0AE300BE91FE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F69200071CDB9A530029EF47 /* Build configuration list for PBXProject "ESPullToRefreshExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F69200321CDB9A530029EF47 /* Debug */, + F69200331CDB9A530029EF47 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F69200341CDB9A530029EF47 /* Build configuration list for PBXNativeTarget "ESPullToRefreshExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F69200351CDB9A530029EF47 /* Debug */, + F69200361CDB9A530029EF47 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = F69200041CDB9A530029EF47 /* Project object */; +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..e97b36e --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj/xcshareddata/xcschemes/ESPullToRefresh.xcscheme b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj/xcshareddata/xcschemes/ESPullToRefresh.xcscheme new file mode 100644 index 0000000..bba3e36 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample.xcodeproj/xcshareddata/xcschemes/ESPullToRefresh.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/AppDelegate.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/AppDelegate.swift new file mode 100644 index 0000000..7f43e2f --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/AppDelegate.swift @@ -0,0 +1,47 @@ +// +// AppDelegate.swift +// ESPullToRefreshExample +// +// Created by egg swift on 16/5/5. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + + +} + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..3f8533c --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,110 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-Notification-1.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-Notification@2x-1.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Small@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-Spotlight-40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-Spotlight-40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-Notification.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-Notification@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-Small.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-Small@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-Spotlight-40.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-Spotlight-40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "icon@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png new file mode 100644 index 0000000..3b1271a Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png new file mode 100644 index 0000000..2539427 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-76.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-76.png new file mode 100644 index 0000000..22b6b05 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-76.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png new file mode 100644 index 0000000..c49423a Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification-1.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification-1.png new file mode 100644 index 0000000..ae695d6 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification-1.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification.png new file mode 100644 index 0000000..ae695d6 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x-1.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x-1.png new file mode 100644 index 0000000..e98f770 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x-1.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png new file mode 100644 index 0000000..f3dc1fa Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Notification@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Small.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Small.png new file mode 100644 index 0000000..f9c178e Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Small.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png new file mode 100644 index 0000000..29d1568 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png new file mode 100644 index 0000000..8aa9b67 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png new file mode 100644 index 0000000..f3dc1fa Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png new file mode 100644 index 0000000..935db19 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png new file mode 100644 index 0000000..3b1271a Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/icon@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/icon@2x.png new file mode 100644 index 0000000..4414d16 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/AppIcon.appiconset/icon@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon.imageset/Contents.json new file mode 100644 index 0000000..54ba36a --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon.imageset/icon@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon.imageset/icon@2x.png new file mode 100644 index 0000000..b67ec1a Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon.imageset/icon@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon_wechat.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon_wechat.imageset/Contents.json new file mode 100644 index 0000000..de48ea5 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon_wechat.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon_wechat@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon_wechat.imageset/icon_wechat@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon_wechat.imageset/icon_wechat@2x.png new file mode 100644 index 0000000..f64e816 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/icon_wechat.imageset/icon_wechat@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_1.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_1.imageset/Contents.json new file mode 100644 index 0000000..70a3c21 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_pull_animation_1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_1.imageset/icon_pull_animation_1.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_1.imageset/icon_pull_animation_1.png new file mode 100644 index 0000000..d74be32 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_1.imageset/icon_pull_animation_1.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_2.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_2.imageset/Contents.json new file mode 100644 index 0000000..8f4263d --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_pull_animation_2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_2.imageset/icon_pull_animation_2.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_2.imageset/icon_pull_animation_2.png new file mode 100644 index 0000000..8217330 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_2.imageset/icon_pull_animation_2.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_3.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_3.imageset/Contents.json new file mode 100644 index 0000000..7489f61 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_pull_animation_3.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_3.imageset/icon_pull_animation_3.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_3.imageset/icon_pull_animation_3.png new file mode 100644 index 0000000..6aeddef Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_3.imageset/icon_pull_animation_3.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_4.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_4.imageset/Contents.json new file mode 100644 index 0000000..39a68cc --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_4.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_pull_animation_4.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_4.imageset/icon_pull_animation_4.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_4.imageset/icon_pull_animation_4.png new file mode 100644 index 0000000..0497365 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_4.imageset/icon_pull_animation_4.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_5.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_5.imageset/Contents.json new file mode 100644 index 0000000..6cf4764 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_5.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_pull_animation_5.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_5.imageset/icon_pull_animation_5.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_5.imageset/icon_pull_animation_5.png new file mode 100644 index 0000000..4e9f011 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_pull_animation_5.imageset/icon_pull_animation_5.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_1.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_1.imageset/Contents.json new file mode 100644 index 0000000..c5589e7 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_shake_animation_1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_1.imageset/icon_shake_animation_1.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_1.imageset/icon_shake_animation_1.png new file mode 100644 index 0000000..834ca0c Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_1.imageset/icon_shake_animation_1.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_2.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_2.imageset/Contents.json new file mode 100644 index 0000000..ba95e88 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_shake_animation_2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_2.imageset/icon_shake_animation_2.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_2.imageset/icon_shake_animation_2.png new file mode 100644 index 0000000..0c8e231 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_2.imageset/icon_shake_animation_2.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_3.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_3.imageset/Contents.json new file mode 100644 index 0000000..c05f8c0 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_shake_animation_3.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_3.imageset/icon_shake_animation_3.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_3.imageset/icon_shake_animation_3.png new file mode 100644 index 0000000..ba90afe Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_3.imageset/icon_shake_animation_3.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_4.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_4.imageset/Contents.json new file mode 100644 index 0000000..71b4db3 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_4.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_shake_animation_4.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_4.imageset/icon_shake_animation_4.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_4.imageset/icon_shake_animation_4.png new file mode 100644 index 0000000..19e88a3 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_4.imageset/icon_shake_animation_4.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_5.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_5.imageset/Contents.json new file mode 100644 index 0000000..d80956a --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_5.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_shake_animation_5.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_5.imageset/icon_shake_animation_5.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_5.imageset/icon_shake_animation_5.png new file mode 100644 index 0000000..475e024 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_5.imageset/icon_shake_animation_5.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_6.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_6.imageset/Contents.json new file mode 100644 index 0000000..0355f45 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_6.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_shake_animation_6.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_6.imageset/icon_shake_animation_6.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_6.imageset/icon_shake_animation_6.png new file mode 100644 index 0000000..b4fe091 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_6.imageset/icon_shake_animation_6.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_7.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_7.imageset/Contents.json new file mode 100644 index 0000000..c9ca331 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_7.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_shake_animation_7.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_7.imageset/icon_shake_animation_7.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_7.imageset/icon_shake_animation_7.png new file mode 100644 index 0000000..edd3e54 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_7.imageset/icon_shake_animation_7.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_8.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_8.imageset/Contents.json new file mode 100644 index 0000000..f15e847 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_8.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_shake_animation_8.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_8.imageset/icon_shake_animation_8.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_8.imageset/icon_shake_animation_8.png new file mode 100644 index 0000000..b4fe091 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/meituan/icon_shake_animation_8.imageset/icon_shake_animation_8.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/network.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/network.imageset/Contents.json new file mode 100644 index 0000000..d1dbb70 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/network.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "network@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/network.imageset/network@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/network.imageset/network@2x.png new file mode 100644 index 0000000..8476785 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/network.imageset/network@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_1.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_1.imageset/Contents.json new file mode 100644 index 0000000..d6fc5e1 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_1@2x.JPG", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_1.imageset/Photo_Lofter_1@2x.JPG b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_1.imageset/Photo_Lofter_1@2x.JPG new file mode 100644 index 0000000..c80a9bc Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_1.imageset/Photo_Lofter_1@2x.JPG differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_2.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_2.imageset/Contents.json new file mode 100644 index 0000000..f853d8e --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_2@2x.JPG", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_2.imageset/Photo_Lofter_2@2x.JPG b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_2.imageset/Photo_Lofter_2@2x.JPG new file mode 100644 index 0000000..e94d934 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_2.imageset/Photo_Lofter_2@2x.JPG differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_3.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_3.imageset/Contents.json new file mode 100644 index 0000000..919f576 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_3@2x.JPG", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_3.imageset/Photo_Lofter_3@2x.JPG b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_3.imageset/Photo_Lofter_3@2x.JPG new file mode 100644 index 0000000..2be47c8 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_3.imageset/Photo_Lofter_3@2x.JPG differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_4.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_4.imageset/Contents.json new file mode 100644 index 0000000..d34da9f --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_4.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_4@2x.JPG", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_4.imageset/Photo_Lofter_4@2x.JPG b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_4.imageset/Photo_Lofter_4@2x.JPG new file mode 100644 index 0000000..c3e1f51 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_4.imageset/Photo_Lofter_4@2x.JPG differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_5.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_5.imageset/Contents.json new file mode 100644 index 0000000..7faf7a9 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_5.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_5@2x.JPG", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_5.imageset/Photo_Lofter_5@2x.JPG b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_5.imageset/Photo_Lofter_5@2x.JPG new file mode 100644 index 0000000..f8b36c6 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_5.imageset/Photo_Lofter_5@2x.JPG differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_6.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_6.imageset/Contents.json new file mode 100644 index 0000000..4a07d43 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_6.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_6@2x.JPG", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_6.imageset/Photo_Lofter_6@2x.JPG b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_6.imageset/Photo_Lofter_6@2x.JPG new file mode 100644 index 0000000..20af354 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_6.imageset/Photo_Lofter_6@2x.JPG differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_7.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_7.imageset/Contents.json new file mode 100644 index 0000000..15260ac --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_7.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_7@2x.JPG", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_7.imageset/Photo_Lofter_7@2x.JPG b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_7.imageset/Photo_Lofter_7@2x.JPG new file mode 100644 index 0000000..07cd9a8 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_7.imageset/Photo_Lofter_7@2x.JPG differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_8.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_8.imageset/Contents.json new file mode 100644 index 0000000..36a6b38 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_8.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_8@2x.JPG", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_8.imageset/Photo_Lofter_8@2x.JPG b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_8.imageset/Photo_Lofter_8@2x.JPG new file mode 100644 index 0000000..a20a241 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_8.imageset/Photo_Lofter_8@2x.JPG differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_9.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_9.imageset/Contents.json new file mode 100644 index 0000000..2e0ef35 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_9.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_9@2x.JPG", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_9.imageset/Photo_Lofter_9@2x.JPG b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_9.imageset/Photo_Lofter_9@2x.JPG new file mode 100644 index 0000000..99fff26 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_9.imageset/Photo_Lofter_9@2x.JPG differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Info.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Info.imageset/Contents.json new file mode 100644 index 0000000..a249e4c --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Info.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_Info@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Info.imageset/Photo_Lofter_Info@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Info.imageset/Photo_Lofter_Info@2x.png new file mode 100644 index 0000000..e1fcf4e Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Info.imageset/Photo_Lofter_Info@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Tab.imageset/Contents.json b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Tab.imageset/Contents.json new file mode 100644 index 0000000..52db033 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Tab.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Photo_Lofter_Tab@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Tab.imageset/Photo_Lofter_Tab@2x.png b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Tab.imageset/Photo_Lofter_Tab@2x.png new file mode 100644 index 0000000..9c13c47 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Assets.xcassets/photo/lofter/Photo_Lofter_Tab.imageset/Photo_Lofter_Tab@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Base.lproj/LaunchScreen.storyboard b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..5bc8b47 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Base.lproj/Main.storyboard b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Base.lproj/Main.storyboard new file mode 100644 index 0000000..1e3ffb3 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Base.lproj/Main.storyboard @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/CollectionView/CollectionViewController.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/CollectionView/CollectionViewController.swift new file mode 100644 index 0000000..80ec6eb --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/CollectionView/CollectionViewController.swift @@ -0,0 +1,129 @@ + +// File.swift +// ESPullToRefreshExample +// +// Created by Meng Ye on 2016/11/2. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +class CollectionViewController: UIViewController { + internal var list: [String] = [] + + private let collectionView: UICollectionView = { + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.alwaysBounceVertical = true + collectionView.register(DemoCollectionViewCell.self, forCellWithReuseIdentifier: "DemoCell") + collectionView.contentInset = UIEdgeInsetsMake(12.0, 15.0, 0, 15.0) + collectionView.backgroundColor = .white + return collectionView + }() + + override func viewDidLoad() { + super.viewDidLoad() + + setupViews() + } + + // MARK: Private Helper Methods + private func setupViews() { + self.collectionView.dataSource = self + + let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout + self.view.addSubview(collectionView) + let itemWidth = (UIScreen.main.bounds.width - 40) / 3 + layout.itemSize = CGSize(width: itemWidth, height: itemWidth) + layout.minimumLineSpacing = 5.0 + layout.minimumInteritemSpacing = 5.0 + layout.scrollDirection = .vertical + + let viewsDict = [ + "collectionView": collectionView + ] + let vflDict = [ + "H:|-0-[collectionView]-0-|", + "V:|-0-[collectionView]-0-|" + ] + self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: vflDict[0] as String, options: [], metrics: nil, views: viewsDict)) + self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: vflDict[1] as String, options: [], metrics: nil, views: viewsDict)) + + // add pull to refresh + self.collectionView.es_addPullToRefresh { + self.loadData() + } + self.collectionView.es_startPullToRefresh() + self.collectionView.es_addInfiniteScrolling { + self.delay(time: 2) { + for item in 21...40 { + self.list.append(String(item)) + } + self.collectionView.es_stopLoadingMore() + self.collectionView.reloadData() + } + } + } + + func delay(time: TimeInterval, completionHandler: @escaping ()-> Void) { + DispatchQueue.main.asyncAfter(deadline: .now() + time) { + completionHandler() + } + } + + private func loadData() { + delay(time: 2) { + self.list = [] + for item in 0...20 { + self.list.append(String(item)) + } + self.collectionView.es_stopPullToRefresh() + self.collectionView.reloadData() + } + } +} + +// MARK: UICollectionViewDataSource +extension CollectionViewController: UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return self.list.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DemoCell", for: indexPath) as! DemoCollectionViewCell + cell.configureCell(title: self.list[indexPath.row]) + + return cell + } +} + +// MARK: DemoCollectionViewCell +class DemoCollectionViewCell: UICollectionViewCell { + lazy var label: UILabel = { + let label = UILabel() + label.font = UIFont(name: "HelveticaNeue-Bold", size: 15) + label.translatesAutoresizingMaskIntoConstraints = false + label.textAlignment = .center + label.textColor = .black + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + let viewsDict = ["label" : label] + let vflDict = ["H:|-0-[label]-0-|", + "V:|-0-[label]-0-|"] + contentView.addSubview(label) + contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: vflDict[0] as String, options: [], metrics: nil, views: viewsDict)) + contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: vflDict[1] as String, options: [], metrics: nil, views: viewsDict)) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configureCell(title: String) { + label.text = title + } +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Day/ESRefreshDayHeaderAnimator.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Day/ESRefreshDayHeaderAnimator.swift new file mode 100644 index 0000000..d8a3f17 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Day/ESRefreshDayHeaderAnimator.swift @@ -0,0 +1,118 @@ +// +// ESRefreshDayHeaderAnimator.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/7/18. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +public class ESRefreshDayHeaderAnimator: UIView, ESRefreshProtocol, ESRefreshAnimatorProtocol { + public var insets: UIEdgeInsets = UIEdgeInsets.zero + public var view: UIView { return self } + public var trigger: CGFloat = 120.0 + public var executeIncremental: CGFloat = 120.0 + public var state: ESRefreshViewState = .pullToRefresh + + private var percent: CGFloat = 0 + private var isDay: Bool = true { + didSet { + self.dayImageView.isHidden = !isDay + self.nightImageView.isHidden = isDay + } + } + private lazy var timer: Timer! = { + let timer = Timer.scheduledTimer(timeInterval: 0.002, target: self, selector: #selector(ESRefreshDayHeaderAnimator.timerAction), userInfo: nil, repeats: true) + return timer + }() + + private let backImageView: UIImageView = { + let imageView = UIImageView.init() + imageView.image = UIImage.init(named: "icon_pull_to_refresh_back") + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + return imageView + }() + private let dayImageView: UIImageView = { + let imageView = UIImageView.init() + imageView.image = UIImage.init(named: "icon_pull_to_refresh_day") + imageView.sizeToFit() + return imageView + }() + private let nightImageView: UIImageView = { + let imageView = UIImageView.init() + imageView.image = UIImage.init(named: "icon_pull_to_refresh_night") + imageView.sizeToFit() + imageView.isHidden = true + return imageView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + self.addSubview(backImageView) + self.addSubview(dayImageView) + self.addSubview(nightImageView) + } + + public required init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func refreshAnimationBegin(view: ESRefreshComponent) { + self.timer.fire() + percent = 0.5 + } + + public func refreshAnimationEnd(view: ESRefreshComponent) { + self.timer.invalidate() + self.timer = nil + isDay = true + percent = 0.5 + } + + public func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) { + let buttom: CGFloat = 2.0 + let top: CGFloat = 12.0 + let p = min(1.0, max(0.0, progress)) + let w = self.bounds.size.width + let h = self.bounds.size.height + let size = dayImageView.image?.size ?? CGSize.zero + self.dayImageView.center = CGPoint.init(x: w / 2.0, y: (h - buttom - size.height / 2.0) - (h - top - buttom - size.height) * p) + } + + public func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) { + + } + + public func timerAction() { + percent += 0.001 + if percent >= 1.0 { + percent = 0.0 + isDay = !isDay + } + self.animateAction() + } + + public func animateAction() { + let p = percent < 0.25 ? percent * 2 : percent > 0.75 ? (0.5 + (percent - 0.75) * 2) : 0.5 + + let top: CGFloat = 12.0 + let buttom: CGFloat = 16.0 + let size = dayImageView.image?.size ?? CGSize.zero + let w = self.bounds.size.width + let h = self.bounds.size.height + let x = p * w + let y = top + (size.height / 2.0) + (h - top - buttom - size.height) * (1 - CGFloat(sin(CGFloat(M_PI) * p))) + if isDay { + let colorP = p < 0.5 ? (0.5 + p) : (p == 0.5 ? 1.0 : (0.5 + 1.0 - p)) + self.backgroundColor = UIColor.init(white: colorP, alpha: 1.0) + self.dayImageView.center = CGPoint.init(x: x, y: y) + } else { + let colorP = p < 0.5 ? (0.5 - p) : (p == 0.5 ? 0.0 : (p - 0.5)) + self.backgroundColor = UIColor.init(white: colorP, alpha: 1.0) + self.nightImageView.center = CGPoint.init(x: x, y: y) + } + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Day/ESRefreshDayTableViewController.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Day/ESRefreshDayTableViewController.swift new file mode 100644 index 0000000..3dc0c84 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Day/ESRefreshDayTableViewController.swift @@ -0,0 +1,95 @@ +// +// ESRefreshDayTableViewController.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/7/18. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +public class ESRefreshDayTableViewController: UITableViewController { + var array = [String]() + var page = 1 + + override public func viewDidLoad() { + super.viewDidLoad() + self.view.translatesAutoresizingMaskIntoConstraints = false + self.view.backgroundColor = UIColor.init(red: 240/255.0, green: 239/255.0, blue: 237/255.0, alpha: 1.0) + self.tableView.register(UINib.init(nibName: "DefaultTableViewCell", bundle: nil), forCellReuseIdentifier: "DefaultTableViewCell") + + for _ in 1...8{ + self.array.append(" ") + } + + self.tableView.es_addPullToRefresh(animator: ESRefreshDayHeaderAnimator.init(frame: CGRect.zero)) { + [weak self] in + let minseconds = 3.0 * Double(NSEC_PER_SEC) + let dtime = DispatchTime.now(dispatch_time_t(DispatchTime.now), Int64(minseconds)) + dispatch_after(dtime, DispatchQueue.main , { + self?.page = 1 + self?.array.removeAll() + for _ in 1...8{ + self?.array.append(" ") + } + self?.tableView.reloadData() + self?.tableView.es_stopPullToRefresh(completion: true) + }) + } + self.tableView.refreshIdentifier = NSStringFromClass(DefaultTableViewController) // Set refresh identifier + self.tableView.expriedTimeInterval = 20.0 // 20 second alive. + + self.tableView.es_addInfiniteScrolling(animator: MTRefreshFooterAnimator.init(frame: CGRect.zero)) { + [weak self] in + let minseconds = 3.0 * Double(NSEC_PER_SEC) + let dtime = DispatchTime.now(dispatch_time_t(DispatchTime.now), Int64(minseconds)) + dispatch_after(dtime, DispatchQueue.main , { + self?.page += 1 + if self?.page <= 3 { + for _ in 1...8{ + self?.array.append(" ") + } + self?.tableView.reloadData() + self?.tableView.es_stopLoadingMore() + } else { + self?.tableView.es_noticeNoMoreData() + } + }) + } + } + + override public func viewDidAppear(animated: Bool) { + super.viewDidAppear(animated) + self.tableView.es_autoPullToRefresh() + } + + // MARK: - Table view data source + override public func numberOfSectionsInTableView(tableView: UITableView) -> Int { + return 1 + } + + override public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return array.count + } + + override public func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { + return 100.0 + } + + override public func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return CGFloat.leastNormalMagnitude + } + + override public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "DefaultTableViewCell", for: indexPath as IndexPath) + cell.backgroundColor = UIColor.init(white: 250.0 / 255.0, alpha: 1.0) + return cell + } + + override public func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { + tableView.deselectRow(at: indexPath as IndexPath, animated: true) + let vc = WebViewController.init() + self.navigationController?.pushViewController(vc, animated: true) + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESPhotoTableViewCell.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESPhotoTableViewCell.swift new file mode 100644 index 0000000..1e5690f --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESPhotoTableViewCell.swift @@ -0,0 +1,32 @@ +// +// ESPhotoTableViewCell.swift +// ESPullToRefreshExample +// +// Created by lihao on 2016/11/9. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +class ESPhotoTableViewCell: UITableViewCell { + + @IBOutlet weak var indexLabel: UILabel! + @IBOutlet weak var photoImageView: UIImageView! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + func updateContent(indexPath: IndexPath) { + let name = String.init(format: "Photo_Lofter_%d", (indexPath.row) % 9 + 1) + self.photoImageView.image = UIImage.init(named: name) + self.indexLabel.text = String.init(format: "Section: %d Row: %d", indexPath.section, indexPath.row) + } + + override func setHighlighted(_ highlighted: Bool, animated: Bool) { + super.setHighlighted(highlighted, animated: animated) + self.photoImageView.alpha = highlighted ? 0.8 : 1.0 + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESPhotoTableViewCell.xib b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESPhotoTableViewCell.xib new file mode 100644 index 0000000..4d555f3 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESPhotoTableViewCell.xib @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESRefreshTableViewCell.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESRefreshTableViewCell.swift new file mode 100644 index 0000000..b39fccb --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESRefreshTableViewCell.swift @@ -0,0 +1,22 @@ +// +// DefaultTableViewCell.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/5/6. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +class ESRefreshTableViewCell: UITableViewCell { + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setHighlighted(_ highlighted: Bool, animated: Bool) { + super.setHighlighted(highlighted, animated: animated) + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESRefreshTableViewCell.xib b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESRefreshTableViewCell.xib new file mode 100644 index 0000000..eeb6e78 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESRefreshTableViewCell.xib @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESRefreshTableViewController.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESRefreshTableViewController.swift new file mode 100644 index 0000000..1067e24 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/ESRefreshTableViewController.swift @@ -0,0 +1,142 @@ +// +// ESRefreshTableViewController.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/8/18. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +public class ESRefreshTableViewController: UITableViewController { + + public var array = [String]() + public var page = 1 + public var type: ESRefreshExampleType = .defaulttype + + public override init(style: UITableViewStyle) { + super.init(style: style) + for num in 1...8{ + if num % 2 == 0 && arc4random() % 4 == 0 { + self.array.append("info") + } else { + self.array.append("photo") + } + } + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public override func viewDidLoad() { + super.viewDidLoad() + + self.tableView.backgroundColor = UIColor.init(red: 244.0 / 255.0, green: 245.0 / 255.0, blue: 245.0 / 255.0, alpha: 1.0) + + self.tableView.register(UINib.init(nibName: "ESRefreshTableViewCell", bundle: nil), forCellReuseIdentifier: "ESRefreshTableViewCell") + self.tableView.register(UINib.init(nibName: "ESPhotoTableViewCell", bundle: nil), forCellReuseIdentifier: "ESPhotoTableViewCell") + self.tableView.rowHeight = UITableViewAutomaticDimension + self.tableView.estimatedRowHeight = 560 + self.tableView.separatorStyle = .none + self.tableView.separatorColor = UIColor.clear + + var header: ESRefreshProtocol & ESRefreshAnimatorProtocol + var footer: ESRefreshProtocol & ESRefreshAnimatorProtocol + switch type { + case .meituan: + header = MTRefreshHeaderAnimator.init(frame: CGRect.zero) + footer = MTRefreshFooterAnimator.init(frame: CGRect.zero) + case .wechat: + header = WCRefreshHeaderAnimator.init(frame: CGRect.zero) + footer = ESRefreshFooterAnimator.init(frame: CGRect.zero) + default: + header = ESRefreshHeaderAnimator.init(frame: CGRect.zero) + footer = ESRefreshFooterAnimator.init(frame: CGRect.zero) + break + } + + self.tableView.es_addPullToRefresh(animator: header) { [weak self] in + self?.refresh() + } + self.tableView.es_addInfiniteScrolling(animator: footer) { [weak self] in + self?.loadMore() + } + self.tableView.refreshIdentifier = String.init(describing: type) + self.tableView.expriedTimeInterval = 20.0 + + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + self.tableView.es_autoPullToRefresh() + } + } + + private func refresh() { + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + self.page = 1 + self.array.removeAll() + for num in 1...8{ + if num % 2 == 0 && arc4random() % 4 == 0 { + self.array.append("info") + } else { + self.array.append("photo") + } + } + self.tableView.reloadData() + self.tableView.es_stopPullToRefresh() + } + } + + private func loadMore() { + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + self.page += 1 + if self.page <= 3 { + for num in 1...8{ + if num % 2 == 0 && arc4random() % 4 == 0 { + self.array.append("info") + } else { + self.array.append("photo") + } + } + self.tableView.reloadData() + self.tableView.es_stopLoadingMore() + } else { + self.tableView.es_noticeNoMoreData() + } + } + } + + // MARK: - Table view data source + public override func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return array.count + } + + public override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return CGFloat.leastNormalMagnitude + } + + public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + var cell: UITableViewCell! + let string = self.array[indexPath.row] + if string == "info" { + cell = tableView.dequeueReusableCell(withIdentifier: "ESRefreshTableViewCell", for: indexPath as IndexPath) + } else if string == "photo" { + cell = tableView.dequeueReusableCell(withIdentifier: "ESPhotoTableViewCell", for: indexPath as IndexPath) + if let cell = cell as? ESPhotoTableViewCell { + cell.updateContent(indexPath: indexPath) + } + } else { + cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath as IndexPath) + } + return cell + } + + public override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath as IndexPath, animated: true) + self.navigationController?.pushViewController(WebViewController.init(), animated: true) + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Meituan/MTRefreshFooterAnimator.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Meituan/MTRefreshFooterAnimator.swift new file mode 100644 index 0000000..9954fe7 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Meituan/MTRefreshFooterAnimator.swift @@ -0,0 +1,102 @@ +// +// MTRefreshFooterAnimator.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/5/7. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +public class MTRefreshFooterAnimator: UIView, ESRefreshProtocol, ESRefreshAnimatorProtocol { + public let loadingMoreDescription: String = "Loading more" + public let noMoreDataDescription: String = "No more data" + public let loadingDescription: String = "Loading..." + + public var view: UIView { + return self + } + public var insets: UIEdgeInsets = UIEdgeInsets.zero + public var trigger: CGFloat = 48.0 + public var executeIncremental: CGFloat = 48.0 + public var state: ESRefreshViewState = .pullToRefresh + + private let topLine: UIView = { + let topLine = UIView.init(frame: CGRect.zero) + topLine.backgroundColor = UIColor.init(red: 214/255.0, green: 211/255.0, blue: 206/255.0, alpha: 1.0) + return topLine + }() + private let bottomLine: UIView = { + let bottomLine = UIView.init(frame: CGRect.zero) + bottomLine.backgroundColor = UIColor.init(red: 214/255.0, green: 211/255.0, blue: 206/255.0, alpha: 1.0) + return bottomLine + }() + private let titleLabel: UILabel = { + let label = UILabel.init(frame: CGRect.zero) + label.font = UIFont.systemFont(ofSize: 14.0) + label.textColor = UIColor.init(white: 160.0 / 255.0, alpha: 1.0) + label.textAlignment = .center + return label + }() + private let indicatorView: UIActivityIndicatorView = { + let indicatorView = UIActivityIndicatorView.init(activityIndicatorStyle: .gray) + indicatorView.isHidden = true + return indicatorView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + self.backgroundColor = UIColor.white + titleLabel.text = loadingMoreDescription + addSubview(titleLabel) + addSubview(indicatorView) + addSubview(topLine) + addSubview(bottomLine) + } + + public required init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func refreshAnimationBegin(view: ESRefreshComponent) { + indicatorView.startAnimating() + indicatorView.isHidden = false + } + + public func refreshAnimationEnd(view: ESRefreshComponent) { + indicatorView.stopAnimating() + indicatorView.isHidden = true + } + + public func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) { + // do nothing + } + + public func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) { + switch state { + case .refreshing : + titleLabel.text = loadingDescription + break + case .autoRefreshing : + titleLabel.text = loadingDescription + break + case .noMoreData: + titleLabel.text = noMoreDataDescription + break + default: + titleLabel.text = loadingMoreDescription + break + } + } + + public override func layoutSubviews() { + super.layoutSubviews() + let s = self.bounds.size + let w = s.width + let h = s.height + titleLabel.frame = self.bounds + indicatorView.center = CGPoint.init(x: 32.0, y: h / 2.0) + topLine.frame = CGRect.init(x: 0.0, y: 0.0, width: w, height: 0.5) + bottomLine.frame = CGRect.init(x: 0.0, y: h - 1.0, width: w, height: 1.0) + } +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Meituan/MTRefreshHeaderAnimator.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Meituan/MTRefreshHeaderAnimator.swift new file mode 100644 index 0000000..da7fefb --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Meituan/MTRefreshHeaderAnimator.swift @@ -0,0 +1,117 @@ +// +// MTRefreshHeaderAnimator.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/5/7. +// Copyright © 2016年 egg swift. All rights reserved. +// +// Icon from 美团 iOS app. +// https://itunes.apple.com/cn/app/mei-tuan-tuan-gou-tuan-gou/id423084029?mt=8 +// + +import UIKit + +public class MTRefreshHeaderAnimator: UIView, ESRefreshProtocol, ESRefreshAnimatorProtocol { + + public var insets: UIEdgeInsets = UIEdgeInsets.zero + public var view: UIView { return self } + public var duration: TimeInterval = 0.3 + public var trigger: CGFloat = 56.0 + public var executeIncremental: CGFloat = 56.0 + public var state: ESRefreshViewState = .pullToRefresh + + private let imageView: UIImageView = { + let imageView = UIImageView.init() + imageView.image = UIImage.init(named: "icon_pull_animation_1") + return imageView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + self.addSubview(imageView) + } + + public required init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func refreshAnimationBegin(view: ESRefreshComponent) { + imageView.center = self.center + UIView.animate(withDuration: 0.2, delay: 0, options: .curveLinear, animations: { + self.imageView.frame = CGRect.init(x: (self.bounds.size.width - 39.0) / 2.0, + y: self.bounds.size.height - 50.0, + width: 39.0, + height: 50.0) + + + }, completion: { (finished) in + var images = [UIImage]() + for idx in 1 ... 8 { + if let aImage = UIImage(named: "icon_shake_animation_\(idx)") { + images.append(aImage) + } + } + self.imageView.animationDuration = 0.5 + self.imageView.animationRepeatCount = 0 + self.imageView.animationImages = images + self.imageView.startAnimating() + }) + } + + public func refreshAnimationEnd(view: ESRefreshComponent) { + imageView.stopAnimating() + imageView.image = UIImage.init(named: "icon_pull_animation_1") + + UIView.animate(withDuration: 0.2, delay: 0, options: .curveLinear, animations: { + self.refresh(view: view, progressDidChange: 0.0) + }, completion: { (finished) in + }) + } + + public func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) { + let p = max(0.0, min(1.0, progress)) + imageView.frame = CGRect.init(x: (self.bounds.size.width - 39.0) / 2.0, + y: self.bounds.size.height - 50.0 * p, + width: 39.0, + height: 50.0 * p) + } + + public func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) { + guard self.state != state else { + return + } + self.state = state + + switch state { + case .pullToRefresh: + var images = [UIImage]() + for idx in 1 ... 5 { + if let aImage = UIImage(named: "icon_pull_animation_\((5 - idx + 1))") { + images.append(aImage) + } + } + imageView.animationDuration = 0.2 + imageView.animationRepeatCount = 1 + imageView.animationImages = images + imageView.image = UIImage.init(named: "icon_pull_animation_1") + imageView.startAnimating() + break + case .releaseToRefresh: + var images = [UIImage]() + for idx in 1 ... 5 { + if let aImage = UIImage(named: "icon_pull_animation_\(idx)") { + images.append(aImage) + } + } + imageView.animationDuration = 0.2 + imageView.animationRepeatCount = 1 + imageView.animationImages = images + imageView.image = UIImage.init(named: "icon_pull_animation_5") + imageView.startAnimating() + break + default: + break + } + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Meituan/MeituanTableViewController.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Meituan/MeituanTableViewController.swift new file mode 100644 index 0000000..2e17d45 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/Meituan/MeituanTableViewController.swift @@ -0,0 +1,92 @@ +// +// MeituanTableViewController.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/5/7. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +class MeituanTableViewController: UITableViewController { + var array = [String]() + var page = 1 + + override func viewDidLoad() { + super.viewDidLoad() + self.view.translatesAutoresizingMaskIntoConstraints = false + self.view.backgroundColor = UIColor.init(red: 240/255.0, green: 239/255.0, blue: 237/255.0, alpha: 1.0) + self.tableView.register(UINib.init(nibName: "DefaultTableViewCell", bundle: nil), forCellReuseIdentifier: "DefaultTableViewCell") + + for _ in 1...8{ + self.array.append(" ") + } + + let _ = self.tableView.es_addPullToRefresh(animator: MTRefreshHeaderAnimator.init(frame: CGRect.zero)) { + [weak self] in + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + self?.page = 1 + self?.array.removeAll() + for _ in 1...8{ + self?.array.append(" ") + } + self?.tableView.reloadData() + self?.tableView.es_stopPullToRefresh(completion: true) + } + } + self.tableView.refreshIdentifier = NSStringFromClass(DefaultTableViewController.self) // Set refresh identifier + self.tableView.expriedTimeInterval = 20.0 // 20 second alive. + + let _ = self.tableView.es_addInfiniteScrolling(animator: MTRefreshFooterAnimator.init(frame: CGRect.zero)) { + [weak self] in + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + self?.page += 1 + if self?.page ?? 0 <= 3 { + for _ in 1...8{ + self?.array.append(" ") + } + self?.tableView.reloadData() + self?.tableView.es_stopLoadingMore() + } else { + self?.tableView.es_noticeNoMoreData() + } + } + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + self.tableView.es_autoPullToRefresh() + } + + // MARK: - Table view data source + func numberOfSectionsInTableView(tableView: UITableView) -> Int { + return 1 + } + + func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return array.count + } + + func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { + return 100.0 + } + + func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return CGFloat.leastNormalMagnitude + } + + func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "DefaultTableViewCell", for: indexPath as IndexPath) + cell.backgroundColor = UIColor.init(white: 250.0 / 255.0, alpha: 1.0) + return cell + } + + func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { + tableView.deselectRow(at: indexPath as IndexPath, animated: true) + let vc = WebViewController.init() + self.navigationController?.pushViewController(vc, animated: true) + } + + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/TextView/TextViewController.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/TextView/TextViewController.swift new file mode 100644 index 0000000..c4065b4 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/TextView/TextViewController.swift @@ -0,0 +1,102 @@ +// +// TextViewController.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/6/23. +// Copyright © 2016年 egg swift. All rights reserved. +// Test from: '007 The Spy Who Loved Me' + +import UIKit + +class TextViewController: UIViewController { + var textView: UITextView! + var num: Int = 0 + var text1: String = "Part One: Me One: Scaredy Cat \n I WAS running away. I was running away from England, from my childhood, from the winter, from a sequence of untidy, unattractive love-affairs, from the few sticks of furniture and jumble of overworn clothes that my London life had collected around me; and I was running away from drabness, fustiness, snobbery, the claustrophobia of close horizons, and from my inability, although I am quite an attractive rat, to make headway in the rat-race. In fact I was running away from almost everything except the law. \n And I had run a very long way indeed-almost, exaggerating a bit, halfway round the world. In fact I had come all the way from London to The Dreamy Pines Motor Court, which is ten miles west of Lake George, the famous American tourist resort in the Adirondacks-that vast expanse of mountains, lakes, and pine forests which forms most of the northern territory of New York State. I had started on September the first, and it was now Friday the thirteenth of October. When I had left, the grimy little row of domesticated maples in my square had been green, or as green as any tree can be in London in August. Now, in the billion-strong army of pine trees that marched away northward toward the Canadian border, the real, wild maples flamed here and there like shrapnel-bursts. And I felt that I, or at any rate my skin, had changed just as much-from the grimy sallowness that had been the badge of my London life to the snap and color and sparkle of living out of doors and going to bed early and all those other dear dull things that had been part of my life in Quebec before it was decided that I must go to England and learn to be a \"lady.\" Very unfashionable, of course, this cherry-ripe, strength-through-joy complexion, and I had even stopped using lipstick and nail polish, but to me it had been like sloughing off a borrowed skin and getting back into my own, and I was childishly happy and pleased with myself whenever I looked in the mirror (that's another thing-I'll never say \"looking-glass\" again; I just don't have to any more) and found myself not wanting to paint a different face over my own. I'm not being smug about this. I was just running away from the person I'd been for the past five years. I wasn't particularly pleased with the person I was now, but I had hated and despised the other one, and I was glad to be rid of her face." + var text2: String = "\nStation WOKO (they might have dreamed up a grander call-sign!) in Albany, the capital of New York State and about fifty miles due south of where I was, announced that it was six o'clock. The weather report that followed included a storm warning with gale-force winds. The storm was moving down from the north and would hit Albany around eight p.m. That meant that I would be having a noisy night. I didn't mind. Storms don't frighten me, and although the nearest living soul, as far as I knew, was ten miles away up the not very good secondary road to Lake George, the thought of the pines that would soon be thrashing outside, the thunder and lightning and rain, made me already feel snug and warm and protected in anticipation. And alone! But above all alone! \"Loneliness becomes a lover, solitude a darling sin.\" Where had I read that? Who had written it? It was so exactly the way I felt, the way that, as a child, I had always felt until I had forced myself to \"get into the swim,\" \"be one of the crowd\"-a good sort, on the ball, hep. And what a hash I had made of \"togetherness\"! I shrugged the memory of failure away. Everyone doesn't have to live in a heap. Painters, writers, musicians are lonely people. So are statesmen and admirals and generals. But then, I added to be fair, so are criminals and lunatics. Let's just say, not to be too flattering, that true Individuals are lonely. It's not a virtue-the reverse, if anything. One ought to share and communicate if one is to be a useful member of the tribe. The fact that I was so much happier when I was alone was surely the sign of a faulty, a neurotic character. I had said this so often to myself in the past five years that now, that evening, I just shrugged my shoulders and, hugging my solitude to me, walked across the big lobby to the door and went out to have a last look at the evening." + var text3: String = "\nI hate pine trees. They are dark and stand very still and you can't shelter under them or climb them. They are very dirty, with a most un-treelike black dirt, and if you get this dirt mixed with their resin they make you really filthy. I find their jagged shapes vaguely inimical, and the way they mass so closely together gives me the impression of an army of spears barring my passage. The only good thing about them is their smell, and, when I can get hold of it, I use pine-needle essence in my bath. Here, in the Adirondacks, the endless vista of pine trees was positively sickening. They clothe every square yard of earth in the valleys and climb up to the top of every mountain so that the impression is of a spiky carpet spread to the horizon-an endless vista of rather stupid-looking green pyramids waiting to be cut down for matches and coat-hangers and copies of the New York Times." + var text4: String = "\nFive acres or so of these stupid trees had been cleared to build the motel, which is all that this place really was. \"Motel\" isn't a good word any longer. It has become smart to use \"Motor Court\" or \"Ranch Cabins\" ever since motels became associated with prostitution, gangsters, and murders, for all of which their anonymity and lack of supervision is a convenience. The site, touristwise, in the lingo of the trade, was a good one. There was this wandering secondary road through the forest, which was a pleasant alternative route between Lake George and Glen Falls to the south, and halfway along it was a small lake, cutely called Dreamy Waters, that was a traditional favorite with picnickers. It was on the southern shore of this lake that the motel had been built, its reception lobby facing the road, with, behind this main building, the rooms fanning out in a semicircle. There were forty rooms with kitchen, shower, and lavatory, and they all had some kind of view of the lake behind them. The whole construction and design was the latest thing-glazed pitch-pine frontages and pretty timber roofs all over knobbles, air-conditioning, television in every cabin, children's playground, swimming pool, golf range out over the lake with floating balls (fifty balls, one dollar)-all the gimmicks. Food? Cafeteria in the lobby, and grocery and liquor deliveries twice a day from Lake George. All this for ten dollars single and sixteen double. No wonder that, with around two hundred thousand dollars' capital outlay and a season lasting only from July the first to the beginning of October, or, so far as the NO VACANCY sign was concerned, from July fourteenth to Labor Day, the owners were finding the going hard. Or so those dreadful Phanceys had told me when they'd taken me on as receptionist for only thirty dollars a week plus keep. Thank heavens they were out of my hair! Song in my heart? There had been the whole heavenly choir at six o'clock that morning when their shiny station-wagon had disappeared down the road on their way to Glens Falls and then to Troy where the monsters came from. Mr. Phancey had made a last grab at me, and I hadn't been quick enough. His free hand had run like a fast lizard over my body before I had crunched my heel into his instep. He had let go then. When his contorted face had cleared, he said softly, \"All right, sex-box. Just see that you mind camp good until the boss comes to take over the keys tomorrow noon. Happy dreams tonight.\" Then he had grinned a grin I hadn't understood, and had gone over to the station-wagon, where his wife had been watching from the driver's seat. \"Come on, Jed,\" she had said sharply. \"You can work off those urges on West Street tonight.\" She put the car in gear and called over to me sweetly, \" \'By now, cutie-pie. Write us every day.\" Then she had wiped the crooked smile off her face and I caught a last glimpse of her withered hatchet profile as the car turned out onto the road. Phew! What a couple! Right out of a book-and what a book! Dear Diary! Well, people couldn\'t come much Worse, and now they\'d gone. From now on, on my travels, the human race must improve!" + var text5: String = "\nI had been standing there, looking down the way the Phanceys had gone, remembering them. Now I turned and looked to the north to see after the weather. It had been a beautiful day, Swiss clear and hot for the middle of October, but now high fretful clouds, black with jagged pink hair from the setting sun, were piling down the sky. Fast little winds were zigzagging among the forest tops and every now and then they hit the single yellow light above the deserted gas station down the road at the tail of the lake and set it swaying. When a longer gust reached me, cold and buffeting, it brought with it the whisper of a metallic squeak from the dancing light, and the first time this happened I shivered deliciously at the little ghostly noise. On the lake shore, beyond the last of the cabins, small waves were lapping fast against the stones, and the gunmetal surface of the lake was fretted with sudden cat\'s-paws that sometimes showed a fleck of white. But, in between the angry gusts, the air was still, and the sentinel trees across the road and behind the motel seemed to be pressing silently closer to huddle round the campfire of the brightly lit building at my back. \n I suddenly wanted to go to the john, and I smiled to myself. It was the piercing tickle that comes to children during hide-and-seek-in-the-dark and Sardines, when, in your cupboard under the stairs, you heard the soft creak of a floorboard, the approaching whisper of the searchers. Then you clutched yourself in thrilling anguish and squeezed your legs together and waited for the ecstasy of discovery, the crack of light from the opening door and then-the supreme moment-your urgent \"Ssh! Come in with me!\" the softly closing door and the giggling warm body pressed tight against your own." + var text6: String = "\nStanding there, a \"big girl\" now, I remembered it all and recognized the sensual itch brought on by a fleeting apprehension-the shiver down the spine, the intuitive gooseflesh that come from the primitive fear-signals of animal ancestors. 1 was amused and I hugged the moment to me. Soon the thunderheads would burst and I would step back from the howl and chaos of the storm into my well-lighted comfortable cave, make myself a drink, listen to the radio, and feel safe and cosseted. \n It was getting dark. Tonight there would be no evening chorus from the birds. They had long ago read the signs and disappeared into their own shelters in the forest, as had the animals-the squirrels and the chipmunks and the deer. In all this huge wild area there was now only me out in the open. I took a last few deep breaths of the soft, moist air. The humidity had strengthened the scent of pine and moss, and now there was also a strong underlying armpit smell of earth. It was almost as if the forest was sweating with the same pleasurable excitement I was feeling. Somewhere, from quite close, a nervous owl asked loudly \"Who?\" and then was silent. I took a few steps away from the lighted doorway and stood in the middle of the dusty road, looking north. A strong gust of wind hit me and blew back my hair. Lightning threw a quick blue-white hand across the horizon. Seconds later thunder growled softly like a wakening guard dog, and then the big wind came and the tops of the trees began to dance and thrash and the yellow light over the gas station jigged and blinked down the road as if to warn me. It was warning me. Suddenly the dancing light was blurred with rain, its luminosity fogged by an advancing gray sheet of water. The first heavy drops hit me, and 1 turned and ran. \n I banged the door behind me, locked it, and put up the chain. I was only just in time. Then the avalanche crashed down and settled into a steady roar of water whose patterns of sound varied from a heavy drumming on the slanting timbers of the roof to a higher, more precise slashing at the windows. In a moment these sounds were joined by the busy violence of the overflow drainpipes. And the noisy background pattern of the storm was set." + var text7: String = "\nI was still standing there, cozily listening, when the thunder that had been creeping quietly up behind my back sprang its ambush. Suddenly lightning blazed in the room, and at the same instant there came a blockbusting crash that shook the building and made the air twang like piano wire. It was just one single colossal explosion that might have been a huge bomb falling only yards away. There was a sharp tinkle as a piece of glass fell out of one of the windows onto the floor, and then the noise of water pattering in onto the linoleum. \n I didn\'t move. I couldn\'t. I stood and cringed, my hands over my ears. I hadn\'t meant it to be like this! The silence, that had been deafening, resolved itself back into the roar of the rain, the roar that had been so comforting but that now said, \"You hadn\'t thought it could be so bad. You had never seen a storm in these mountains. Pretty flimsy this little shelter of yours, really. How\'d you like to have the lights put out as a start? Then the crash of a thunderbolt through that matchwood ceiling of yours? Then, just to finish you off, lightning to set fire to the place-perhaps electrocute you? Or shall we just frighten you so much that you dash out in the rain and try and make those ten miles to Lake George. Like to be alone, do you? Well, just try this for size!\" Again the room turned blue-white, again, just overhead, there came the ear-splitting crack of the explosion, but this time the crack widened and racketed to and fro in a furious cannonade that set the cups and glasses rattling behind the bar and made the woodwork creak with the pressure of the sound-waves.My legs felt weak, and I faltered to the nearest chair and sat down, my head in my hands. How could I have been so foolish, so-so impudent? If only someone would come, someone to stay with me, someone to tell me that this was only a storm! But it wasn\'t! It was catastrophe, the end of the world! And all aimed at me! Now! It would be coming again! Any minute now! I must do something, get help! But the Phanceys had paid off the telephone company, and the service had been disconnected. There was only one hope! I got up and ran to the door, reaching up for the big switch that controlled the VACANCY/NO VACANCY sign in red neon above the threshold. If I put it to VACANCY, there might be someone driving down the road. Someone who would be glad of shelter. But, as I pulled the switch, the lightning that had been watching me crackled viciously in the room, and, as the thunder crashed, I was seized by a giant hand and hurled to the floor." + + override func viewDidLoad() { + super.viewDidLoad() + + textView = UITextView.init(frame: self.view.bounds) + textView.isEditable = false + textView.alwaysBounceVertical = true + textView.textColor = UIColor.init(white: 0.3, alpha: 1.0) + textView.textAlignment = .justified + textView.textContainerInset = UIEdgeInsets.init(top: 12, left: 8, bottom: 12, right: 8) + self.view.addSubview(textView) + + textView.es_addPullToRefresh { + [weak self] in + guard let weakSelf = self else { + return + } + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + weakSelf.num = 0 + let style = NSMutableParagraphStyle.init() + style.lineSpacing = 0.0 + style.firstLineHeadIndent = 10.0 + style.alignment = .justified + weakSelf.textView.attributedText = NSAttributedString.init(string: weakSelf.text1, attributes: [NSParagraphStyleAttributeName : style, NSFontAttributeName: UIFont.init(name: "ChalkboardSE-Bold", size: 16.0)!, NSForegroundColorAttributeName: UIColor.init(white: 0.3, alpha: 1.0)]) + weakSelf.textView.es_stopPullToRefresh() + } + } + + textView.es_addInfiniteScrolling { + [weak self] in + guard let weakSelf = self else { + return + } + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + weakSelf.num += 1 + var str: String = weakSelf.text1 + if weakSelf.num >= 1 { + str += weakSelf.text2 + } + if weakSelf.num >= 2 { + str += weakSelf.text3 + } + if weakSelf.num >= 3 { + str += weakSelf.text4 + } + if weakSelf.num >= 4 { + str += weakSelf.text5 + } + if weakSelf.num >= 5 { + str += weakSelf.text6 + } + if weakSelf.num >= 6 { + str += weakSelf.text7 + } + if weakSelf.num >= 7 { + weakSelf.textView.es_noticeNoMoreData() + } else { + let style = NSMutableParagraphStyle.init() + style.lineSpacing = 0.0 + style.firstLineHeadIndent = 10.0 + style.alignment = .justified + weakSelf.textView.attributedText = NSAttributedString.init(string: str, attributes: [NSParagraphStyleAttributeName : style, NSFontAttributeName: UIFont.init(name: "ChalkboardSE-Bold", size: 16.0)!, NSForegroundColorAttributeName: UIColor.init(white: 0.3, alpha: 1.0)]) + + weakSelf.textView.es_stopLoadingMore() + } + } + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + self.textView.es_startPullToRefresh() + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + if !textView.frame.equalTo(self.view.bounds) { + textView.frame = self.view.bounds + } + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/WeChat/WCRefreshHeaderAnimator.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/WeChat/WCRefreshHeaderAnimator.swift new file mode 100644 index 0000000..d550a3b --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/WeChat/WCRefreshHeaderAnimator.swift @@ -0,0 +1,99 @@ +// +// WCRefreshHeaderAnimator.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/5/9. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +public class WCRefreshHeaderAnimator: UIView, ESRefreshProtocol, ESRefreshAnimatorProtocol { + + public var insets: UIEdgeInsets = UIEdgeInsets.zero + public var view: UIView { return self } + public var trigger: CGFloat = 56.0 + public var executeIncremental: CGFloat = 0.0 + public var state: ESRefreshViewState = .pullToRefresh + + private var timer: Timer? + private var timerProgress: Double = 0.0 + + private let imageView: UIImageView = { + let imageView = UIImageView.init() + imageView.image = UIImage.init(named: "icon_wechat") + imageView.sizeToFit() + let size = imageView.image?.size ?? CGSize.zero + imageView.center = CGPoint.init(x: UIScreen.main.bounds.size.width / 2.0, y: -size.height) + return imageView + }() + + public override init(frame: CGRect) { + super.init(frame: frame) + self.addSubview(imageView) + } + + public required init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func refreshAnimationBegin(view: ESRefreshComponent) { + self.startAnimating() + UIView.animate(withDuration: 0.2, delay: 0, options: .curveLinear, animations: { + let size = self.imageView.image?.size ?? CGSize.zero + self.imageView.center = CGPoint.init(x: UIScreen.main.bounds.size.width / 2.0, y: 16.0 + size.height / 2.0) + }, completion: { (finished) in }) + } + + public func refreshAnimationEnd(view: ESRefreshComponent) { + UIView.animate(withDuration: 0.1, delay: 0, options: .curveEaseIn, animations: { + self.imageView.transform = CGAffineTransform.identity + self.imageView.center = CGPoint.init(x: UIScreen.main.bounds.size.width / 2.0, y: self.imageView.center.y + 10.0) + }, completion: { (finished) in + UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: { + let size = self.imageView.image?.size ?? CGSize.zero + self.imageView.transform = CGAffineTransform.identity + self.imageView.center = CGPoint.init(x: UIScreen.main.bounds.size.width / 2.0, y: -size.height) + }, completion: { (finished) in + self.stopAnimating() + }) + }) + } + + public func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) { + let size = imageView.image?.size ?? CGSize.zero + let p = min(1.0, max(0.0, progress)) + let y = (-self.trigger * progress) + 16.0 - (size.height + 16.0) * (1 - p) + let center = CGPoint.init(x: UIScreen.main.bounds.size.width / 2.0, y: y + (size.height / 2.0)) + self.imageView.center = center + self.imageView.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI) * progress) + } + + public func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) { + guard self.state != state else { + return + } + self.state = state + } + + func timerAction() { + timerProgress += 0.01 + self.imageView.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI) * CGFloat(timerProgress)) + } + + func startAnimating() { + if timer == nil { + timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(WCRefreshHeaderAnimator.timerAction), userInfo: nil, repeats: true) + RunLoop.current.add(timer!, forMode: RunLoopMode.commonModes) + } + } + + func stopAnimating() { + if timer != nil { + timerProgress = 0.0 + timer?.invalidate() + timer = nil + } + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/WeChat/WeChatTableHeaderView.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/WeChat/WeChatTableHeaderView.swift new file mode 100644 index 0000000..d5620c9 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/WeChat/WeChatTableHeaderView.swift @@ -0,0 +1,40 @@ +// +// WeChatTableHeaderView.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/5/9. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +class WeChatTableHeaderView: UIView { + let imageView: UIImageView = { + let imageView = UIImageView.init(image: UIImage.init(named: "icon_wechat_header")) + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + return imageView + }() + + let avatarView: UIImageView = { + let avatarView = UIImageView.init(image: UIImage.init(named: "icon")) + return avatarView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + self.addSubview(imageView) + self.addSubview(avatarView) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + imageView.frame = self.bounds + avatarView.frame = CGRect.init(x: self.bounds.size.width - 10.0 - 75.0, y: self.bounds.size.height - 48.0, width: 75.0, height: 75.0) + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/WeChat/WeChatTableViewController.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/WeChat/WeChatTableViewController.swift new file mode 100644 index 0000000..3c314e5 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Custom/WeChat/WeChatTableViewController.swift @@ -0,0 +1,101 @@ +// +// WeChatTableViewController.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/5/9. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +class WeChatTableViewController: UITableViewController { + var array = [String]() + var page = 1 + + override func viewDidLoad() { + super.viewDidLoad() + self.view.translatesAutoresizingMaskIntoConstraints = false + self.view.backgroundColor = UIColor.init(red: 46/255.0, green: 49/255.0, blue: 50/255.0, alpha: 1.0) + self.tableView.register(UINib.init(nibName: "DefaultTableViewCell", bundle: nil), forCellReuseIdentifier: "DefaultTableViewCell") + + // Header like WeChat + let header = WeChatTableHeaderView.init(frame: CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: self.view.bounds.size.width, height: 260))) + self.tableView.tableHeaderView = header + + /// Add some data + for _ in 1...8{ + self.array.append(" ") + } + + let _ = self.tableView.es_addPullToRefresh(animator: WCRefreshHeaderAnimator.init(frame: CGRect.zero)) { + [weak self] in + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + self?.page = 1 + self?.array.removeAll() + for _ in 1...8{ + self?.array.append(" ") + } + self?.tableView.reloadData() + self?.tableView.es_stopPullToRefresh(completion: true) + } + } + self.tableView.refreshIdentifier = NSStringFromClass(DefaultTableViewController.self) // Set refresh identifier + self.tableView.expriedTimeInterval = 20.0 // 20 second alive. + + let _ = self.tableView.es_addInfiniteScrolling() { + [weak self] in + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { + self?.page += 1 + if self?.page ?? 0 <= 3 { + for _ in 1...8{ + self?.array.append(" ") + } + self?.tableView.reloadData() + self?.tableView.es_stopLoadingMore() + } else { + self?.tableView.es_noticeNoMoreData() + } + } + } + self.tableView.es_footer?.backgroundColor = UIColor.white // Custom footer background color + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + self.tableView.es_autoPullToRefresh() + } + + // MARK: - Table view data source + func numberOfSectionsInTableView(tableView: UITableView) -> Int { + return 1 + } + + func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return array.count + } + + func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { + return 100.0 + } + + func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return CGFloat.leastNormalMagnitude + } + + func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return CGFloat.leastNormalMagnitude + } + + func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "DefaultTableViewCell", for: indexPath as IndexPath) + cell.backgroundColor = UIColor.init(white: 250.0 / 255.0, alpha: 1.0) + return cell + } + + func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { + tableView.deselectRow(at: indexPath as IndexPath, animated: true) + let vc = WebViewController.init() + self.navigationController?.pushViewController(vc, animated: true) + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Info.plist b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Info.plist new file mode 100644 index 0000000..0ec9040 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 2.6 + CFBundleSignature + ???? + CFBundleVersion + 8 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/ListTableViewCell.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/ListTableViewCell.swift new file mode 100644 index 0000000..1a21e367 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/ListTableViewCell.swift @@ -0,0 +1,26 @@ +// +// ListTableViewCell.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/9/12. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +class ListTableViewCell: UITableViewCell { + + @IBOutlet weak var titleLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/ListTableViewCell.xib b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/ListTableViewCell.xib new file mode 100644 index 0000000..c026c30 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/ListTableViewCell.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/ViewController.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/ViewController.swift new file mode 100644 index 0000000..edb89f6 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/ViewController.swift @@ -0,0 +1,110 @@ +// +// ViewController.swift +// ESPullToRefreshExample +// +// Created by egg swift on 16/5/5. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +public enum ESRefreshExampleType { + case defaulttype, meituan, wechat +} + +public enum ESRefreshExampleListType { + case tableview, collectionview +} + +public class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { + @IBOutlet weak var tableView: UITableView! + + public var listType: ESRefreshExampleListType = .tableview + + public let dataArray = [ + "Default", + "美团网 (Meituan.com)", + "WeChat", + "TextView", + "Day", + "CollectionView" + ] + + public override func viewDidLoad() { + super.viewDidLoad() + let appearance = UIBarButtonItem.appearance() + appearance.setBackButtonTitlePositionAdjustment(UIOffset.init(horizontal: 0.0, vertical: -60), for: .default) + + self.navigationController?.navigationBar.isTranslucent = true + self.navigationController?.navigationBar.barTintColor = UIColor.init(red: 250/255.0, green: 250/255.0, blue: 250/255.0, alpha: 0.8) + self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName : UIColor.init(red: 38/255.0, green: 38/255.0, blue: 38/255.0, alpha: 1.0), NSFontAttributeName: UIFont.systemFont(ofSize: 16.0)] + self.navigationController?.navigationBar.tintColor = UIColor.init(red: 38/255.0, green: 38/255.0, blue: 38/255.0, alpha: 1.0) + self.navigationItem.title = "Example" + + self.tableView.register(UINib.init(nibName: "ListTableViewCell", bundle: nil), forCellReuseIdentifier: "ListTableViewCell") + } + + public func select(indexPath: IndexPath) { + var vc: UIViewController! + switch indexPath.row { + case 0: + vc = ESRefreshTableViewController.init(style: .plain) + if let vc = vc as? ESRefreshTableViewController { + vc.type = .defaulttype + } + case 1: + vc = ESRefreshTableViewController.init(style: .plain) + if let vc = vc as? ESRefreshTableViewController { + vc.type = .meituan + } + case 2: + vc = ESRefreshTableViewController.init(style: .plain) + if let vc = vc as? ESRefreshTableViewController { + vc.type = .wechat + } + case 3: + vc = TextViewController.init() + case 4: + vc = ESRefreshTableViewController.init(style: .plain) + case 5: + vc = CollectionViewController() + default: + break + } + vc.title = dataArray[indexPath.row] + self.navigationController?.pushViewController(vc, animated: true) + } + + // MARK: UITableViewDataSource + public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return dataArray.count + } + + public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 54.0 + } + + public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = self.tableView.dequeueReusableCell(withIdentifier: "ListTableViewCell") + if let cell = cell as? ListTableViewCell { + cell.titleLabel.text = "\(indexPath.row + 1). " + dataArray[indexPath.row] + } + return cell! + } + + public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return 0.5 + } + + public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + let view = UIView.init(frame: CGRect.init(x: 0, y: 0, width: tableView.bounds.size.width, height: 0.5)) + view.backgroundColor = UIColor.lightGray + return view + } + + public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath as IndexPath, animated: true) + self.select(indexPath: indexPath) + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/WebViewController.swift b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/WebViewController.swift new file mode 100644 index 0000000..b06e06d --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/WebViewController.swift @@ -0,0 +1,58 @@ +// +// WebViewController.swift +// ESPullToRefreshExample +// +// Created by lihao on 16/5/6. +// Copyright © 2016年 egg swift. All rights reserved. +// + +import UIKit + +class WebViewController: UIViewController, UIWebViewDelegate { + + @IBOutlet weak var networkTipsButton: UIButton! + @IBOutlet weak var webViewXib: UIWebView! + var webView: UIWebView! + + override func viewDidLoad() { + super.viewDidLoad() + + if let _ = self.webViewXib { + self.webView = self.webViewXib + } else { + self.webView = UIWebView() + self.webView.frame = self.view.bounds + self.view.addSubview(self.webView!) + } + + self.webView!.delegate = self + + let url = "https://github.com/eggswift" + self.title = "egg swift" + let request = NSURLRequest.init(url: NSURL(string: url)! as URL) + + self.webView.scrollView.es_addPullToRefresh { + [weak self] in + self!.webView.loadRequest(request as URLRequest) + } + self.webView.scrollView.es_startPullToRefresh() + } + + func webViewDidFinishLoad(_ webView: UIWebView) { + self.webView.scrollView.es_stopPullToRefresh() + self.webView.scrollView.bounces = true + self.webView.scrollView.alwaysBounceVertical = true + } + + func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { + self.webView.scrollView.es_stopPullToRefresh(ignoreDate: true) + self.networkTipsButton.isHidden = false + } + + @IBAction func networkRetryAction(_ sender: AnyObject) { + self.networkTipsButton.isHidden = true + UIView.performWithoutAnimation { + self.webView.scrollView.es_startPullToRefresh() + } + } +} diff --git a/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/WebViewController.xib b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/WebViewController.xib new file mode 100644 index 0000000..4f7e610 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/ESPullToRefreshExample/ESPullToRefreshExample/WebViewController.xib @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/pull-to-refresh/LICENSE b/Carthage/Checkouts/pull-to-refresh/LICENSE new file mode 100644 index 0000000..5e81458 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 lihao + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Carthage/Checkouts/pull-to-refresh/Package.swift b/Carthage/Checkouts/pull-to-refresh/Package.swift new file mode 100644 index 0000000..4879f5d --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/Package.swift @@ -0,0 +1,29 @@ +// +// ESTabBarItemContent.swift +// +// Created by egg swift on 16/4/7. +// Copyright (c) 2013-2016 ESPullToRefresh +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import PackageDescription + +let package = Package( + name: "ESPullToRefresh" +) \ No newline at end of file diff --git a/Carthage/Checkouts/pull-to-refresh/README.md b/Carthage/Checkouts/pull-to-refresh/README.md new file mode 100644 index 0000000..24d6f9a --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/README.md @@ -0,0 +1,175 @@ + +
![logo](logo.png)
+ +
+[![Travis](https://travis-ci.org/eggswift/pull-to-refresh.svg?branch=master)](https://travis-ci.org/eggswift/pull-to-refresh) +[![CocoaPods](https://img.shields.io/cocoapods/v/ESPullToRefresh.svg)](http://cocoapods.org/pods/pull-to-refresh) +[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![Swift v2.3 v3](https://img.shields.io/badge/Swift-v2.3 v3-orange.svg?style=flat)](https://developer.apple.com/swift/) +[![Twitter](https://img.shields.io/badge/Twitter-@lihao_iOS-blue.svg?style=flat)](https://twitter.com/lihao_iOS) +[![Twitter](https://img.shields.io/badge/Weibo-@李昊_____-orange.svg?style=flat)](http://weibo.com/5120522686/profile?rightmod=1&wvr=6&mod=personinfo&is_all=1) +
+ +###[中文介绍](README_CN.md) + +**ESPullToRefresh** is an easy-to-use component that give **pull-to-refresh** and **infinite-scrolling** implemention for developers. By extension to UIScrollView, you can easily add pull-to-refresh and infinite-scrolling for any subclass of UIScrollView. If you want to customize its UI style, you just need conform the specified protocol. + + +## Requirements + +* Xcode 8 or later +* iOS 8.0 or later +* ARC +* Swift 2.3 or later + +## Features + +* Support `UIScrollView` and its subclasses `UICollectionView` `UITableView` `UITextView` +* Pull-Down to refresh and Pull-Up to load more +* Support customize your own style(s) + +## Demo + +Download and run the ESPullToRefreshExample project in Xcode to see ESPullToRefresh in action. + + +## Installation + +### CocoaPods + +``` ruby +pod "ESPullToRefresh" +``` + +### Carthage + +```ruby +github "eggswift/pull-to-refresh" +``` + +### Manually + +``` ruby +git clone https://github.com/eggswift/pull-to-refresh.git +open ESPullToRefresh +``` + +## Usage + +### Default style: + + +![](example_default.gif) + + + +Add `ESPullToRefresh` to your project + +```swift +import ESPullToRefresh +``` + +Add default pull-to-refresh + +``` swift +self.tableView.es_addPullToRefresh { + [weak self] in + /// Do anything you want... + /// ... + /// Stop refresh when your job finished, it will reset refresh footer if completion is true + self?.tableView.es_stopPullToRefresh(completion: true) + /// Set ignore footer or not + self?.tableView.es_stopPullToRefresh(completion: true, ignoreFooter: false) +} +``` + +Add default infinite-scrolling +``` swift +self.tableView.es_addInfiniteScrolling { + [weak self] in + /// Do anything you want... + /// ... + /// If common end + self?.tableView.es_stopLoadingMore() + /// If no more data + self?.tableView.es_noticeNoMoreData() +} +``` + + +### Customize Style + +#### As effect: + +![](example_meituan.gif) + +**PS: Load effect is from MeiTuan iOS app.** + +![](example_wechat.gif) + + +Customize refresh need conform the **ESRefreshProtocol** and **ESRefreshAnimatorProtocol** protocol. + +Add customize pull-to-refresh + +``` swift +func es_addPullToRefresh(animator animator: protocol, handler: ESRefreshHandler) +``` + +Add customize infinite-scrolling + +``` swift +func es_addInfiniteScrolling(animator animator: protocol, handler: ESRefreshHandler) +``` + +### Espried and auto refresh + +ESPullToRefresh support for the latest expiration time and the cache refresh time, You need set an `refreshIdentifier` to your UIScrollView. +``` swift +scrollView.refreshIdentifier = "Your Identifier" // Set refresh identifier +scrollView.expriedTimeInterval = 20.0 // Set the expiration interval +``` +You can use `es_autoPullToRefresh()` method, when the time over the last refresh interval expires automatically refreshed. +``` swift +scrollView.es_autoPullToRefresh() + +let expried = scrollView.espried // expired or not +``` + + +### Remove + +``` swift +func es_removeRefreshHeader() +func es_removeRefreshFooter() +``` + + +## Contribution + +You are welcome to contribute to the project by forking the repo, modifying the code and opening issues or pull requests. + +## License + +The MIT License (MIT) + +Copyright (c) 2013-2016 eggswift + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Carthage/Checkouts/pull-to-refresh/README_CN.md b/Carthage/Checkouts/pull-to-refresh/README_CN.md new file mode 100644 index 0000000..35a1d98 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/README_CN.md @@ -0,0 +1,175 @@ + +
![logo](logo.png)
+ +
+[![Travis](https://travis-ci.org/eggswift/pull-to-refresh.svg?branch=master)](https://travis-ci.org/eggswift/pull-to-refresh) +[![CocoaPods](https://img.shields.io/cocoapods/v/ESPullToRefresh.svg)](http://cocoapods.org/pods/pull-to-refresh) +[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![Swift v2.3 v3](https://img.shields.io/badge/Swift-v2.3 v3-orange.svg?style=flat)](https://developer.apple.com/swift/) +[![Twitter](https://img.shields.io/badge/Twitter-@lihao_iOS-blue.svg?style=flat)](https://twitter.com/lihao_iOS) +[![Twitter](https://img.shields.io/badge/Weibo-@李昊_____-orange.svg?style=flat)](http://weibo.com/5120522686/profile?rightmod=1&wvr=6&mod=personinfo&is_all=1) +
+ +###[For English](README.md) + +**ESPullToRefresh**是一个非常易于开发者使用的下拉刷新和加载更多组件。通过一个UIScrollView的扩展,可以轻松为UIScrollView的所有子类添加下拉刷新功能。 如果你想定制组件的UI样式,只要实现指定的协议方法即可。 + + +## 支持环境 + +* Xcode 8 or later +* iOS 8.0 or later +* ARC +* Swift 2.3 or later + +## 特性 + +* 支持UIScrollView及其子类UICollectionView、UITableView、UIWebView等; +* 支持下拉刷新和上拉加载更多; +* 支持定制自己所需的样式; +* 支持刷新时间缓存,设置过期时间并策略刷新。 + +## Demo + +下载后运行ESPullToRefreshExample工程,你可以看到一些使用ESPullToRefresh实现的自定义下拉刷新和加载更多例子。 + + +## 如何安装 + +### CocoaPods + +``` ruby +pod "ESPullToRefresh" +``` + +### Carthage + +```ruby +github "eggswift/ESPullToRefresh" +``` + +### 手动安装 + +``` ruby +git clone https://github.com/eggswift/pull-to-refresh.git +open ESPullToRefresh +``` + +## 开始使用 + +### 使用默认样式: + +#### 效果如下: + +![](example_default.gif) + + + +将ESPullToRefresh导入至你的工程 + +```swift +import ESPullToRefresh +``` + +设置默认下拉刷新组件 + +```swift +self.tableView.es_addPullToRefresh { + [weak self] in + /// 在这里做刷新相关事件 + /// ... + /// 如果你的刷新事件成功,设置completion自动重置footer的状态 + self?.tableView.es_stopPullToRefresh(completion: true) + /// 设置ignoreFooter来处理不需要显示footer的情况 + self?.tableView.es_stopPullToRefresh(completion: true, ignoreFooter: false) +} +``` + +设置默认加载更多组件 +``` swift +self.tableView.es_addInfiniteScrolling { + [weak self] in + /// 在这里做加载更多相关事件 + /// ... + /// 如果你的加载更多事件成功,调用es_stopLoadingMore()重置footer状态 + self?.tableView.es_stopLoadingMore() + /// 通过es_noticeNoMoreData()设置footer暂无数据状态 + self?.tableView.es_noticeNoMoreData() +} +``` + + +### 使用自定义样式 + +#### 效果如下: + +![](example_meituan.gif) + +注: 加载动画资源来自美团 iOS app。 + +![](example_wechat.gif) + + +**ESPullToRefresh**通过**ESRefreshProtocol**和**ESRefreshAnimatorProtocol**来约束刷新组件的使用,自定义的组件必须遵守这两个协议,并实现协议中的方法。 + +设置自定义下拉刷新组件 +``` swift +func es_addPullToRefresh(animator animator: protocol, handler: ESRefreshHandler) +``` + +设置自定义加载更多组件 +``` swift +func es_addInfiniteScrolling(animator animator: protocol, handler: ESRefreshHandler) +``` + +### 设置过期时间和自动刷新 + +ESPullToRefresh支持最近刷新时间和过期时间缓存,您需要为UIScrollView子类设置`refreshIdentifier`标示。 +``` swift +scrollView.refreshIdentifier = "Your Identifier" // 设置当前ScrollView的标识 +scrollView.expriedTimeInterval = 20.0 // 设置过期时间间隔 +``` +你可以通过`es_autoPullToRefresh()` 方法,当上次刷新时间超过过期时间间隔时自动刷新。 +``` swift +scrollView.es_autoPullToRefresh() + +let expried = scrollView.espried // 获取是否过期 +``` + + +### 移除方法 + +``` swift +func es_removeRefreshHeader() +func es_removeRefreshFooter() +``` + + +## 贡献 + +欢迎提交 issue 和 pull request,有任何疑问可以随时交流。 + +## 使用许可 + +The MIT License (MIT) + +Copyright (c) 2013-2016 eggswift (https://github.com/eggswift/pull-to-refresh) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Carthage/Checkouts/pull-to-refresh/Sources/Animator/ESRefreshFooterAnimator.swift b/Carthage/Checkouts/pull-to-refresh/Sources/Animator/ESRefreshFooterAnimator.swift new file mode 100644 index 0000000..173597f --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/Sources/Animator/ESRefreshFooterAnimator.swift @@ -0,0 +1,114 @@ +// +// ESRefreshFooterAnimator.swift +// +// Created by egg swift on 16/4/7. +// Copyright (c) 2013-2016 ESPullToRefresh (https://github.com/eggswift/pull-to-refresh) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import UIKit + +open class ESRefreshFooterAnimator: UIView, ESRefreshProtocol, ESRefreshAnimatorProtocol { + + open var loadingMoreDescription: String = "Loading more" + open var noMoreDataDescription: String = "No more data" + open var loadingDescription: String = "Loading..." + + open var view: UIView { return self } + open var duration: TimeInterval = 0.3 + open var insets: UIEdgeInsets = UIEdgeInsets.zero + open var trigger: CGFloat = 42.0 + open var executeIncremental: CGFloat = 42.0 + open var state: ESRefreshViewState = .pullToRefresh + + fileprivate let titleLabel: UILabel = { + let label = UILabel.init(frame: CGRect.zero) + label.font = UIFont.systemFont(ofSize: 14.0) + label.textColor = UIColor.init(white: 160.0 / 255.0, alpha: 1.0) + label.textAlignment = .center + return label + }() + + fileprivate let indicatorView: UIActivityIndicatorView = { + let indicatorView = UIActivityIndicatorView.init(activityIndicatorStyle: .gray) + indicatorView.isHidden = true + return indicatorView + }() + + public override init(frame: CGRect) { + super.init(frame: frame) + titleLabel.text = loadingMoreDescription + addSubview(titleLabel) + addSubview(indicatorView) + } + + public required init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + open func refreshAnimationBegin(view: ESRefreshComponent) { + indicatorView.startAnimating() + titleLabel.text = loadingDescription + indicatorView.isHidden = false + } + + open func refreshAnimationEnd(view: ESRefreshComponent) { + indicatorView.stopAnimating() + titleLabel.text = loadingMoreDescription + indicatorView.isHidden = true + } + + open func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) { + // do nothing + } + + open func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) { + guard self.state != state else { + return + } + self.state = state + + switch state { + case .refreshing, .autoRefreshing : + titleLabel.text = loadingDescription + break + case .noMoreData: + titleLabel.text = noMoreDataDescription + break + case .pullToRefresh: + titleLabel.text = loadingMoreDescription + break + default: + break + } + self.setNeedsLayout() + } + + open override func layoutSubviews() { + super.layoutSubviews() + let s = self.bounds.size + let w = s.width + let h = s.height + + titleLabel.sizeToFit() + titleLabel.center = CGPoint.init(x: w / 2.0, y: h / 2.0 - 5.0) + indicatorView.center = CGPoint.init(x: titleLabel.frame.origin.x - 18.0, y: titleLabel.center.y) + } +} diff --git a/Carthage/Checkouts/pull-to-refresh/Sources/Animator/ESRefreshHeaderAnimator.swift b/Carthage/Checkouts/pull-to-refresh/Sources/Animator/ESRefreshHeaderAnimator.swift new file mode 100644 index 0000000..2c8ddfd --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/Sources/Animator/ESRefreshHeaderAnimator.swift @@ -0,0 +1,152 @@ +// +// ESRefreshHeaderView.swift +// +// Created by egg swift on 16/4/7. +// Copyright (c) 2013-2016 ESPullToRefresh (https://github.com/eggswift/pull-to-refresh) +// Icon from http://www.iconfont.cn +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import QuartzCore +import UIKit + +open class ESRefreshHeaderAnimator: UIView, ESRefreshProtocol, ESRefreshAnimatorProtocol, ESRefreshImpactProtocol { + open var pullToRefreshDescription = "Pull to refresh" { + didSet { + if pullToRefreshDescription != oldValue { + titleLabel.text = pullToRefreshDescription; + } + } + } + open var releaseToRefreshDescription = "Release to refresh" + open var loadingDescription = "Loading..." + + open var view: UIView { return self } + open var insets: UIEdgeInsets = UIEdgeInsets.zero + open var trigger: CGFloat = 60.0 + open var executeIncremental: CGFloat = 60.0 + open var state: ESRefreshViewState = .pullToRefresh + + fileprivate let imageView: UIImageView = { + let imageView = UIImageView.init() + if #available(iOS 8, *) { + imageView.image = UIImage(named: "icon_pull_to_refresh_arrow", in: Bundle(for: ESRefreshHeaderAnimator.self), compatibleWith: nil) + } else { + imageView.image = UIImage(named: "icon_pull_to_refresh_arrow") + } + return imageView + }() + + fileprivate let titleLabel: UILabel = { + let label = UILabel.init(frame: CGRect.zero) + label.font = UIFont.systemFont(ofSize: 14.0) + label.textColor = UIColor.init(white: 0.625, alpha: 1.0) + label.textAlignment = .left + return label + }() + + fileprivate let indicatorView: UIActivityIndicatorView = { + let indicatorView = UIActivityIndicatorView.init(activityIndicatorStyle: .gray) + indicatorView.isHidden = true + return indicatorView + }() + + public override init(frame: CGRect) { + super.init(frame: frame) + titleLabel.text = pullToRefreshDescription + self.addSubview(imageView) + self.addSubview(titleLabel) + self.addSubview(indicatorView) + } + + public required init(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + open func refreshAnimationBegin(view: ESRefreshComponent) { + indicatorView.startAnimating() + indicatorView.isHidden = false + imageView.isHidden = true + titleLabel.text = loadingDescription + imageView.transform = CGAffineTransform(rotationAngle: 0.000001 - CGFloat(M_PI)) + } + + open func refreshAnimationEnd(view: ESRefreshComponent) { + indicatorView.stopAnimating() + indicatorView.isHidden = true + imageView.isHidden = false + titleLabel.text = pullToRefreshDescription + imageView.transform = CGAffineTransform.identity + } + + open func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) { + // Do nothing + + } + + open func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) { + guard self.state != state else { + return + } + self.state = state + + switch state { + case .refreshing, .autoRefreshing: + titleLabel.text = loadingDescription + self.setNeedsLayout() + break + case .releaseToRefresh: + titleLabel.text = releaseToRefreshDescription + self.setNeedsLayout() + self.impact() + UIView.animate(withDuration: 0.2, delay: 0.0, options: UIViewAnimationOptions(), animations: { + [weak self] in + self?.imageView.transform = CGAffineTransform(rotationAngle: 0.000001 - CGFloat(M_PI)) + }) { (animated) in } + break + case .pullToRefresh: + titleLabel.text = pullToRefreshDescription + self.setNeedsLayout() + UIView.animate(withDuration: 0.2, delay: 0.0, options: UIViewAnimationOptions(), animations: { + [weak self] in + self?.imageView.transform = CGAffineTransform.identity + }) { (animated) in } + break + default: + break + } + } + + open override func layoutSubviews() { + super.layoutSubviews() + let s = self.bounds.size + let w = s.width + let h = s.height + + UIView.performWithoutAnimation { + titleLabel.sizeToFit() + titleLabel.center = CGPoint.init(x: w / 2.0, y: h / 2.0) + indicatorView.center = CGPoint.init(x: titleLabel.frame.origin.x - 16.0, y: h / 2.0) + imageView.frame = CGRect.init(x: titleLabel.frame.origin.x - 28.0, y: (h - 18.0) / 2.0, width: 18.0, height: 18.0) + } + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/Sources/Animator/icon_pull_to_refresh_arrow@2x.png b/Carthage/Checkouts/pull-to-refresh/Sources/Animator/icon_pull_to_refresh_arrow@2x.png new file mode 100644 index 0000000..ca32ee9 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/Sources/Animator/icon_pull_to_refresh_arrow@2x.png differ diff --git a/Carthage/Checkouts/pull-to-refresh/Sources/ESPullToRefresh+Manager.swift b/Carthage/Checkouts/pull-to-refresh/Sources/ESPullToRefresh+Manager.swift new file mode 100644 index 0000000..205e629 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/Sources/ESPullToRefresh+Manager.swift @@ -0,0 +1,107 @@ +// +// ESPullToRefresh+Manager.swift +// +// Created by egg swift on 16/4/7. +// Copyright (c) 2013-2016 ESPullToRefresh (https://github.com/eggswift/pull-to-refresh) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +open class ESRefreshDataManager { + + static let sharedManager = ESRefreshDataManager.init() + + static let lastRefreshKey: String = "com.espulltorefresh.lastRefreshKey" + static let expiredTimeIntervalKey: String = "com.espulltorefresh.expiredTimeIntervalKey" + open var lastRefreshInfo = [String: Date]() + open var expiredTimeIntervalInfo = [String: TimeInterval]() + + public required init() { + if let lastRefreshInfo = UserDefaults.standard.dictionary(forKey: ESRefreshDataManager.lastRefreshKey) as? [String: Date] { + self.lastRefreshInfo = lastRefreshInfo + } + if let expiredTimeIntervalInfo = UserDefaults.standard.dictionary(forKey: ESRefreshDataManager.expiredTimeIntervalKey) as? [String: TimeInterval] { + self.expiredTimeIntervalInfo = expiredTimeIntervalInfo + } + } + + open func date(forKey key: String) -> Date? { + let date = lastRefreshInfo[key] + return date + } + + open func setDate(_ date: Date?, forKey key: String) { + lastRefreshInfo[key] = date + UserDefaults.standard.set(lastRefreshInfo, forKey: ESRefreshDataManager.lastRefreshKey) + UserDefaults.standard.synchronize() + } + + open func expriedTimeInterval(forKey key: String) -> TimeInterval? { + let interval = expiredTimeIntervalInfo[key] + return interval + } + + open func setExpriedTimeInterval(_ interval: TimeInterval?, forKey key: String) { + expiredTimeIntervalInfo[key] = interval + UserDefaults.standard.set(expiredTimeIntervalInfo, forKey: ESRefreshDataManager.expiredTimeIntervalKey) + UserDefaults.standard.synchronize() + } + + open func isExpried(forKey key: String) -> Bool { + guard let date = date(forKey: key) else { + return true + } + guard let interval = expriedTimeInterval(forKey: key) else { + return false + } + if date.timeIntervalSinceNow < -interval { + return true // Expried + } + return false + } + + open func isExpried(forKey key: String, block: ((Bool) -> ())?) { + DispatchQueue.global().async { + [weak self] in + guard let weakSelf = self else { + return + } + let result = weakSelf.isExpried(forKey: key) + DispatchQueue.main.async(execute: { + block?(result) + }) + } + } + + open static func clearAll() { + self.clearLastRefreshInfo() + self.clearExpriedTimeIntervalInfo() + } + + open static func clearLastRefreshInfo() { + UserDefaults.standard.set(nil, forKey: ESRefreshDataManager.lastRefreshKey) + } + + open static func clearExpriedTimeIntervalInfo() { + UserDefaults.standard.set(nil, forKey: ESRefreshDataManager.expiredTimeIntervalKey) + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/Sources/ESPullToRefresh.swift b/Carthage/Checkouts/pull-to-refresh/Sources/ESPullToRefresh.swift new file mode 100644 index 0000000..db5c36b --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/Sources/ESPullToRefresh.swift @@ -0,0 +1,523 @@ +// +// ESPullToRefresh.swift +// +// Created by egg swift on 16/4/7. +// Copyright (c) 2013-2016 ESPullToRefresh (https://github.com/eggswift/pull-to-refresh) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +private var kESRefreshHeaderKey: String = "" +private var kESRefreshFooterKey: String = "" + +public extension UIScrollView { + + /// Pull-to-refresh associated property + public var es_header: ESRefreshHeaderView? { + get { return (objc_getAssociatedObject(self, &kESRefreshHeaderKey) as? ESRefreshHeaderView) } + set(newValue) { objc_setAssociatedObject(self, &kESRefreshHeaderKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } + } + + /// Infinitiy scroll associated property + public var es_footer: ESRefreshFooterView? { + get { return (objc_getAssociatedObject(self, &kESRefreshFooterKey) as? ESRefreshFooterView) } + set(newValue) { objc_setAssociatedObject(self, &kESRefreshFooterKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } + } + + /// Add pull-to-refresh + @discardableResult + public func es_addPullToRefresh(handler: @escaping ESRefreshHandler) -> ESRefreshHeaderView { + es_removeRefreshHeader() + let header = ESRefreshHeaderView(frame: CGRect.zero, handler: handler) + let headerH = header.animator.executeIncremental + header.frame = CGRect.init(x: 0.0, y: -headerH /* - contentInset.top */, width: bounds.size.width, height: headerH) + addSubview(header) + es_header = header + return header + } + + @discardableResult + public func es_addPullToRefresh(animator: ESRefreshProtocol & ESRefreshAnimatorProtocol, handler: @escaping ESRefreshHandler) -> ESRefreshHeaderView { + es_removeRefreshHeader() + let header = ESRefreshHeaderView(frame: CGRect.zero, handler: handler, animator: animator) + let headerH = animator.executeIncremental + header.frame = CGRect.init(x: 0.0, y: -headerH /* - contentInset.top */, width: bounds.size.width, height: headerH) + addSubview(header) + es_header = header + return header + } + + /// Add infinite-scrolling + @discardableResult + public func es_addInfiniteScrolling(handler: @escaping ESRefreshHandler) -> ESRefreshFooterView { + es_removeRefreshFooter() + let footer = ESRefreshFooterView(frame: CGRect.zero, handler: handler) + let footerH = footer.animator.executeIncremental + footer.frame = CGRect.init(x: 0.0, y: contentSize.height + contentInset.bottom, width: bounds.size.width, height: footerH) + addSubview(footer) + es_footer = footer + return footer + } + + @discardableResult + public func es_addInfiniteScrolling(animator: ESRefreshProtocol & ESRefreshAnimatorProtocol, handler: @escaping ESRefreshHandler) -> ESRefreshFooterView { + es_removeRefreshFooter() + let footer = ESRefreshFooterView(frame: CGRect.zero, handler: handler, animator: animator) + let footerH = footer.animator.executeIncremental + footer.frame = CGRect.init(x: 0.0, y: contentSize.height + contentInset.bottom, width: bounds.size.width, height: footerH) + es_footer = footer + addSubview(footer) + return footer + } + + /// Remove + public func es_removeRefreshHeader() { + es_header?.stopRefreshing() + es_header?.removeFromSuperview() + es_header = nil + } + + public func es_removeRefreshFooter() { + es_footer?.stopRefreshing() + es_footer?.removeFromSuperview() + es_footer = nil + } + + /// Manual refresh + public func es_startPullToRefresh() { + DispatchQueue.main.async { [weak self] in + guard let weakSelf = self else { + return + } + weakSelf.es_header?.startRefreshing(isAuto: false) + } + } + + /// Auto refresh if expried. + public func es_autoPullToRefresh() { + if self.expried == true { + DispatchQueue.main.async { [weak self] in + guard let weakSelf = self else { + return + } + weakSelf.es_header?.startRefreshing(isAuto: true) + } + } + } + + /// Stop pull to refresh + public func es_stopPullToRefresh(ignoreDate: Bool = false, ignoreFooter: Bool = false) { + es_header?.stopRefreshing() + if ignoreDate == false { + if let key = es_header?.refreshIdentifier { + ESRefreshDataManager.sharedManager.setDate(Date(), forKey: key) + } + es_footer?.resetNoMoreData() + } + es_footer?.isHidden = ignoreFooter + } + + /// Footer notice method + public func es_noticeNoMoreData() { + es_footer?.stopRefreshing() + es_footer?.noMoreData = true + } + + public func es_resetNoMoreData() { + es_footer?.noMoreData = false + } + + public func es_stopLoadingMore() { + es_footer?.stopRefreshing() + } + +} + +public extension UIScrollView /* Date Manager */ { + + /// Identifier for cache expried timeinterval and last refresh date. + public var refreshIdentifier: String? { + get { return self.es_header?.refreshIdentifier } + set { self.es_header?.refreshIdentifier = newValue } + } + + /// If you setted refreshIdentifier and expriedTimeInterval, return nearest refresh expried or not. Default is false. + public var expried: Bool { + get { + if let key = self.es_header?.refreshIdentifier { + return ESRefreshDataManager.sharedManager.isExpried(forKey: key) + } + return false + } + } + + public var expriedTimeInterval: TimeInterval? { + get { + if let key = self.es_header?.refreshIdentifier { + let interval = ESRefreshDataManager.sharedManager.expriedTimeInterval(forKey: key) + return interval + } + return nil + } + set { + if let key = self.es_header?.refreshIdentifier { + ESRefreshDataManager.sharedManager.setExpriedTimeInterval(newValue, forKey: key) + } + } + } + + /// Auto cached last refresh date when you setted refreshIdentifier. + public var lastRefreshDate: Date? { + get { + if let key = self.es_header?.refreshIdentifier { + return ESRefreshDataManager.sharedManager.date(forKey: key) + } + return nil + } + } + +} + + +open class ESRefreshHeaderView: ESRefreshComponent { + fileprivate var previousOffset: CGFloat = 0.0 + fileprivate var scrollViewInsets: UIEdgeInsets = UIEdgeInsets.zero + fileprivate var scrollViewBounces: Bool = true + + open var lastRefreshTimestamp: TimeInterval? + open var refreshIdentifier: String? + + public convenience init(frame: CGRect, handler: @escaping ESRefreshHandler) { + self.init(frame: frame) + self.handler = handler + self.animator = ESRefreshHeaderAnimator.init() + } + + open override func willMove(toSuperview newSuperview: UIView?) { + super.willMove(toSuperview: newSuperview) + /* + DispatchQueue.main.async { + [weak self] in + // It's better + } + */ + } + + open override func didMoveToSuperview() { + super.didMoveToSuperview() + DispatchQueue.main.async { + [weak self] in + guard let weakSelf = self else { + return + } + weakSelf.scrollViewBounces = weakSelf.scrollView?.bounces ?? true + weakSelf.scrollViewInsets = weakSelf.scrollView?.contentInset ?? UIEdgeInsets.zero + } + } + + open override func offsetChangeAction(object: AnyObject?, change: [NSKeyValueChangeKey : Any]?) { + guard let scrollView = scrollView else { + return + } + + super.offsetChangeAction(object: object, change: change) + + guard self.isRefreshing == false && self.isAutoRefreshing == false else { + let top = scrollViewInsets.top + let offsetY = scrollView.contentOffset.y + let height = self.frame.size.height + var scrollingTop = (-offsetY > top) ? -offsetY : top + scrollingTop = (scrollingTop > height + top) ? (height + top) : scrollingTop + + scrollView.contentInset.top = scrollingTop + + return + } + + // Check needs re-set animator's progress or not. + var isRecordingProgress = false + defer { + if isRecordingProgress == true { + let percent = -(previousOffset + scrollViewInsets.top) / self.animator.trigger + self.animator.refresh(view: self, progressDidChange: percent) + } + } + + let offsets = previousOffset + scrollViewInsets.top + if offsets < -self.animator.trigger { + // Reached critical + if isRefreshing == false && isAutoRefreshing == false { + if scrollView.isDragging == false { + // Start to refresh... + self.startRefreshing(isAuto: false) + self.animator.refresh(view: self, stateDidChange: .refreshing) + } else { + // Release to refresh! Please drop down hard... + self.animator.refresh(view: self, stateDidChange: .releaseToRefresh) + isRecordingProgress = true + } + } + } else if offsets < 0 { + // Pull to refresh! + if isRefreshing == false && isAutoRefreshing == false { + self.animator.refresh(view: self, stateDidChange: .pullToRefresh) + isRecordingProgress = true + } + } else { + // Normal state + } + + previousOffset = scrollView.contentOffset.y + + } + + open override func start() { + guard let scrollView = scrollView else { + return + } + + // ignore observer + self.ignoreObserver(true) + + // stop scroll view bounces for animation + scrollView.bounces = false + + // call super start + super.start() + + self.animator.refreshAnimationBegin(view: self) + + // 缓存scrollview当前的contentInset, 并根据animator的executeIncremental属性计算刷新时所需要的contentInset,它将在接下来的动画中应用。 + // Tips: 这里将self.scrollViewInsets.top更新,也可以将scrollViewInsets整个更新,因为left、right、bottom属性都没有用到,如果接下来的迭代需要使用这三个属性的话,这里可能需要额外的处理。 + var insets = scrollView.contentInset + self.scrollViewInsets.top = insets.top + insets.top += animator.executeIncremental + + // We need to restore previous offset because we will animate scroll view insets and regular scroll view animating is not applied then. + scrollView.contentOffset.y = previousOffset + + UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveLinear, animations: { + scrollView.contentInset = insets + scrollView.contentOffset.y = -insets.top + }, completion: { (finished) in + self.handler?() + // un-ignore observer + self.ignoreObserver(false) + scrollView.bounces = self.scrollViewBounces + }) + + } + + open override func stop() { + guard let scrollView = scrollView else { + return + } + + // ignore observer + self.ignoreObserver(true) + + self.animator.refreshAnimationEnd(view: self) + + // Back state + UIView.animate(withDuration: 0.2, delay: 0, options: .curveLinear, animations: { + scrollView.contentInset.top = self.scrollViewInsets.top + }, completion: { (finished) in + self.animator.refresh(view: self, stateDidChange: .pullToRefresh) + super.stop() + scrollView.contentInset.top = self.scrollViewInsets.top + // un-ignore observer + self.ignoreObserver(false) + }) + } + +} + +open class ESRefreshFooterView: ESRefreshComponent { + fileprivate var scrollViewInsets: UIEdgeInsets = UIEdgeInsets.zero + open var noMoreData = false { + didSet { + if noMoreData != oldValue { + self.animator.refresh(view: self, stateDidChange: noMoreData ? .noMoreData : .pullToRefresh) + } + } + } + + open override var isHidden: Bool { + didSet { + if isHidden == true { + scrollView?.contentInset.bottom = scrollViewInsets.bottom + var rect = self.frame + rect.origin.y = scrollView?.contentSize.height ?? 0.0 + self.frame = rect + } else { + scrollView?.contentInset.bottom = scrollViewInsets.bottom + animator.executeIncremental + var rect = self.frame + rect.origin.y = scrollView?.contentSize.height ?? 0.0 + self.frame = rect + } + } + } + + public convenience init(frame: CGRect, handler: @escaping ESRefreshHandler) { + self.init(frame: frame) + self.handler = handler + self.animator = ESRefreshFooterAnimator.init() + } + + open override func willMove(toSuperview newSuperview: UIView?) { + super.willMove(toSuperview: newSuperview) + /* + DispatchQueue.main.async { + [weak self] in + // It's better + } + */ + } + + /** + In didMoveToSuperview, it will cache superview(UIScrollView)'s contentInset and update self's frame. + It called ESRefreshComponent's didMoveToSuperview. + */ + open override func didMoveToSuperview() { + super.didMoveToSuperview() + DispatchQueue.main.async { + [weak self] in + guard let weakSelf = self else { + return + } + weakSelf.scrollViewInsets = weakSelf.scrollView?.contentInset ?? UIEdgeInsets.zero + weakSelf.scrollView?.contentInset.bottom = weakSelf.scrollViewInsets.bottom + weakSelf.bounds.size.height + var rect = weakSelf.frame + rect.origin.y = weakSelf.scrollView?.contentSize.height ?? 0.0 + weakSelf.frame = rect + } + } + + open override func sizeChangeAction(object: AnyObject?, change: [NSKeyValueChangeKey : Any]?) { + guard let scrollView = scrollView else { return } + super.sizeChangeAction(object: object, change: change) + let targetY = scrollView.contentSize.height + scrollViewInsets.bottom + if self.frame.origin.y != targetY { + var rect = self.frame + rect.origin.y = targetY + self.frame = rect + } + } + + open override func offsetChangeAction(object: AnyObject?, change: [NSKeyValueChangeKey : Any]?) { + guard let scrollView = scrollView else { + return + } + + super.offsetChangeAction(object: object, change: change) + + guard isRefreshing == false && isAutoRefreshing == false && noMoreData == false && isHidden == false else { + // 正在loading more或者内容为空时不相应变化 + return + } + + if scrollView.contentSize.height <= 0.0 || scrollView.contentOffset.y + scrollView.contentInset.top <= 0.0 { + self.alpha = 0.0 + return + } else { + self.alpha = 1.0 + } + + if scrollView.contentSize.height + scrollView.contentInset.top > scrollView.bounds.size.height { + // 内容超过一个屏幕 计算公式,判断是不是在拖在到了底部 + if scrollView.contentSize.height - scrollView.contentOffset.y + scrollView.contentInset.bottom <= scrollView.bounds.size.height { + self.animator.refresh(view: self, stateDidChange: .refreshing) + self.startRefreshing() + } + } else { + //内容没有超过一个屏幕,这时拖拽高度大于1/2footer的高度就表示请求上拉 + if scrollView.contentOffset.y + scrollView.contentInset.top >= animator.trigger / 2.0 { + self.animator.refresh(view: self, stateDidChange: .refreshing) + self.startRefreshing() + } + } + } + + open override func start() { + guard let scrollView = scrollView else { + return + } + super.start() + + self.animator.refreshAnimationBegin(view: self) + + let x = scrollView.contentOffset.x + let y = max(0.0, scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom) + + // Call handler + UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveLinear, animations: { + scrollView.contentOffset = CGPoint.init(x: x, y: y) + }, completion: { (animated) in + self.handler?() + }) + } + + open override func stop() { + guard let scrollView = scrollView else { + return + } + + self.animator.refreshAnimationEnd(view: self) + + // Back state + UIView.animate(withDuration: 0.3, delay: 0, options: .curveLinear, animations: { + }, completion: { (finished) in + if self.noMoreData == false { + self.animator.refresh(view: self, stateDidChange: .pullToRefresh) + } + super.stop() + }) + + // Stop deceleration of UIScrollView. When the button tap event is caught, you read what the [scrollView contentOffset].x is, and set the offset to this value with animation OFF. + // http://stackoverflow.com/questions/2037892/stop-deceleration-of-uiscrollview + if scrollView.isDecelerating { + var contentOffset = scrollView.contentOffset + contentOffset.y = min(contentOffset.y, scrollView.contentSize.height - scrollView.frame.size.height) + if contentOffset.y < 0.0 { + contentOffset.y = 0.0 + UIView.animate(withDuration: 0.1, animations: { + scrollView.setContentOffset(contentOffset, animated: false) + }) + } else { + scrollView.setContentOffset(contentOffset, animated: false) + } + } + + } + + /// Change to no-more-data status. + open func noticeNoMoreData() { + self.noMoreData = true + } + + /// Reset no-more-data status. + open func resetNoMoreData() { + self.noMoreData = false + } + +} + diff --git a/Carthage/Checkouts/pull-to-refresh/Sources/ESRefreshAnimator.swift b/Carthage/Checkouts/pull-to-refresh/Sources/ESRefreshAnimator.swift new file mode 100644 index 0000000..f36cd19 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/Sources/ESRefreshAnimator.swift @@ -0,0 +1,65 @@ +// +// ESRefreshAnimator.swift +// +// Created by egg swift on 16/4/7. +// Copyright (c) 2013-2016 ESPullToRefresh (https://github.com/eggswift/pull-to-refresh) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +open class ESRefreshAnimator: ESRefreshProtocol, ESRefreshAnimatorProtocol { + // The view that called when component refresh, returns a custom view or self if 'self' is the customized views. + open var view: UIView + // Customized inset. + open var insets: UIEdgeInsets + // Refresh event is executed threshold required y offset, set a value greater than 0.0, the default is 60.0 + open var trigger: CGFloat = 60.0 + // Offset y refresh event executed by this parameter you can customize the animation to perform when you refresh the view of reservations height + open var executeIncremental: CGFloat = 60.0 + // Current refresh state, default is .pullToRefresh + open var state: ESRefreshViewState = .pullToRefresh + + public init() { + view = UIView() + insets = UIEdgeInsets.zero + } + + open func refreshAnimationBegin(view: ESRefreshComponent) { + /// Do nothing! + } + + open func refreshAnimationWillEnd(view: ESRefreshComponent) { + /// Do nothing! + } + + open func refreshAnimationEnd(view: ESRefreshComponent) { + /// Do nothing! + } + + open func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) { + /// Do nothing! + } + + open func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) { + /// Do nothing! + } +} diff --git a/Carthage/Checkouts/pull-to-refresh/Sources/ESRefreshComponent.swift b/Carthage/Checkouts/pull-to-refresh/Sources/ESRefreshComponent.swift new file mode 100644 index 0000000..8ff45a0 --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/Sources/ESRefreshComponent.swift @@ -0,0 +1,212 @@ +// +// ESRefreshComponent.swift +// +// Created by egg swift on 16/4/7. +// Copyright (c) 2013-2016 ESPullToRefresh (https://github.com/eggswift/pull-to-refresh) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +public typealias ESRefreshHandler = (() -> ()) + +open class ESRefreshComponent: UIView { + + open weak var scrollView: UIScrollView? + + /// @param handler Refresh callback method + open var handler: ESRefreshHandler? + + /// @param animator Animated view refresh controls, custom must comply with the following two protocol + open var animator: (ESRefreshProtocol & ESRefreshAnimatorProtocol)! + + /// @param refreshing or not + fileprivate var _isRefreshing = false + open var isRefreshing: Bool { + get { + return self._isRefreshing + } + } + + /// @param auto refreshing or not + fileprivate var _isAutoRefreshing = false + open var isAutoRefreshing: Bool { + get { + return self._isAutoRefreshing + } + } + + /// @param tag observing + fileprivate var isObservingScrollView = false + fileprivate var isIgnoreObserving = false + + public override init(frame: CGRect) { + super.init(frame: frame) + autoresizingMask = [.flexibleLeftMargin, .flexibleWidth, .flexibleRightMargin] + } + + public convenience init(frame: CGRect, handler: @escaping ESRefreshHandler) { + self.init(frame: frame) + self.handler = handler + self.animator = ESRefreshAnimator.init() + } + + public convenience init(frame: CGRect, handler: @escaping ESRefreshHandler, animator: ESRefreshProtocol & ESRefreshAnimatorProtocol) { + self.init(frame: frame) + self.handler = handler + self.animator = animator + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + deinit { + removeObserver() + } + + open override func willMove(toSuperview newSuperview: UIView?) { + super.willMove(toSuperview: newSuperview) + /// Remove observer from superview immediately + self.removeObserver() + DispatchQueue.main.async { [weak self, newSuperview] in + guard let weakSelf = self else { return } + /// Add observer to new superview in next runloop + weakSelf.addObserver(newSuperview) + } + } + + open override func didMoveToSuperview() { + super.didMoveToSuperview() + self.scrollView = self.superview as? UIScrollView + if let _ = animator { + let v = animator.view + if v.superview == nil { + let inset = animator.insets + self.addSubview(v) + v.frame = CGRect.init(x: inset.left, + y: inset.right, + width: self.bounds.size.width - inset.left - inset.right, + height: self.bounds.size.height - inset.top - inset.bottom) + v.autoresizingMask = [ + .flexibleWidth, + .flexibleTopMargin, + .flexibleHeight, + .flexibleBottomMargin + ] + } + } + } + +} + +extension ESRefreshComponent /* KVO methods */ { + + fileprivate static var context = "ESRefreshKVOContext" + fileprivate static let offsetKeyPath = "contentOffset" + fileprivate static let contentSizeKeyPath = "contentSize" + + public func ignoreObserver(_ ignore: Bool = false) { + if let scrollView = scrollView { + scrollView.isScrollEnabled = !ignore + } + isIgnoreObserving = ignore + } + + fileprivate func addObserver(_ view: UIView?) { + if let scrollView = view as? UIScrollView, !isObservingScrollView { + scrollView.addObserver(self, forKeyPath: ESRefreshComponent.offsetKeyPath, options: [.initial, .new], context: &ESRefreshComponent.context) + scrollView.addObserver(self, forKeyPath: ESRefreshComponent.contentSizeKeyPath, options: [.initial, .new], context: &ESRefreshComponent.context) + isObservingScrollView = true + } + } + + fileprivate func removeObserver() { + if let scrollView = superview as? UIScrollView, isObservingScrollView { + scrollView.removeObserver(self, forKeyPath: ESRefreshComponent.offsetKeyPath, context: &ESRefreshComponent.context) + scrollView.removeObserver(self, forKeyPath: ESRefreshComponent.contentSizeKeyPath, context: &ESRefreshComponent.context) + isObservingScrollView = false + } + } + + override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { + if context == &ESRefreshComponent.context { + guard isUserInteractionEnabled == true && isHidden == false else { + return + } + if keyPath == ESRefreshComponent.contentSizeKeyPath { + if isIgnoreObserving == false { + sizeChangeAction(object: object as AnyObject?, change: change) + } + } else if keyPath == ESRefreshComponent.offsetKeyPath { + if isIgnoreObserving == false { + offsetChangeAction(object: object as AnyObject?, change: change) + } + } + } else { + + } + } + +} + +public extension ESRefreshComponent /* Action */ { + + public final func startRefreshing(isAuto: Bool = false) -> Void { + guard isRefreshing == false && isAutoRefreshing == false else { + return + } + + _isRefreshing = !isAuto + _isAutoRefreshing = isAuto + + self.start() + } + + public final func stopRefreshing() -> Void { + guard isRefreshing == true || isAutoRefreshing == true else { + return + } + + self.stop() + } + + public func start() { + + } + + public func stop() { + _isRefreshing = false + _isAutoRefreshing = false + } + + // ScrollView contentSize change action + public func sizeChangeAction(object: AnyObject?, change: [NSKeyValueChangeKey : Any]?) { + + } + + // ScrollView offset change action + public func offsetChangeAction(object: AnyObject?, change: [NSKeyValueChangeKey : Any]?) { + + } + +} + diff --git a/Carthage/Checkouts/pull-to-refresh/Sources/ESRefreshProtocol.swift b/Carthage/Checkouts/pull-to-refresh/Sources/ESRefreshProtocol.swift new file mode 100644 index 0000000..b32ff3a --- /dev/null +++ b/Carthage/Checkouts/pull-to-refresh/Sources/ESRefreshProtocol.swift @@ -0,0 +1,118 @@ +// +// ESRefreshProtocol.swift +// +// Created by egg swift on 16/4/7. +// Copyright (c) 2013-2016 ESPullToRefresh (https://github.com/eggswift/pull-to-refresh) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import UIKit + +public enum ESRefreshViewState { + case pullToRefresh + case releaseToRefresh + case refreshing + case autoRefreshing + case noMoreData +} + +/** + * ESRefreshProtocol + * Animation event handling callback protocol + * You can customize the refresh or custom animation effects + * Mutating is to be able to modify or enum struct variable in the method - http://swifter.tips/protocol-mutation/ by ONEVCAT + */ +public protocol ESRefreshProtocol { + + /** + Refresh operation begins execution method + You can refresh your animation logic here, it will need to start the animation each time a refresh + */ + mutating func refreshAnimationBegin(view: ESRefreshComponent) + + /** + Refresh operation stop execution method + Here you can reset your refresh control UI, such as a Stop UIImageView animations or some opened Timer refresh, etc., it will be executed once each time the need to end the animation + */ + mutating func refreshAnimationEnd(view: ESRefreshComponent) + + /** + Pulling status callback , progress is the percentage of the current offset with trigger, and avoid doing too many tasks in this process so as not to affect the fluency. + */ + mutating func refresh(view: ESRefreshComponent, progressDidChange progress: CGFloat) + + mutating func refresh(view: ESRefreshComponent, stateDidChange state: ESRefreshViewState) +} + + +public protocol ESRefreshAnimatorProtocol { + + // The view that called when component refresh, returns a custom view or self if 'self' is the customized views. + var view: UIView {get} + + // Customized inset. + var insets: UIEdgeInsets {set get} + + // Refresh event is executed threshold required y offset, set a value greater than 0.0, the default is 60.0 + var trigger: CGFloat {set get} + + // Offset y refresh event executed by this parameter you can customize the animation to perform when you refresh the view of reservations height + var executeIncremental: CGFloat {set get} + + // Current refresh state, default is .pullToRefresh + var state: ESRefreshViewState {set get} + +} + +/** + * ESRefreshImpacter + * Support iPhone7/iPhone7 Plus or later feedback impact + * You can confirm the ESRefreshImpactProtocol + */ +fileprivate class ESRefreshImpacter { + static private var impacter: AnyObject? = { + if #available(iOS 10.0, *) { + if NSClassFromString("UIFeedbackGenerator") != nil { + let generator = UIImpactFeedbackGenerator.init(style: .light) + generator.prepare() + return generator + } + } + return nil + }() + + static open func impact() -> Void { + if #available(iOS 10.0, *) { + if let impacter = impacter as? UIImpactFeedbackGenerator { + impacter.impactOccurred() + } + } + } +} + +public protocol ESRefreshImpactProtocol {} +public extension ESRefreshImpactProtocol { + + public func impact() -> Void { + ESRefreshImpacter.impact() + } + +} diff --git a/Carthage/Checkouts/pull-to-refresh/example_default.gif b/Carthage/Checkouts/pull-to-refresh/example_default.gif new file mode 100644 index 0000000..241d067 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/example_default.gif differ diff --git a/Carthage/Checkouts/pull-to-refresh/example_meituan.gif b/Carthage/Checkouts/pull-to-refresh/example_meituan.gif new file mode 100644 index 0000000..9d19a67 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/example_meituan.gif differ diff --git a/Carthage/Checkouts/pull-to-refresh/example_wechat.gif b/Carthage/Checkouts/pull-to-refresh/example_wechat.gif new file mode 100644 index 0000000..e02878b Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/example_wechat.gif differ diff --git a/Carthage/Checkouts/pull-to-refresh/logo.png b/Carthage/Checkouts/pull-to-refresh/logo.png new file mode 100644 index 0000000..6523d75 Binary files /dev/null and b/Carthage/Checkouts/pull-to-refresh/logo.png differ diff --git a/Example/GodEye.xcodeproj/project.pbxproj b/Example/GodEye.xcodeproj/project.pbxproj index 13c3644..1567efe 100644 --- a/Example/GodEye.xcodeproj/project.pbxproj +++ b/Example/GodEye.xcodeproj/project.pbxproj @@ -15,6 +15,79 @@ 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; 99EF52E446A0B2DD16C5945C /* Pods_GodEye_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8CBB94DCF364B6182266AFF /* Pods_GodEye_Tests.framework */; }; 9E19FE3A1E25072E002A7398 /* DemoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E19FE391E25072E002A7398 /* DemoModel.swift */; }; + 9EA9D81F1E821D330045492A /* GodEye.h in Headers */ = {isa = PBXBuildFile; fileRef = 9EA9D81D1E821D330045492A /* GodEye.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9EA9D8751E821D440045492A /* eye@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9EA9D8261E821D440045492A /* eye@2x.png */; }; + 9EA9D8761E821D440045492A /* eye@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9EA9D8271E821D440045492A /* eye@3x.png */; }; + 9EA9D8781E821D440045492A /* CommandConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D82B1E821D440045492A /* CommandConfiguration.swift */; }; + 9EA9D8791E821D440045492A /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D82C1E821D440045492A /* Configuration.swift */; }; + 9EA9D87A1E821D440045492A /* ControlConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D82D1E821D440045492A /* ControlConfiguration.swift */; }; + 9EA9D87B1E821D440045492A /* SwitchConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D82E1E821D440045492A /* SwitchConfiguration.swift */; }; + 9EA9D87C1E821D440045492A /* GodEyeController+Show.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8301E821D440045492A /* GodEyeController+Show.swift */; }; + 9EA9D87D1E821D440045492A /* GodEyeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8311E821D440045492A /* GodEyeController.swift */; }; + 9EA9D87E1E821D440045492A /* ConsolePrintViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8331E821D440045492A /* ConsolePrintViewController.swift */; }; + 9EA9D87F1E821D440045492A /* ConsoleController+Eye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8361E821D440045492A /* ConsoleController+Eye.swift */; }; + 9EA9D8801E821D440045492A /* ConsoleController+TableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8371E821D440045492A /* ConsoleController+TableView.swift */; }; + 9EA9D8811E821D440045492A /* ConsoleController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8381E821D440045492A /* ConsoleController.swift */; }; + 9EA9D8821E821D440045492A /* EyesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8391E821D440045492A /* EyesManager.swift */; }; + 9EA9D8831E821D440045492A /* FileController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D83B1E821D440045492A /* FileController.swift */; }; + 9EA9D8841E821D440045492A /* MonitorContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D83D1E821D440045492A /* MonitorContainerView.swift */; }; + 9EA9D8851E821D440045492A /* MonitorController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D83E1E821D440045492A /* MonitorController.swift */; }; + 9EA9D8861E821D440045492A /* SettingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8401E821D440045492A /* SettingController.swift */; }; + 9EA9D8871E821D440045492A /* MonitorSystemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8421E821D440045492A /* MonitorSystemType.swift */; }; + 9EA9D8881E821D440045492A /* RecordType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8431E821D440045492A /* RecordType.swift */; }; + 9EA9D8891E821D440045492A /* Define.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8441E821D440045492A /* Define.swift */; }; + 9EA9D88A1E821D440045492A /* GodEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8451E821D440045492A /* GodEye.swift */; }; + 9EA9D88B1E821D440045492A /* ANRRecordModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8471E821D440045492A /* ANRRecordModel.swift */; }; + 9EA9D88C1E821D440045492A /* CommandRecordModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8481E821D440045492A /* CommandRecordModel.swift */; }; + 9EA9D88D1E821D440045492A /* CrashRecordModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8491E821D440045492A /* CrashRecordModel.swift */; }; + 9EA9D88E1E821D440045492A /* LeakRecordModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D84A1E821D440045492A /* LeakRecordModel.swift */; }; + 9EA9D88F1E821D440045492A /* LogRecordModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D84B1E821D440045492A /* LogRecordModel.swift */; }; + 9EA9D8901E821D440045492A /* NetworkRecordModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D84C1E821D440045492A /* NetworkRecordModel.swift */; }; + 9EA9D8911E821D440045492A /* ANRRecordModel+ORM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D84E1E821D440045492A /* ANRRecordModel+ORM.swift */; }; + 9EA9D8921E821D440045492A /* CommandRecordModel+ORM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D84F1E821D440045492A /* CommandRecordModel+ORM.swift */; }; + 9EA9D8931E821D440045492A /* CrashRecordModel+ORM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8501E821D440045492A /* CrashRecordModel+ORM.swift */; }; + 9EA9D8941E821D440045492A /* LeakRecordModel+ORM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8511E821D440045492A /* LeakRecordModel+ORM.swift */; }; + 9EA9D8951E821D440045492A /* LogRecordModel+ORM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8521E821D440045492A /* LogRecordModel+ORM.swift */; }; + 9EA9D8961E821D440045492A /* NetworkRecordModel+ORM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8531E821D440045492A /* NetworkRecordModel+ORM.swift */; }; + 9EA9D8971E821D440045492A /* ORMProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8541E821D440045492A /* ORMProtocol.swift */; }; + 9EA9D8981E821D440045492A /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8561E821D440045492A /* Store.swift */; }; + 9EA9D8991E821D440045492A /* UIFont+GodEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8571E821D440045492A /* UIFont+GodEye.swift */; }; + 9EA9D89A1E821D440045492A /* UIWindow+GodEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8581E821D440045492A /* UIWindow+GodEye.swift */; }; + 9EA9D89B1E821D440045492A /* Date+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D85B1E821D440045492A /* Date+.swift */; }; + 9EA9D89C1E821D440045492A /* String+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D85C1E821D440045492A /* String+.swift */; }; + 9EA9D89D1E821D440045492A /* Thread.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D85D1E821D440045492A /* Thread.swift */; }; + 9EA9D89E1E821D440045492A /* UITableView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D85E1E821D440045492A /* UITableView+.swift */; }; + 9EA9D89F1E821D440045492A /* UITableViewCell+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D85F1E821D440045492A /* UITableViewCell+.swift */; }; + 9EA9D8A01E821D440045492A /* Double+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8601E821D440045492A /* Double+.swift */; }; + 9EA9D8A11E821D440045492A /* UIApplication+GodEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8611E821D440045492A /* UIApplication+GodEye.swift */; }; + 9EA9D8A21E821D440045492A /* UIScreen+GodEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8621E821D440045492A /* UIScreen+GodEye.swift */; }; + 9EA9D8A31E821D440045492A /* UIView+GodEye.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8631E821D440045492A /* UIView+GodEye.swift */; }; + 9EA9D8A41E821D440045492A /* MonitorBaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8661E821D440045492A /* MonitorBaseView.swift */; }; + 9EA9D8A51E821D440045492A /* MonitorDeviceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8671E821D440045492A /* MonitorDeviceView.swift */; }; + 9EA9D8A61E821D440045492A /* MonitorSysNetFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8681E821D440045492A /* MonitorSysNetFlowView.swift */; }; + 9EA9D8A71E821D440045492A /* RecordTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D86A1E821D440045492A /* RecordTableView.swift */; }; + 9EA9D8A81E821D440045492A /* RecordTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D86B1E821D440045492A /* RecordTableViewCell.swift */; }; + 9EA9D8A91E821D440045492A /* ANRRecordViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D86D1E821D440045492A /* ANRRecordViewModel.swift */; }; + 9EA9D8AA1E821D440045492A /* BaseRecordViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D86E1E821D440045492A /* BaseRecordViewModel.swift */; }; + 9EA9D8AB1E821D440045492A /* CommandRecordViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D86F1E821D440045492A /* CommandRecordViewModel.swift */; }; + 9EA9D8AC1E821D440045492A /* CrashRecordViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8701E821D440045492A /* CrashRecordViewModel.swift */; }; + 9EA9D8AD1E821D440045492A /* LeakRecordViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8711E821D440045492A /* LeakRecordViewModel.swift */; }; + 9EA9D8AE1E821D440045492A /* LogRecordViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8721E821D440045492A /* LogRecordViewModel.swift */; }; + 9EA9D8AF1E821D440045492A /* NetworkRecordViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA9D8731E821D440045492A /* NetworkRecordViewModel.swift */; }; + 9EA9D8B11E821DB20045492A /* ANREye.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8B01E821DB20045492A /* ANREye.framework */; }; + 9EA9D8B31E821DB60045492A /* AppBaseKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8B21E821DB60045492A /* AppBaseKit.framework */; }; + 9EA9D8B51E821DB90045492A /* AppSwizzle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8B41E821DB90045492A /* AppSwizzle.framework */; }; + 9EA9D8B71E821DBD0045492A /* ASLEye.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8B61E821DBD0045492A /* ASLEye.framework */; }; + 9EA9D8B91E821DC20045492A /* AssistiveButton.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8B81E821DC20045492A /* AssistiveButton.framework */; }; + 9EA9D8BB1E821DCA0045492A /* CrashEye.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8BA1E821DCA0045492A /* CrashEye.framework */; }; + 9EA9D8BD1E821DD40045492A /* ESPullToRefresh.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8BC1E821DD40045492A /* ESPullToRefresh.framework */; }; + 9EA9D8BF1E821DD80045492A /* FileBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8BE1E821DD80045492A /* FileBrowser.framework */; }; + 9EA9D8C11E821DDE0045492A /* LeakEye.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8C01E821DDE0045492A /* LeakEye.framework */; }; + 9EA9D8C31E821DE20045492A /* Log4G.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8C21E821DE20045492A /* Log4G.framework */; }; + 9EA9D8C51E821DE60045492A /* NetworkEye.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8C41E821DE60045492A /* NetworkEye.framework */; }; + 9EA9D8C71E821DE90045492A /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8C61E821DE90045492A /* SQLite.framework */; }; + 9EA9D8C91E821DED0045492A /* SwViewCapture.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8C81E821DED0045492A /* SwViewCapture.framework */; }; + 9EA9D8CB1E821DF00045492A /* SystemEye.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EA9D8CA1E821DF00045492A /* SystemEye.framework */; }; D8BE7E202C2E7281CE37BBF5 /* Pods_GodEye_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD8E22232895D32D06FB834 /* Pods_GodEye_Example.framework */; }; /* End PBXBuildFile section */ @@ -44,6 +117,81 @@ 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 78C2A5A02918EC5DDB2CEB2F /* Pods-GodEye_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GodEye_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GodEye_Example/Pods-GodEye_Example.debug.xcconfig"; sourceTree = ""; }; 9E19FE391E25072E002A7398 /* DemoModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemoModel.swift; sourceTree = ""; }; + 9EA9D81B1E821D330045492A /* GodEye.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GodEye.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9EA9D81D1E821D330045492A /* GodEye.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GodEye.h; sourceTree = ""; }; + 9EA9D81E1E821D330045492A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9EA9D8261E821D440045492A /* eye@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "eye@2x.png"; sourceTree = ""; }; + 9EA9D8271E821D440045492A /* eye@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "eye@3x.png"; sourceTree = ""; }; + 9EA9D82B1E821D440045492A /* CommandConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandConfiguration.swift; sourceTree = ""; }; + 9EA9D82C1E821D440045492A /* Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; + 9EA9D82D1E821D440045492A /* ControlConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlConfiguration.swift; sourceTree = ""; }; + 9EA9D82E1E821D440045492A /* SwitchConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchConfiguration.swift; sourceTree = ""; }; + 9EA9D8301E821D440045492A /* GodEyeController+Show.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GodEyeController+Show.swift"; sourceTree = ""; }; + 9EA9D8311E821D440045492A /* GodEyeController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GodEyeController.swift; sourceTree = ""; }; + 9EA9D8331E821D440045492A /* ConsolePrintViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsolePrintViewController.swift; sourceTree = ""; }; + 9EA9D8361E821D440045492A /* ConsoleController+Eye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ConsoleController+Eye.swift"; sourceTree = ""; }; + 9EA9D8371E821D440045492A /* ConsoleController+TableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ConsoleController+TableView.swift"; sourceTree = ""; }; + 9EA9D8381E821D440045492A /* ConsoleController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsoleController.swift; sourceTree = ""; }; + 9EA9D8391E821D440045492A /* EyesManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EyesManager.swift; sourceTree = ""; }; + 9EA9D83B1E821D440045492A /* FileController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileController.swift; sourceTree = ""; }; + 9EA9D83D1E821D440045492A /* MonitorContainerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonitorContainerView.swift; sourceTree = ""; }; + 9EA9D83E1E821D440045492A /* MonitorController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonitorController.swift; sourceTree = ""; }; + 9EA9D8401E821D440045492A /* SettingController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingController.swift; sourceTree = ""; }; + 9EA9D8421E821D440045492A /* MonitorSystemType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonitorSystemType.swift; sourceTree = ""; }; + 9EA9D8431E821D440045492A /* RecordType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecordType.swift; sourceTree = ""; }; + 9EA9D8441E821D440045492A /* Define.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Define.swift; sourceTree = ""; }; + 9EA9D8451E821D440045492A /* GodEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GodEye.swift; sourceTree = ""; }; + 9EA9D8471E821D440045492A /* ANRRecordModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ANRRecordModel.swift; sourceTree = ""; }; + 9EA9D8481E821D440045492A /* CommandRecordModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandRecordModel.swift; sourceTree = ""; }; + 9EA9D8491E821D440045492A /* CrashRecordModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CrashRecordModel.swift; sourceTree = ""; }; + 9EA9D84A1E821D440045492A /* LeakRecordModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeakRecordModel.swift; sourceTree = ""; }; + 9EA9D84B1E821D440045492A /* LogRecordModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogRecordModel.swift; sourceTree = ""; }; + 9EA9D84C1E821D440045492A /* NetworkRecordModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkRecordModel.swift; sourceTree = ""; }; + 9EA9D84E1E821D440045492A /* ANRRecordModel+ORM.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ANRRecordModel+ORM.swift"; sourceTree = ""; }; + 9EA9D84F1E821D440045492A /* CommandRecordModel+ORM.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CommandRecordModel+ORM.swift"; sourceTree = ""; }; + 9EA9D8501E821D440045492A /* CrashRecordModel+ORM.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CrashRecordModel+ORM.swift"; sourceTree = ""; }; + 9EA9D8511E821D440045492A /* LeakRecordModel+ORM.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LeakRecordModel+ORM.swift"; sourceTree = ""; }; + 9EA9D8521E821D440045492A /* LogRecordModel+ORM.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LogRecordModel+ORM.swift"; sourceTree = ""; }; + 9EA9D8531E821D440045492A /* NetworkRecordModel+ORM.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NetworkRecordModel+ORM.swift"; sourceTree = ""; }; + 9EA9D8541E821D440045492A /* ORMProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ORMProtocol.swift; sourceTree = ""; }; + 9EA9D8561E821D440045492A /* Store.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = ""; }; + 9EA9D8571E821D440045492A /* UIFont+GodEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIFont+GodEye.swift"; sourceTree = ""; }; + 9EA9D8581E821D440045492A /* UIWindow+GodEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIWindow+GodEye.swift"; sourceTree = ""; }; + 9EA9D85B1E821D440045492A /* Date+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+.swift"; sourceTree = ""; }; + 9EA9D85C1E821D440045492A /* String+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+.swift"; sourceTree = ""; }; + 9EA9D85D1E821D440045492A /* Thread.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Thread.swift; sourceTree = ""; }; + 9EA9D85E1E821D440045492A /* UITableView+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+.swift"; sourceTree = ""; }; + 9EA9D85F1E821D440045492A /* UITableViewCell+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableViewCell+.swift"; sourceTree = ""; }; + 9EA9D8601E821D440045492A /* Double+.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Double+.swift"; sourceTree = ""; }; + 9EA9D8611E821D440045492A /* UIApplication+GodEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+GodEye.swift"; sourceTree = ""; }; + 9EA9D8621E821D440045492A /* UIScreen+GodEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIScreen+GodEye.swift"; sourceTree = ""; }; + 9EA9D8631E821D440045492A /* UIView+GodEye.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+GodEye.swift"; sourceTree = ""; }; + 9EA9D8661E821D440045492A /* MonitorBaseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonitorBaseView.swift; sourceTree = ""; }; + 9EA9D8671E821D440045492A /* MonitorDeviceView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonitorDeviceView.swift; sourceTree = ""; }; + 9EA9D8681E821D440045492A /* MonitorSysNetFlowView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonitorSysNetFlowView.swift; sourceTree = ""; }; + 9EA9D86A1E821D440045492A /* RecordTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecordTableView.swift; sourceTree = ""; }; + 9EA9D86B1E821D440045492A /* RecordTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecordTableViewCell.swift; sourceTree = ""; }; + 9EA9D86D1E821D440045492A /* ANRRecordViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ANRRecordViewModel.swift; sourceTree = ""; }; + 9EA9D86E1E821D440045492A /* BaseRecordViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseRecordViewModel.swift; sourceTree = ""; }; + 9EA9D86F1E821D440045492A /* CommandRecordViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandRecordViewModel.swift; sourceTree = ""; }; + 9EA9D8701E821D440045492A /* CrashRecordViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CrashRecordViewModel.swift; sourceTree = ""; }; + 9EA9D8711E821D440045492A /* LeakRecordViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeakRecordViewModel.swift; sourceTree = ""; }; + 9EA9D8721E821D440045492A /* LogRecordViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogRecordViewModel.swift; sourceTree = ""; }; + 9EA9D8731E821D440045492A /* NetworkRecordViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkRecordViewModel.swift; sourceTree = ""; }; + 9EA9D8B01E821DB20045492A /* ANREye.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ANREye.framework; path = ../Carthage/Build/iOS/ANREye.framework; sourceTree = ""; }; + 9EA9D8B21E821DB60045492A /* AppBaseKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppBaseKit.framework; path = ../Carthage/Build/iOS/AppBaseKit.framework; sourceTree = ""; }; + 9EA9D8B41E821DB90045492A /* AppSwizzle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppSwizzle.framework; path = ../Carthage/Build/iOS/AppSwizzle.framework; sourceTree = ""; }; + 9EA9D8B61E821DBD0045492A /* ASLEye.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ASLEye.framework; path = ../Carthage/Build/iOS/ASLEye.framework; sourceTree = ""; }; + 9EA9D8B81E821DC20045492A /* AssistiveButton.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssistiveButton.framework; path = ../Carthage/Build/iOS/AssistiveButton.framework; sourceTree = ""; }; + 9EA9D8BA1E821DCA0045492A /* CrashEye.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CrashEye.framework; path = ../Carthage/Build/iOS/CrashEye.framework; sourceTree = ""; }; + 9EA9D8BC1E821DD40045492A /* ESPullToRefresh.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ESPullToRefresh.framework; path = ../Carthage/Build/iOS/ESPullToRefresh.framework; sourceTree = ""; }; + 9EA9D8BE1E821DD80045492A /* FileBrowser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FileBrowser.framework; path = ../Carthage/Build/iOS/FileBrowser.framework; sourceTree = ""; }; + 9EA9D8C01E821DDE0045492A /* LeakEye.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LeakEye.framework; path = ../Carthage/Build/iOS/LeakEye.framework; sourceTree = ""; }; + 9EA9D8C21E821DE20045492A /* Log4G.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Log4G.framework; path = ../Carthage/Build/iOS/Log4G.framework; sourceTree = ""; }; + 9EA9D8C41E821DE60045492A /* NetworkEye.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkEye.framework; path = ../Carthage/Build/iOS/NetworkEye.framework; sourceTree = ""; }; + 9EA9D8C61E821DE90045492A /* SQLite.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SQLite.framework; path = ../Carthage/Build/iOS/SQLite.framework; sourceTree = ""; }; + 9EA9D8C81E821DED0045492A /* SwViewCapture.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwViewCapture.framework; path = ../Carthage/Build/iOS/SwViewCapture.framework; sourceTree = ""; }; + 9EA9D8CA1E821DF00045492A /* SystemEye.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemEye.framework; path = ../Carthage/Build/iOS/SystemEye.framework; sourceTree = ""; }; B7B09398705F2E997E16DF59 /* Pods-GodEye_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GodEye_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-GodEye_Tests/Pods-GodEye_Tests.release.xcconfig"; sourceTree = ""; }; C0ABE2AA0DC951C75EC55266 /* Pods-GodEye_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GodEye_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-GodEye_Example/Pods-GodEye_Example.release.xcconfig"; sourceTree = ""; }; DAD8E22232895D32D06FB834 /* Pods_GodEye_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GodEye_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -68,6 +216,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9EA9D8171E821D330045492A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EA9D8BD1E821DD40045492A /* ESPullToRefresh.framework in Frameworks */, + 9EA9D8B11E821DB20045492A /* ANREye.framework in Frameworks */, + 9EA9D8B31E821DB60045492A /* AppBaseKit.framework in Frameworks */, + 9EA9D8B51E821DB90045492A /* AppSwizzle.framework in Frameworks */, + 9EA9D8B91E821DC20045492A /* AssistiveButton.framework in Frameworks */, + 9EA9D8B71E821DBD0045492A /* ASLEye.framework in Frameworks */, + 9EA9D8BF1E821DD80045492A /* FileBrowser.framework in Frameworks */, + 9EA9D8C31E821DE20045492A /* Log4G.framework in Frameworks */, + 9EA9D8C11E821DDE0045492A /* LeakEye.framework in Frameworks */, + 9EA9D8C71E821DE90045492A /* SQLite.framework in Frameworks */, + 9EA9D8C51E821DE60045492A /* NetworkEye.framework in Frameworks */, + 9EA9D8CB1E821DF00045492A /* SystemEye.framework in Frameworks */, + 9EA9D8C91E821DED0045492A /* SwViewCapture.framework in Frameworks */, + 9EA9D8BB1E821DCA0045492A /* CrashEye.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -88,6 +257,7 @@ 607FACF51AFB993E008FA782 /* Podspec Metadata */, 607FACD21AFB9204008FA782 /* Example for GodEye */, 607FACE81AFB9204008FA782 /* Tests */, + 9EA9D81C1E821D330045492A /* GodEye */, 607FACD11AFB9204008FA782 /* Products */, 5459B87DAFE08EC274CCF455 /* Pods */, E4499FB9EECF304E2155F820 /* Frameworks */, @@ -99,6 +269,7 @@ children = ( 607FACD01AFB9204008FA782 /* GodEye_Example.app */, 607FACE51AFB9204008FA782 /* GodEye_Tests.xctest */, + 9EA9D81B1E821D330045492A /* GodEye.framework */, ); name = Products; sourceTree = ""; @@ -153,9 +324,259 @@ name = "Podspec Metadata"; sourceTree = ""; }; + 9EA9D81C1E821D330045492A /* GodEye */ = { + isa = PBXGroup; + children = ( + 9EA9D8231E821D440045492A /* GodEye */, + 9EA9D81D1E821D330045492A /* GodEye.h */, + 9EA9D81E1E821D330045492A /* Info.plist */, + ); + path = GodEye; + sourceTree = ""; + }; + 9EA9D8231E821D440045492A /* GodEye */ = { + isa = PBXGroup; + children = ( + 9EA9D8241E821D440045492A /* Assets */, + 9EA9D8281E821D440045492A /* Classes */, + ); + name = GodEye; + path = ../../GodEye; + sourceTree = ""; + }; + 9EA9D8241E821D440045492A /* Assets */ = { + isa = PBXGroup; + children = ( + 9EA9D8261E821D440045492A /* eye@2x.png */, + 9EA9D8271E821D440045492A /* eye@3x.png */, + ); + path = Assets; + sourceTree = ""; + }; + 9EA9D8281E821D440045492A /* Classes */ = { + isa = PBXGroup; + children = ( + 9EA9D82A1E821D440045492A /* Configuration */, + 9EA9D82F1E821D440045492A /* Controller */, + 9EA9D8411E821D440045492A /* Define */, + 9EA9D8441E821D440045492A /* Define.swift */, + 9EA9D8451E821D440045492A /* GodEye.swift */, + 9EA9D8461E821D440045492A /* Model */, + 9EA9D84D1E821D440045492A /* ORM */, + 9EA9D8551E821D440045492A /* Store */, + 9EA9D8571E821D440045492A /* UIFont+GodEye.swift */, + 9EA9D8581E821D440045492A /* UIWindow+GodEye.swift */, + 9EA9D8591E821D440045492A /* Util */, + 9EA9D8641E821D440045492A /* View */, + 9EA9D86C1E821D440045492A /* ViewModel */, + ); + path = Classes; + sourceTree = ""; + }; + 9EA9D82A1E821D440045492A /* Configuration */ = { + isa = PBXGroup; + children = ( + 9EA9D82B1E821D440045492A /* CommandConfiguration.swift */, + 9EA9D82C1E821D440045492A /* Configuration.swift */, + 9EA9D82D1E821D440045492A /* ControlConfiguration.swift */, + 9EA9D82E1E821D440045492A /* SwitchConfiguration.swift */, + ); + path = Configuration; + sourceTree = ""; + }; + 9EA9D82F1E821D440045492A /* Controller */ = { + isa = PBXGroup; + children = ( + 9EA9D8301E821D440045492A /* GodEyeController+Show.swift */, + 9EA9D8311E821D440045492A /* GodEyeController.swift */, + 9EA9D8321E821D440045492A /* Sub */, + 9EA9D8341E821D440045492A /* TabController */, + ); + path = Controller; + sourceTree = ""; + }; + 9EA9D8321E821D440045492A /* Sub */ = { + isa = PBXGroup; + children = ( + 9EA9D8331E821D440045492A /* ConsolePrintViewController.swift */, + ); + path = Sub; + sourceTree = ""; + }; + 9EA9D8341E821D440045492A /* TabController */ = { + isa = PBXGroup; + children = ( + 9EA9D8351E821D440045492A /* ConsoleController */, + 9EA9D83A1E821D440045492A /* FileController */, + 9EA9D83C1E821D440045492A /* MonitorController */, + 9EA9D83F1E821D440045492A /* SettingController */, + ); + path = TabController; + sourceTree = ""; + }; + 9EA9D8351E821D440045492A /* ConsoleController */ = { + isa = PBXGroup; + children = ( + 9EA9D8361E821D440045492A /* ConsoleController+Eye.swift */, + 9EA9D8371E821D440045492A /* ConsoleController+TableView.swift */, + 9EA9D8381E821D440045492A /* ConsoleController.swift */, + 9EA9D8391E821D440045492A /* EyesManager.swift */, + ); + path = ConsoleController; + sourceTree = ""; + }; + 9EA9D83A1E821D440045492A /* FileController */ = { + isa = PBXGroup; + children = ( + 9EA9D83B1E821D440045492A /* FileController.swift */, + ); + path = FileController; + sourceTree = ""; + }; + 9EA9D83C1E821D440045492A /* MonitorController */ = { + isa = PBXGroup; + children = ( + 9EA9D83D1E821D440045492A /* MonitorContainerView.swift */, + 9EA9D83E1E821D440045492A /* MonitorController.swift */, + ); + path = MonitorController; + sourceTree = ""; + }; + 9EA9D83F1E821D440045492A /* SettingController */ = { + isa = PBXGroup; + children = ( + 9EA9D8401E821D440045492A /* SettingController.swift */, + ); + path = SettingController; + sourceTree = ""; + }; + 9EA9D8411E821D440045492A /* Define */ = { + isa = PBXGroup; + children = ( + 9EA9D8421E821D440045492A /* MonitorSystemType.swift */, + 9EA9D8431E821D440045492A /* RecordType.swift */, + ); + path = Define; + sourceTree = ""; + }; + 9EA9D8461E821D440045492A /* Model */ = { + isa = PBXGroup; + children = ( + 9EA9D8471E821D440045492A /* ANRRecordModel.swift */, + 9EA9D8481E821D440045492A /* CommandRecordModel.swift */, + 9EA9D8491E821D440045492A /* CrashRecordModel.swift */, + 9EA9D84A1E821D440045492A /* LeakRecordModel.swift */, + 9EA9D84B1E821D440045492A /* LogRecordModel.swift */, + 9EA9D84C1E821D440045492A /* NetworkRecordModel.swift */, + ); + path = Model; + sourceTree = ""; + }; + 9EA9D84D1E821D440045492A /* ORM */ = { + isa = PBXGroup; + children = ( + 9EA9D84E1E821D440045492A /* ANRRecordModel+ORM.swift */, + 9EA9D84F1E821D440045492A /* CommandRecordModel+ORM.swift */, + 9EA9D8501E821D440045492A /* CrashRecordModel+ORM.swift */, + 9EA9D8511E821D440045492A /* LeakRecordModel+ORM.swift */, + 9EA9D8521E821D440045492A /* LogRecordModel+ORM.swift */, + 9EA9D8531E821D440045492A /* NetworkRecordModel+ORM.swift */, + 9EA9D8541E821D440045492A /* ORMProtocol.swift */, + ); + path = ORM; + sourceTree = ""; + }; + 9EA9D8551E821D440045492A /* Store */ = { + isa = PBXGroup; + children = ( + 9EA9D8561E821D440045492A /* Store.swift */, + ); + path = Store; + sourceTree = ""; + }; + 9EA9D8591E821D440045492A /* Util */ = { + isa = PBXGroup; + children = ( + 9EA9D85A1E821D440045492A /* Base */, + 9EA9D8601E821D440045492A /* Double+.swift */, + 9EA9D8611E821D440045492A /* UIApplication+GodEye.swift */, + 9EA9D8621E821D440045492A /* UIScreen+GodEye.swift */, + 9EA9D8631E821D440045492A /* UIView+GodEye.swift */, + ); + path = Util; + sourceTree = ""; + }; + 9EA9D85A1E821D440045492A /* Base */ = { + isa = PBXGroup; + children = ( + 9EA9D85B1E821D440045492A /* Date+.swift */, + 9EA9D85C1E821D440045492A /* String+.swift */, + 9EA9D85D1E821D440045492A /* Thread.swift */, + 9EA9D85E1E821D440045492A /* UITableView+.swift */, + 9EA9D85F1E821D440045492A /* UITableViewCell+.swift */, + ); + path = Base; + sourceTree = ""; + }; + 9EA9D8641E821D440045492A /* View */ = { + isa = PBXGroup; + children = ( + 9EA9D8651E821D440045492A /* Monitor */, + 9EA9D8691E821D440045492A /* RecordTableView */, + ); + path = View; + sourceTree = ""; + }; + 9EA9D8651E821D440045492A /* Monitor */ = { + isa = PBXGroup; + children = ( + 9EA9D8661E821D440045492A /* MonitorBaseView.swift */, + 9EA9D8671E821D440045492A /* MonitorDeviceView.swift */, + 9EA9D8681E821D440045492A /* MonitorSysNetFlowView.swift */, + ); + path = Monitor; + sourceTree = ""; + }; + 9EA9D8691E821D440045492A /* RecordTableView */ = { + isa = PBXGroup; + children = ( + 9EA9D86A1E821D440045492A /* RecordTableView.swift */, + 9EA9D86B1E821D440045492A /* RecordTableViewCell.swift */, + ); + path = RecordTableView; + sourceTree = ""; + }; + 9EA9D86C1E821D440045492A /* ViewModel */ = { + isa = PBXGroup; + children = ( + 9EA9D86D1E821D440045492A /* ANRRecordViewModel.swift */, + 9EA9D86E1E821D440045492A /* BaseRecordViewModel.swift */, + 9EA9D86F1E821D440045492A /* CommandRecordViewModel.swift */, + 9EA9D8701E821D440045492A /* CrashRecordViewModel.swift */, + 9EA9D8711E821D440045492A /* LeakRecordViewModel.swift */, + 9EA9D8721E821D440045492A /* LogRecordViewModel.swift */, + 9EA9D8731E821D440045492A /* NetworkRecordViewModel.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; E4499FB9EECF304E2155F820 /* Frameworks */ = { isa = PBXGroup; children = ( + 9EA9D8CA1E821DF00045492A /* SystemEye.framework */, + 9EA9D8C81E821DED0045492A /* SwViewCapture.framework */, + 9EA9D8C61E821DE90045492A /* SQLite.framework */, + 9EA9D8C41E821DE60045492A /* NetworkEye.framework */, + 9EA9D8C21E821DE20045492A /* Log4G.framework */, + 9EA9D8C01E821DDE0045492A /* LeakEye.framework */, + 9EA9D8BE1E821DD80045492A /* FileBrowser.framework */, + 9EA9D8BC1E821DD40045492A /* ESPullToRefresh.framework */, + 9EA9D8BA1E821DCA0045492A /* CrashEye.framework */, + 9EA9D8B81E821DC20045492A /* AssistiveButton.framework */, + 9EA9D8B61E821DBD0045492A /* ASLEye.framework */, + 9EA9D8B41E821DB90045492A /* AppSwizzle.framework */, + 9EA9D8B21E821DB60045492A /* AppBaseKit.framework */, + 9EA9D8B01E821DB20045492A /* ANREye.framework */, DAD8E22232895D32D06FB834 /* Pods_GodEye_Example.framework */, E8CBB94DCF364B6182266AFF /* Pods_GodEye_Tests.framework */, ); @@ -164,6 +585,17 @@ }; /* End PBXGroup section */ +/* Begin PBXHeadersBuildPhase section */ + 9EA9D8181E821D330045492A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EA9D81F1E821D330045492A /* GodEye.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + /* Begin PBXNativeTarget section */ 607FACCF1AFB9204008FA782 /* GodEye_Example */ = { isa = PBXNativeTarget; @@ -206,6 +638,25 @@ productReference = 607FACE51AFB9204008FA782 /* GodEye_Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 9EA9D81A1E821D330045492A /* GodEye */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9EA9D8221E821D330045492A /* Build configuration list for PBXNativeTarget "GodEye" */; + buildPhases = ( + 9EA9D8161E821D330045492A /* Sources */, + 9EA9D8171E821D330045492A /* Frameworks */, + 9EA9D8181E821D330045492A /* Headers */, + 9EA9D8191E821D330045492A /* Resources */, + 9EA9D8CC1E821DFE0045492A /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GodEye; + productName = GodEye; + productReference = 9EA9D81B1E821D330045492A /* GodEye.framework */; + productType = "com.apple.product-type.framework"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -227,6 +678,11 @@ LastSwiftMigration = 0810; TestTargetID = 607FACCF1AFB9204008FA782; }; + 9EA9D81A1E821D330045492A = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = L35WZWVC98; + ProvisioningStyle = Automatic; + }; }; }; buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "GodEye" */; @@ -244,6 +700,7 @@ targets = ( 607FACCF1AFB9204008FA782 /* GodEye_Example */, 607FACE41AFB9204008FA782 /* GodEye_Tests */, + 9EA9D81A1E821D330045492A /* GodEye */, ); }; /* End PBXProject section */ @@ -266,6 +723,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9EA9D8191E821D330045492A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EA9D8751E821D440045492A /* eye@2x.png in Resources */, + 9EA9D8761E821D440045492A /* eye@3x.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -299,6 +765,33 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-GodEye_Example/Pods-GodEye_Example-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 9EA9D8CC1E821DFE0045492A /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/../Carthage/Build/iOS/ESPullToRefresh.framework", + "$(SRCROOT)/../Carthage/Build/iOS/ANREye.framework", + "$(SRCROOT)/../Carthage/Build/iOS/AppBaseKit.framework", + "$(SRCROOT)/../Carthage/Build/iOS/AppSwizzle.framework", + "$(SRCROOT)/../Carthage/Build/iOS/AssistiveButton.framework", + "$(SRCROOT)/../Carthage/Build/iOS/ASLEye.framework", + "$(SRCROOT)/../Carthage/Build/iOS/FileBrowser.framework", + "$(SRCROOT)/../Carthage/Build/iOS/Log4G.framework", + "$(SRCROOT)/../Carthage/Build/iOS/LeakEye.framework", + "$(SRCROOT)/../Carthage/Build/iOS/SQLite.framework", + "$(SRCROOT)/../Carthage/Build/iOS/NetworkEye.framework", + "$(SRCROOT)/../Carthage/Build/iOS/SystemEye.framework", + "$(SRCROOT)/../Carthage/Build/iOS/SwViewCapture.framework", + "$(SRCROOT)/../Carthage/Build/iOS/CrashEye.framework", + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/usr/local/bin/carthage copy-frameworks"; + }; D338EB86C330D7964F049BF8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -380,6 +873,69 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9EA9D8161E821D330045492A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9EA9D8861E821D440045492A /* SettingController.swift in Sources */, + 9EA9D88A1E821D440045492A /* GodEye.swift in Sources */, + 9EA9D8871E821D440045492A /* MonitorSystemType.swift in Sources */, + 9EA9D89D1E821D440045492A /* Thread.swift in Sources */, + 9EA9D87A1E821D440045492A /* ControlConfiguration.swift in Sources */, + 9EA9D88B1E821D440045492A /* ANRRecordModel.swift in Sources */, + 9EA9D8A41E821D440045492A /* MonitorBaseView.swift in Sources */, + 9EA9D89C1E821D440045492A /* String+.swift in Sources */, + 9EA9D8791E821D440045492A /* Configuration.swift in Sources */, + 9EA9D8A81E821D440045492A /* RecordTableViewCell.swift in Sources */, + 9EA9D8981E821D440045492A /* Store.swift in Sources */, + 9EA9D88E1E821D440045492A /* LeakRecordModel.swift in Sources */, + 9EA9D8851E821D440045492A /* MonitorController.swift in Sources */, + 9EA9D8AE1E821D440045492A /* LogRecordViewModel.swift in Sources */, + 9EA9D8951E821D440045492A /* LogRecordModel+ORM.swift in Sources */, + 9EA9D8921E821D440045492A /* CommandRecordModel+ORM.swift in Sources */, + 9EA9D89F1E821D440045492A /* UITableViewCell+.swift in Sources */, + 9EA9D87D1E821D440045492A /* GodEyeController.swift in Sources */, + 9EA9D8A31E821D440045492A /* UIView+GodEye.swift in Sources */, + 9EA9D88F1E821D440045492A /* LogRecordModel.swift in Sources */, + 9EA9D8A71E821D440045492A /* RecordTableView.swift in Sources */, + 9EA9D8991E821D440045492A /* UIFont+GodEye.swift in Sources */, + 9EA9D8AA1E821D440045492A /* BaseRecordViewModel.swift in Sources */, + 9EA9D8AD1E821D440045492A /* LeakRecordViewModel.swift in Sources */, + 9EA9D8971E821D440045492A /* ORMProtocol.swift in Sources */, + 9EA9D8A21E821D440045492A /* UIScreen+GodEye.swift in Sources */, + 9EA9D8AC1E821D440045492A /* CrashRecordViewModel.swift in Sources */, + 9EA9D8831E821D440045492A /* FileController.swift in Sources */, + 9EA9D8AB1E821D440045492A /* CommandRecordViewModel.swift in Sources */, + 9EA9D8A11E821D440045492A /* UIApplication+GodEye.swift in Sources */, + 9EA9D8A91E821D440045492A /* ANRRecordViewModel.swift in Sources */, + 9EA9D8961E821D440045492A /* NetworkRecordModel+ORM.swift in Sources */, + 9EA9D8911E821D440045492A /* ANRRecordModel+ORM.swift in Sources */, + 9EA9D8811E821D440045492A /* ConsoleController.swift in Sources */, + 9EA9D88D1E821D440045492A /* CrashRecordModel.swift in Sources */, + 9EA9D8931E821D440045492A /* CrashRecordModel+ORM.swift in Sources */, + 9EA9D89A1E821D440045492A /* UIWindow+GodEye.swift in Sources */, + 9EA9D87F1E821D440045492A /* ConsoleController+Eye.swift in Sources */, + 9EA9D87E1E821D440045492A /* ConsolePrintViewController.swift in Sources */, + 9EA9D8891E821D440045492A /* Define.swift in Sources */, + 9EA9D8941E821D440045492A /* LeakRecordModel+ORM.swift in Sources */, + 9EA9D8A61E821D440045492A /* MonitorSysNetFlowView.swift in Sources */, + 9EA9D8841E821D440045492A /* MonitorContainerView.swift in Sources */, + 9EA9D89B1E821D440045492A /* Date+.swift in Sources */, + 9EA9D8AF1E821D440045492A /* NetworkRecordViewModel.swift in Sources */, + 9EA9D88C1E821D440045492A /* CommandRecordModel.swift in Sources */, + 9EA9D8801E821D440045492A /* ConsoleController+TableView.swift in Sources */, + 9EA9D8A01E821D440045492A /* Double+.swift in Sources */, + 9EA9D8881E821D440045492A /* RecordType.swift in Sources */, + 9EA9D89E1E821D440045492A /* UITableView+.swift in Sources */, + 9EA9D8821E821D440045492A /* EyesManager.swift in Sources */, + 9EA9D8A51E821D440045492A /* MonitorDeviceView.swift in Sources */, + 9EA9D87B1E821D440045492A /* SwitchConfiguration.swift in Sources */, + 9EA9D8901E821D440045492A /* NetworkRecordModel.swift in Sources */, + 9EA9D8781E821D440045492A /* CommandConfiguration.swift in Sources */, + 9EA9D87C1E821D440045492A /* GodEyeController+Show.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -560,6 +1116,67 @@ }; name = Release; }; + 9EA9D8201E821D330045492A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../Carthage/Build/iOS/**"; + INFOPLIST_FILE = GodEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.GodEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9EA9D8211E821D330045492A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = L35WZWVC98; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../Carthage/Build/iOS/**"; + INFOPLIST_FILE = GodEye/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zixun.GodEye; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -590,6 +1207,14 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 9EA9D8221E821D330045492A /* Build configuration list for PBXNativeTarget "GodEye" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9EA9D8201E821D330045492A /* Debug */, + 9EA9D8211E821D330045492A /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; /* End XCConfigurationList section */ }; rootObject = 607FACC81AFB9204008FA782 /* Project object */; diff --git a/Example/GodEye.xcodeproj/project.xcworkspace/xcshareddata/GodEye.xcscmblueprint b/Example/GodEye.xcodeproj/project.xcworkspace/xcshareddata/GodEye.xcscmblueprint new file mode 100644 index 0000000..86a7811 --- /dev/null +++ b/Example/GodEye.xcodeproj/project.xcworkspace/xcshareddata/GodEye.xcscmblueprint @@ -0,0 +1,30 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "D3F7DA3A34E95B1AC5044B6CB97109AB59A9DCA3", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "D3F7DA3A34E95B1AC5044B6CB97109AB59A9DCA3" : 9223372036854775807, + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : 9223372036854775807 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "2DEA37E2-1A78-482B-B30F-1E9A33E136B6", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "D3F7DA3A34E95B1AC5044B6CB97109AB59A9DCA3" : "GodEye\/", + "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" : "..\/.." + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "GodEye", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Example\/GodEye.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.oschina.net:zixunapp\/AppSaber-MAC.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BF1F56C483977AC36F575A9C50FB74A7EFF41C69" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zixun\/GodEye.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "D3F7DA3A34E95B1AC5044B6CB97109AB59A9DCA3" + } + ] +} \ No newline at end of file diff --git a/Example/GodEye.xcodeproj/xcshareddata/xcschemes/GodEye.xcscheme b/Example/GodEye.xcodeproj/xcshareddata/xcschemes/GodEye.xcscheme new file mode 100644 index 0000000..a9bfd68 --- /dev/null +++ b/Example/GodEye.xcodeproj/xcshareddata/xcschemes/GodEye.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/GodEye/GodEye.h b/Example/GodEye/GodEye.h new file mode 100644 index 0000000..0e39c14 --- /dev/null +++ b/Example/GodEye/GodEye.h @@ -0,0 +1,19 @@ +// +// GodEye.h +// GodEye +// +// Created by zixun on 2017/3/22. +// Copyright © 2017年 CocoaPods. All rights reserved. +// + +#import + +//! Project version number for GodEye. +FOUNDATION_EXPORT double GodEyeVersionNumber; + +//! Project version string for GodEye. +FOUNDATION_EXPORT const unsigned char GodEyeVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Example/GodEye/Info.plist b/Example/GodEye/Info.plist index eb18faa..fbe1e6b 100644 --- a/Example/GodEye/Info.plist +++ b/Example/GodEye/Info.plist @@ -13,27 +13,12 @@ CFBundleName $(PRODUCT_NAME) CFBundlePackageType - APPL + FMWK CFBundleShortVersionString 1.0 - CFBundleSignature - ???? CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + diff --git a/Example/Podfile.lock b/Example/Podfile.lock index b49c5f7..748f8e6 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,37 +1,37 @@ PODS: - - ANREye (1.0.0) - - AppBaseKit (0.1.0) - - AppSwizzle (1.0.0) - - ASLEye (1.0.0) - - AssistiveButton (1.0.0) - - CrashEye (1.0.1) + - ANREye (1.1.0) + - AppBaseKit (0.2.0) + - AppSwizzle (1.1.1) + - ASLEye (1.1.0) + - AssistiveButton (1.1.0) + - CrashEye (1.1.0) + - ESPullToRefresh (2.6) - FileBrowser (0.2.0) - - GodEye (1.0.1): - - ANREye (~> 1.0.0) - - AppBaseKit - - AppSwizzle (~> 1.0.0) - - ASLEye (~> 1.0.0) - - AssistiveButton (~> 1.0.0) - - CrashEye (~> 1.0.1) + - GodEye (1.0.2): + - ANREye (~> 1.1.0) + - AppBaseKit (~> 0.2.0) + - AppSwizzle (~> 1.1.1) + - ASLEye (~> 1.1.0) + - AssistiveButton (~> 1.1.0) + - CrashEye (~> 1.1.0) + - ESPullToRefresh (~> 2.6) - FileBrowser (~> 0.2.0) - - LeakEye (~> 1.0.0) - - Log4G (~> 0.1.1) - - MJRefresh (~> 3.1.12) - - NetworkEye.swift (~> 1.0.0) + - LeakEye (~> 1.1.1) + - Log4G (~> 0.2.0) + - NetworkEye.swift (~> 1.1.1) - SQLite.swift (~> 0.11.1) - SwViewCapture (~> 1.0.5) - - SystemEye (~> 0.1.0) - - LeakEye (1.0.0): - - AppSwizzle (~> 1.0.0) - - Log4G (0.1.2) - - MJRefresh (3.1.12) - - NetworkEye.swift (1.0.0): - - AppSwizzle (~> 1.0.0) + - SystemEye (~> 0.2.0) + - LeakEye (1.1.1): + - AppSwizzle (~> 1.1.1) + - Log4G (0.2.0) + - NetworkEye.swift (1.1.1): + - AppSwizzle (~> 1.1.1) - SQLite.swift (0.11.2): - SQLite.swift/standard (= 0.11.2) - SQLite.swift/standard (0.11.2) - SwViewCapture (1.0.5) - - SystemEye (0.1.0) + - SystemEye (0.2.0) DEPENDENCIES: - GodEye (from `../`) @@ -41,21 +41,21 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - ANREye: a3c65dfdcf027f70cf2967ee2bca8c92c01464ef - AppBaseKit: 5bc9211a560e7bd3afb48ed5b2cc303fc2e4073c - AppSwizzle: 0ba5dc3d884a5315a89ac4ab08c7f8e1c85c795c - ASLEye: 486cae91913d54266201b6392ea00df33b316f07 - AssistiveButton: 562aae28b8875b107ea468ccce1b932ff50ac866 - CrashEye: 1f08b89b46d65c752277ea12d43bc2c1fa84ef9f + ANREye: f5d8afdfa695af4bd08ecb8d370d5e85b570e14a + AppBaseKit: 41da67c2456b8acaf4e7a8ec646bb2d1370fa7ef + AppSwizzle: ff4ae6735b6e2bab9991d5b660357beae2fa6e68 + ASLEye: 88490116e798292fbf28f9b08a354dadfcffc4c2 + AssistiveButton: 1af6cd2cdcb5b5cb87808cd965ae72b76dae2f0d + CrashEye: 22e4daeb27f30bed7fd034edd413100b84ac45c5 + ESPullToRefresh: 85f4990acf87f78c6a1466bbbee7a75d7de24db9 FileBrowser: af8abc035daca66a6066351ae162c4af4c6b24dd - GodEye: 0b83875aaf1320a0512e3fd5fa28df68dc766e77 - LeakEye: 0797226c1415d2c69fdb4085866f47d7b5aeeac3 - Log4G: 28bc441d103633ea02962dd6ffa238388304e2fb - MJRefresh: b96cdb21c4aa75a7b07654311ab2f315c497e806 - NetworkEye.swift: cec9c0e73ebda143679751e047bce14ad96cccbc + GodEye: a4f62b0fbb3a186aa76f011ff5eca36c4cd8842e + LeakEye: 277f708e88acc6816950663d21f8808e26aaa754 + Log4G: f04fe4e1beb2e7e72e8467b17da07f9ce124130d + NetworkEye.swift: 5eb24e1c9d396c714c48005461a598fdf2195168 SQLite.swift: 670c3e9e0a806bbfd56a3de5d530768dc0e6fe7c SwViewCapture: 7ddb627ffbc70b21d92690bf25a84e545c38083e - SystemEye: efee11d6f355d91daddb2cb69fb844f1038df956 + SystemEye: d6c5ec3e39a0a75d51e4bebd1cfc15a58effed35 PODFILE CHECKSUM: 9877fa90d1c0cee190e1a39a22342801b9f1adb4 diff --git a/GodEye.podspec b/GodEye.podspec index 3ef3255..fee46c4 100644 --- a/GodEye.podspec +++ b/GodEye.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'GodEye' - s.version = '1.0.2' + s.version = '1.1.0' s.summary = 'Automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code based on Swift. Just like God opened his eyes.' # This description is used to generate tags and improve search results. @@ -39,20 +39,21 @@ Automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and et # s.public_header_files = 'Pod/Classes/**/*.h' # s.frameworks = 'UIKit', 'MapKit' - s.dependency 'AppBaseKit' - s.dependency 'Log4G', '~> 0.1.1' - s.dependency 'AppSwizzle', '~> 1.0.0' - s.dependency 'AssistiveButton', '~> 1.0.0' + s.dependency 'AppBaseKit', '~> 0.2.0' + s.dependency 'Log4G', '~> 0.2.0' + s.dependency 'AppSwizzle', '~> 1.1.1' + s.dependency 'AssistiveButton', '~> 1.1.0' - s.dependency 'ASLEye', '~> 1.0.0' - s.dependency 'CrashEye', '~> 1.0.1' - s.dependency 'ANREye', '~> 1.0.0' - s.dependency 'SystemEye', '~> 0.1.0' - s.dependency 'NetworkEye.swift', '~> 1.0.0' - s.dependency 'LeakEye', '~> 1.0.0' + s.dependency 'ASLEye', '~> 1.1.0' + s.dependency 'CrashEye', '~> 1.1.0' + s.dependency 'ANREye', '~> 1.1.0' + s.dependency 'SystemEye', '~> 0.2.0' + s.dependency 'NetworkEye.swift', '~> 1.1.1' + s.dependency 'LeakEye', '~> 1.1.1' s.dependency 'FileBrowser', '~> 0.2.0' s.dependency 'SwViewCapture', '~> 1.0.5' s.dependency 'SQLite.swift', '~> 0.11.1' - s.dependency 'MJRefresh', '~> 3.1.12' + #s.dependency 'MJRefresh', '~> 3.1.12' + s.dependency 'ESPullToRefresh', '~> 2.6' end diff --git a/GodEye/Classes/Controller/Sub/ConsolePrintViewController.swift b/GodEye/Classes/Controller/Sub/ConsolePrintViewController.swift index 56e2be9..17c3865 100644 --- a/GodEye/Classes/Controller/Sub/ConsolePrintViewController.swift +++ b/GodEye/Classes/Controller/Sub/ConsolePrintViewController.swift @@ -7,7 +7,7 @@ // import Foundation -import MJRefresh +import ESPullToRefresh import SwViewCapture class ConsolePrintViewController: UIViewController { @@ -42,7 +42,7 @@ class ConsolePrintViewController: UIViewController { self.view.addSubview(self.recordTableView) self.view.addSubview(self.inputField) - self.recordTableView.mj_header = MJRefreshNormalHeader(refreshingBlock: { [weak self] in + self.recordTableView.es_addPullToRefresh { [weak self] in guard let sself = self else { return } @@ -51,8 +51,8 @@ class ConsolePrintViewController: UIViewController { if result == true { sself.recordTableView.reloadData() } - sself.recordTableView.mj_header.endRefreshing() - }) + sself.recordTableView.es_stopPullToRefresh() + } NotificationCenter.default.addObserver(self, selector: #selector(ConsolePrintViewController.keyboardWillShow(noti:)), diff --git a/GodEye/Classes/Controller/TabController/ConsoleController/ConsoleController+Eye.swift b/GodEye/Classes/Controller/TabController/ConsoleController/ConsoleController+Eye.swift index 8e729d9..d5c5ce0 100644 --- a/GodEye/Classes/Controller/TabController/ConsoleController/ConsoleController+Eye.swift +++ b/GodEye/Classes/Controller/TabController/ConsoleController/ConsoleController+Eye.swift @@ -9,7 +9,7 @@ import Foundation import ASLEye import CrashEye -import NetworkEye_swift +import NetworkEye import ANREye import Log4G import LeakEye diff --git a/GodEye/Classes/Controller/TabController/ConsoleController/EyesManager.swift b/GodEye/Classes/Controller/TabController/ConsoleController/EyesManager.swift index 8a406fd..97a3d52 100644 --- a/GodEye/Classes/Controller/TabController/ConsoleController/EyesManager.swift +++ b/GodEye/Classes/Controller/TabController/ConsoleController/EyesManager.swift @@ -8,7 +8,7 @@ import Foundation import ASLEye -import NetworkEye_swift +import NetworkEye import Log4G import CrashEye import ANREye diff --git a/GodEye/Classes/UIWindow+GodEye.swift b/GodEye/Classes/UIWindow+GodEye.swift index 4660019..47ce99a 100644 --- a/GodEye/Classes/UIWindow+GodEye.swift +++ b/GodEye/Classes/UIWindow+GodEye.swift @@ -26,7 +26,11 @@ extension UIWindow { let rect = CGRect(x: self.frame.size.width - 48, y: self.frame.size.height - 160, width: 48, height: 48) - let image = UIImage(named: "GodEye.bundle/eye", in: Bundle(for: GodEyeController.classForCoder()), compatibleWith: nil) + var image = UIImage(named: "GodEye.bundle/eye", in: Bundle(for: GodEyeController.classForCoder()), compatibleWith: nil) + if image == nil { + // for carthage, image in framework + image = UIImage(named: "eye", in: Bundle(for: GodEyeController.classForCoder()), compatibleWith: nil) + } let btn = AssistiveButton(frame: rect, normalImage: image!) btn.didTap = { () -> () in if GodEyeController.shared.showing { diff --git a/README.md b/README.md index 0ca9e88..53f8ebb 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [![Version](https://img.shields.io/cocoapods/v/Log4G.svg?style=flat)](http://cocoapods.org/pods/GodEye) [![License](https://img.shields.io/cocoapods/l/Log4G.svg?style=flat)](http://cocoapods.org/pods/GodEye) [![Platform](https://img.shields.io/cocoapods/p/Log4G.svg?style=flat)](http://cocoapods.org/pods/GodEye) +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) Automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code based on Swift. Just like God opened his eyes. @@ -49,18 +50,21 @@ It's so huge that I split it into several independent components: ## Preview - - - - - - - - - + + + + +## Book and Principle + +**I has wrote a book named [《iOS监控编程》](https://www.qingdan.us/product/25),each chapter records the course function of the implementation details and the way to explore.sorry for english friends,this book wrote by chineses.** + +

+ +

## Installation +### CocoaPods GodEye is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following line to your Podfile: @@ -68,14 +72,55 @@ it, simply add the following line to your Podfile: pod "GodEye" ``` -## Book and Principle +#### Not build in Release -**I has wrote a book named [《iOS监控编程》](https://www.qingdan.us/product/25),each chapter records the course function of the implementation details and the way to explore.sorry for english friends,this book wrote by chineses.** +First, add configurations in Podfile. + +```ruby +pod 'GodEye', '~> 1.0.0', :configurations => ['Debug'] +``` + +Then, find `Other Swift Flags` in your target's `Build Settings`,add `DEBUG` in Debug scheme. + +Finally, add `DEBUG` macro in makeEye: + +```swift +#if DEBUG + GodEye.makeEye(with: self.window!) +#endif +``` + +### Carthage +Or, if you’re using [Carthage](https://github.com/Carthage/Carthage), add GodEye to your Cartfile: + +``` +github "zixun/GodEye" +``` + +#### Add GodEye to Embed Frameworks +On your application targets’ `“General”` settings tab, in the “Embed Frameworks” section, drag and drop `GodEye.framework` from the Carthage/Build folder on disk. + +#### Add Dependency to Linked Frameworks and Libraries +On your application targets’ `“General”` settings tab, in the “Linked Frameworks and Libraries” section, drag and drop the dependency framework used in GodEye from the Carthage/Build folder on disk.

- +

+#### Add Run Script +On your application targets’ “Build Phases” settings tab, click the “+” icon and choose “New Run Script Phase”. Create a Run Script in which you specify your shell (ex: /bin/sh), add the following contents to the script area below the shell: + +``` +/usr/local/bin/carthage copy-frameworks +``` + +and add the paths to the frameworks you want to use under “Input Files”: + +

+ +

+ + ## OpenSource Application Use GodEye [CocoaChinaPlus](https://github.com/zixun/CocoaChinaPlus) is an open source application wrote by swift, now the GodEye is work well in it! diff --git a/README_CN.md b/README_CN.md index f3006ed..62ce24f 100644 --- a/README_CN.md +++ b/README_CN.md @@ -7,6 +7,7 @@ [![Version](https://img.shields.io/cocoapods/v/Log4G.svg?style=flat)](http://cocoapods.org/pods/GodEye) [![License](https://img.shields.io/cocoapods/l/Log4G.svg?style=flat)](http://cocoapods.org/pods/GodEye) [![Platform](https://img.shields.io/cocoapods/p/Log4G.svg?style=flat)](http://cocoapods.org/pods/GodEye) +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) Automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code based on Swift. Just like God opened his eyes. @@ -49,36 +50,78 @@ Automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and et ## 预览 - - - - - - - - - + -## 安装 +## 书与原理 + +**笔者写了一本书,名叫[《iOS监控编程》](https://www.qingdan.us/product/25),每个章节记录了功能的实现细节,以及笔者一路探索的心路历程。当然,笔者后续依旧会寻求与探索新的监控方向,一旦有所得都会更新到本书的章节中.** + +

+ +

+## 安装 +### CocoaPods GodEye目前可以通过 [CocoaPods](http://cocoapods.org)来安装.只需要将下面的代码加入到你的Podfile中即可: ```ruby pod "GodEye" ``` -## 在使用GodEye的开源App +#### 在Release下不编译进一行代码 +首先,在Podfile中添加configurations配置: -[CocoaChinaPlus](https://github.com/zixun/CocoaChinaPlus)是一款用Swift编写的开源的CocoaChina第三方客户端,目前已经接入GodEye,并且可以很好的工作。 +```ruby +pod 'GodEye', '~> 1.0.0', :configurations => ['Debug'] +``` -## 书与原理 +然后,在你的target的`Build Settings`中找到`Other Swift Flags`项,,在Debug scheme中添加 `DEBUG`. -**笔者写了一本书,名叫[《iOS监控编程》](https://www.qingdan.us/product/25),每个章节记录了功能的实现细节,以及笔者一路探索的心路历程。当然,笔者后续依旧会寻求与探索新的监控方向,一旦有所得都会更新到本书的章节中.** +最后,在初始化GodEye代码上添加`DEBUG`宏: + +```swift +#if DEBUG + GodEye.makeEye(with: self.window!) +#endif +``` + +### Carthage +如果你使用 [Carthage](https://github.com/Carthage/Carthage)来集成, 在Cartfile添加GodEye: + +``` +github "zixun/GodEye" +``` + +#### Add GodEye to Embed Frameworks +拖拽Carthage/Build目录下的`GodEye.framework`到你应用的target的`“General”`设置面板中的`“Embed Frameworks”`栏中 + +#### Add Dependency to Linked Frameworks and Libraries + +拖拽Carthage/Build目录下的GodEye依赖的framework到你应用的target的`“General”`设置面板中的`“Linked Frameworks and Libraries”`栏中

- +

+#### Add Run Script +在你应用的target下的“Build Phases”设置面板中,点击“+”按钮,选择“New Run Script Phase”,新建一个Run Script,添加下面的内容到shell输入框中: + +``` +/usr/local/bin/carthage copy-frameworks +``` + +添加上面依赖的framework的路径到“Input Files”中: + +

+ +

+ +## 在使用GodEye的开源App + +[CocoaChinaPlus](https://github.com/zixun/CocoaChinaPlus)是一款用Swift编写的开源的CocoaChina第三方客户端,目前已经接入GodEye,并且可以很好的工作。 + + + ## 使用 在`AppDelegate`中用下面的代码导入进来: diff --git a/design/image/dependency.jpg b/design/image/dependency.jpg new file mode 100644 index 0000000..70e0ebb Binary files /dev/null and b/design/image/dependency.jpg differ diff --git a/design/image/preview.png b/design/image/preview.png new file mode 100644 index 0000000..9d8498d Binary files /dev/null and b/design/image/preview.png differ diff --git a/design/image/preview_meitu_1.jpg b/design/image/preview_meitu_1.jpg new file mode 100644 index 0000000..ef8e167 Binary files /dev/null and b/design/image/preview_meitu_1.jpg differ diff --git a/design/image/runscript.jpg b/design/image/runscript.jpg new file mode 100644 index 0000000..826d00b Binary files /dev/null and b/design/image/runscript.jpg differ