shmily

sdk init

Showing 100 changed files with 3908 additions and 0 deletions

Too many changes to show.

To preserve performance only 100 of 100+ files are displayed.

  1 +# Xcode
  2 +#
  3 +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
  4 +
  5 +## Build generated
  6 +build/
  7 +DerivedData/
  8 +
  9 +## Various settings
  10 +*.pbxuser
  11 +!default.pbxuser
  12 +*.mode1v3
  13 +!default.mode1v3
  14 +*.mode2v3
  15 +!default.mode2v3
  16 +*.perspectivev3
  17 +!default.perspectivev3
  18 +xcuserdata/
  19 +
  20 +## Other
  21 +*.moved-aside
  22 +*.xccheckout
  23 +*.xcscmblueprint
  24 +
  25 +## Obj-C/Swift specific
  26 +*.hmap
  27 +*.ipa
  28 +*.dSYM.zip
  29 +*.dSYM
  30 +
  31 +## Playgrounds
  32 +timeline.xctimeline
  33 +playground.xcworkspace
  34 +
  35 +# Swift Package Manager
  36 +#
  37 +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
  38 +# Packages/
  39 +# Package.pins
  40 +.build/
  41 +
  42 +# CocoaPods
  43 +#
  44 +# We recommend against adding the Pods directory to your .gitignore. However
  45 +# you should judge for yourself, the pros and cons are mentioned at:
  46 +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
  47 +#
  48 +# Pods/
  49 +
  50 +# Carthage
  51 +#
  52 +# Add this line if you want to avoid checking in source code from Carthage dependencies.
  53 +# Carthage/Checkouts
  54 +
  55 +Carthage/Build
  56 +
  57 +# fastlane
  58 +#
  59 +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
  60 +# screenshots whenever they are needed.
  61 +# For more information about the recommended setup visit:
  62 +# https://docs.fastlane.tools/best-practices/source-control/#source-control
  63 +
  64 +fastlane/report.xml
  65 +fastlane/Preview.html
  66 +fastlane/screenshots
  67 +fastlane/test_output
  1 +Pod::Spec.new do |s|
  2 + s.name = "HHDoctorSDK"
  3 + s.version = "1.0.0"
  4 + s.summary = "和缓视频医生SDK(融云)"
  5 +
  6 + s.description = <<-DESC
  7 + 和缓视频医生,连接千万用户和全科医生。
  8 + DESC
  9 +
  10 + s.homepage = "https://code.hh-medic.com/dev-client/hhsdk.ios"
  11 + s.license = "MIT"
  12 + s.author = { "shmily" => "shmilyshijian@foxmail.com" }
  13 + s.social_media_url = "https://github.com/515783034"
  14 +
  15 + s.ios.deployment_target = '9.0'
  16 + s.platform = :ios, "9.0"
  17 + s.source = { :git => "git@code.hh-medic.com:hh_public/HHDoctorSDK.ios.git", :tag => s.version }
  18 + s.default_subspec = 'Base'
  19 +
  20 +
  21 + s.subspec 'Base' do |base|
  22 + base.vendored_frameworks = 'HHDoctorSDK/*.framework'
  23 + base.frameworks = 'SystemConfiguration', 'MobileCoreServices', 'AVFoundation', 'CoreTelephony', 'VideoToolbox', 'AudioToolbox', 'CoreMedia'
  24 + base.libraries = 'z', 'sqlite3.0', 'c++'
  25 + end
  26 +
  27 +end
  28 +
  29 +
This file is too large to display.
  1 +//
  2 +// CGGeometry+RSKImageCropper.h
  3 +//
  4 +// Copyright (c) 2015 Ruslan Skorb, http://ruslanskorb.com/
  5 +//
  6 +// Permission is hereby granted, free of charge, to any person obtaining a copy
  7 +// of this software and associated documentation files (the "Software"), to deal
  8 +// in the Software without restriction, including without limitation the rights
  9 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 +// copies of the Software, and to permit persons to whom the Software is
  11 +// furnished to do so, subject to the following conditions:
  12 +//
  13 +// The above copyright notice and this permission notice shall be included in
  14 +// all copies or substantial portions of the Software.
  15 +//
  16 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 +// THE SOFTWARE.
  23 +//
  24 +
  25 +#import <CoreGraphics/CoreGraphics.h>
  26 +#import <tgmath.h>
  27 +
  28 +// tgmath functions aren't used on iOS when modules are enabled.
  29 +// Open Radar - http://www.openradar.me/16744288
  30 +// Work around this by redeclaring things here.
  31 +
  32 +#undef cos
  33 +#define cos(__x) __tg_cos(__tg_promote1((__x))(__x))
  34 +
  35 +#undef sin
  36 +#define sin(__x) __tg_sin(__tg_promote1((__x))(__x))
  37 +
  38 +#undef atan2
  39 +#define atan2(__x, __y) __tg_atan2(__tg_promote2((__x), (__y))(__x), \
  40 +__tg_promote2((__x), (__y))(__y))
  41 +
  42 +#undef pow
  43 +#define pow(__x, __y) __tg_pow(__tg_promote2((__x), (__y))(__x), \
  44 +__tg_promote2((__x), (__y))(__y))
  45 +
  46 +#undef sqrt
  47 +#define sqrt(__x) __tg_sqrt(__tg_promote1((__x))(__x))
  48 +
  49 +#undef fabs
  50 +#define fabs(__x) __tg_fabs(__tg_promote1((__x))(__x))
  51 +
  52 +#undef ceil
  53 +#define ceil(__x) __tg_ceil(__tg_promote1((__x))(__x))
  54 +
  55 +#ifdef CGFLOAT_IS_DOUBLE
  56 + #define RSK_EPSILON DBL_EPSILON
  57 +#else
  58 + #define RSK_EPSILON FLT_EPSILON
  59 +#endif
  60 +
  61 +// Line segments.
  62 +struct RSKLineSegment {
  63 + CGPoint start;
  64 + CGPoint end;
  65 +};
  66 +typedef struct RSKLineSegment RSKLineSegment;
  67 +
  68 +// The "empty" point. This is the point returned when, for example, we
  69 +// intersect two disjoint line segments. Note that the null point is not the
  70 +// same as the zero point.
  71 +CG_EXTERN const CGPoint RSKPointNull;
  72 +
  73 +// Returns the exact center point of the given rectangle.
  74 +CGPoint RSKRectCenterPoint(CGRect rect);
  75 +
  76 +// Returns the `rect` scaled around the `point` by `sx` and `sy`.
  77 +CGRect RSKRectScaleAroundPoint(CGRect rect, CGPoint point, CGFloat sx, CGFloat sy);
  78 +
  79 +// Returns true if `point' is the null point, false otherwise.
  80 +bool RSKPointIsNull(CGPoint point);
  81 +
  82 +// Returns the `point` rotated around the `pivot` by `angle`.
  83 +CGPoint RSKPointRotateAroundPoint(CGPoint point, CGPoint pivot, CGFloat angle);
  84 +
  85 +// Returns the distance between two points.
  86 +CGFloat RSKPointDistance(CGPoint p1, CGPoint p2);
  87 +
  88 +// Make a line segment from two points `start` and `end`.
  89 +RSKLineSegment RSKLineSegmentMake(CGPoint start, CGPoint end);
  90 +
  91 +// Returns the line segment rotated around the `pivot` by `angle`.
  92 +RSKLineSegment RSKLineSegmentRotateAroundPoint(RSKLineSegment lineSegment, CGPoint pivot, CGFloat angle);
  93 +
  94 +// Returns the intersection of `ls1' and `ls2'. This may return a null point.
  95 +CGPoint RSKLineSegmentIntersection(RSKLineSegment ls1, RSKLineSegment ls2);
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +/**
  17 + * Welcome to CocoaLumberjack!
  18 + *
  19 + * The project page has a wealth of documentation if you have any questions.
  20 + * https://github.com/CocoaLumberjack/CocoaLumberjack
  21 + *
  22 + * If you're new to the project you may wish to read "Getting Started" at:
  23 + * Documentation/GettingStarted.md
  24 + *
  25 + * Otherwise, here is a quick refresher.
  26 + * There are three steps to using the macros:
  27 + *
  28 + * Step 1:
  29 + * Import the header in your implementation or prefix file:
  30 + *
  31 + * #import <CocoaLumberjack/CocoaLumberjack.h>
  32 + *
  33 + * Step 2:
  34 + * Define your logging level in your implementation file:
  35 + *
  36 + * // Log levels: off, error, warn, info, verbose
  37 + * static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
  38 + *
  39 + * Step 2 [3rd party frameworks]:
  40 + *
  41 + * Define your LOG_LEVEL_DEF to a different variable/function than ddLogLevel:
  42 + *
  43 + * // #undef LOG_LEVEL_DEF // Undefine first only if needed
  44 + * #define LOG_LEVEL_DEF myLibLogLevel
  45 + *
  46 + * Define your logging level in your implementation file:
  47 + *
  48 + * // Log levels: off, error, warn, info, verbose
  49 + * static const DDLogLevel myLibLogLevel = DDLogLevelVerbose;
  50 + *
  51 + * Step 3:
  52 + * Replace your NSLog statements with DDLog statements according to the severity of the message.
  53 + *
  54 + * NSLog(@"Fatal error, no dohickey found!"); -> DDLogError(@"Fatal error, no dohickey found!");
  55 + *
  56 + * DDLog works exactly the same as NSLog.
  57 + * This means you can pass it multiple variables just like NSLog.
  58 + **/
  59 +
  60 +#import <Foundation/Foundation.h>
  61 +
  62 +// Disable legacy macros
  63 +#ifndef DD_LEGACY_MACROS
  64 + #define DD_LEGACY_MACROS 0
  65 +#endif
  66 +
  67 +// Core
  68 +#import "DDLog.h"
  69 +
  70 +// Main macros
  71 +#import "DDLogMacros.h"
  72 +#import "DDAssertMacros.h"
  73 +
  74 +// Capture ASL
  75 +#import "DDASLLogCapture.h"
  76 +
  77 +// Loggers
  78 +#import "DDTTYLogger.h"
  79 +#import "DDASLLogger.h"
  80 +#import "DDFileLogger.h"
  81 +#import "DDOSLogger.h"
  82 +
  83 +// CLI
  84 +#if __has_include("CLIColor.h") && TARGET_OS_OSX
  85 +#import "CLIColor.h"
  86 +#endif
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +#import "DDASLLogger.h"
  17 +
  18 +@protocol DDLogger;
  19 +
  20 +/**
  21 + * This class provides the ability to capture the ASL (Apple System Logs)
  22 + */
  23 +@interface DDASLLogCapture : NSObject
  24 +
  25 +/**
  26 + * Start capturing logs
  27 + */
  28 ++ (void)start;
  29 +
  30 +/**
  31 + * Stop capturing logs
  32 + */
  33 ++ (void)stop;
  34 +
  35 +/**
  36 + * The current capture level.
  37 + * @note Default log level: DDLogLevelVerbose (i.e. capture all ASL messages).
  38 + */
  39 +@property (class) DDLogLevel captureLevel;
  40 +
  41 +@end
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +#import <Foundation/Foundation.h>
  17 +
  18 +// Disable legacy macros
  19 +#ifndef DD_LEGACY_MACROS
  20 + #define DD_LEGACY_MACROS 0
  21 +#endif
  22 +
  23 +#import "DDLog.h"
  24 +
  25 +// Custom key set on messages sent to ASL
  26 +extern const char* const kDDASLKeyDDLog;
  27 +
  28 +// Value set for kDDASLKeyDDLog
  29 +extern const char* const kDDASLDDLogValue;
  30 +
  31 +/**
  32 + * This class provides a logger for the Apple System Log facility.
  33 + *
  34 + * As described in the "Getting Started" page,
  35 + * the traditional NSLog() function directs its output to two places:
  36 + *
  37 + * - Apple System Log
  38 + * - StdErr (if stderr is a TTY) so log statements show up in Xcode console
  39 + *
  40 + * To duplicate NSLog() functionality you can simply add this logger and a tty logger.
  41 + * However, if you instead choose to use file logging (for faster performance),
  42 + * you may choose to use a file logger and a tty logger.
  43 + **/
  44 +@interface DDASLLogger : DDAbstractLogger <DDLogger>
  45 +
  46 +/**
  47 + * Singleton method
  48 + *
  49 + * @return the shared instance
  50 + */
  51 +@property (class, readonly, strong) DDASLLogger *sharedInstance;
  52 +
  53 +// Inherited from DDAbstractLogger
  54 +
  55 +// - (id <DDLogFormatter>)logFormatter;
  56 +// - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
  57 +
  58 +@end
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +// Disable legacy macros
  17 +#ifndef DD_LEGACY_MACROS
  18 + #define DD_LEGACY_MACROS 0
  19 +#endif
  20 +
  21 +#import "DDLog.h"
  22 +
  23 +/**
  24 + * This class provides an abstract implementation of a database logger.
  25 + *
  26 + * That is, it provides the base implementation for a database logger to build atop of.
  27 + * All that is needed for a concrete database logger is to extend this class
  28 + * and override the methods in the implementation file that are prefixed with "db_".
  29 + **/
  30 +@interface DDAbstractDatabaseLogger : DDAbstractLogger {
  31 +
  32 +@protected
  33 + NSUInteger _saveThreshold;
  34 + NSTimeInterval _saveInterval;
  35 + NSTimeInterval _maxAge;
  36 + NSTimeInterval _deleteInterval;
  37 + BOOL _deleteOnEverySave;
  38 +
  39 + BOOL _saveTimerSuspended;
  40 + NSUInteger _unsavedCount;
  41 + dispatch_time_t _unsavedTime;
  42 + dispatch_source_t _saveTimer;
  43 + dispatch_time_t _lastDeleteTime;
  44 + dispatch_source_t _deleteTimer;
  45 +}
  46 +
  47 +/**
  48 + * Specifies how often to save the data to disk.
  49 + * Since saving is an expensive operation (disk io) it is not done after every log statement.
  50 + * These properties allow you to configure how/when the logger saves to disk.
  51 + *
  52 + * A save is done when either (whichever happens first):
  53 + *
  54 + * - The number of unsaved log entries reaches saveThreshold
  55 + * - The amount of time since the oldest unsaved log entry was created reaches saveInterval
  56 + *
  57 + * You can optionally disable the saveThreshold by setting it to zero.
  58 + * If you disable the saveThreshold you are entirely dependent on the saveInterval.
  59 + *
  60 + * You can optionally disable the saveInterval by setting it to zero (or a negative value).
  61 + * If you disable the saveInterval you are entirely dependent on the saveThreshold.
  62 + *
  63 + * It's not wise to disable both saveThreshold and saveInterval.
  64 + *
  65 + * The default saveThreshold is 500.
  66 + * The default saveInterval is 60 seconds.
  67 + **/
  68 +@property (assign, readwrite) NSUInteger saveThreshold;
  69 +
  70 +/**
  71 + * See the description for the `saveThreshold` property
  72 + */
  73 +@property (assign, readwrite) NSTimeInterval saveInterval;
  74 +
  75 +/**
  76 + * It is likely you don't want the log entries to persist forever.
  77 + * Doing so would allow the database to grow infinitely large over time.
  78 + *
  79 + * The maxAge property provides a way to specify how old a log statement can get
  80 + * before it should get deleted from the database.
  81 + *
  82 + * The deleteInterval specifies how often to sweep for old log entries.
  83 + * Since deleting is an expensive operation (disk io) is is done on a fixed interval.
  84 + *
  85 + * An alternative to the deleteInterval is the deleteOnEverySave option.
  86 + * This specifies that old log entries should be deleted during every save operation.
  87 + *
  88 + * You can optionally disable the maxAge by setting it to zero (or a negative value).
  89 + * If you disable the maxAge then old log statements are not deleted.
  90 + *
  91 + * You can optionally disable the deleteInterval by setting it to zero (or a negative value).
  92 + *
  93 + * If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted.
  94 + *
  95 + * It's not wise to enable both deleteInterval and deleteOnEverySave.
  96 + *
  97 + * The default maxAge is 7 days.
  98 + * The default deleteInterval is 5 minutes.
  99 + * The default deleteOnEverySave is NO.
  100 + **/
  101 +@property (assign, readwrite) NSTimeInterval maxAge;
  102 +
  103 +/**
  104 + * See the description for the `maxAge` property
  105 + */
  106 +@property (assign, readwrite) NSTimeInterval deleteInterval;
  107 +
  108 +/**
  109 + * See the description for the `maxAge` property
  110 + */
  111 +@property (assign, readwrite) BOOL deleteOnEverySave;
  112 +
  113 +/**
  114 + * Forces a save of any pending log entries (flushes log entries to disk).
  115 + **/
  116 +- (void)savePendingLogEntries;
  117 +
  118 +/**
  119 + * Removes any log entries that are older than maxAge.
  120 + **/
  121 +- (void)deleteOldLogEntries;
  122 +
  123 +@end
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +/**
  17 + * NSAsset replacement that will output a log message even when assertions are disabled.
  18 + **/
  19 +#define DDAssert(condition, frmt, ...) \
  20 + if (!(condition)) { \
  21 + NSString *description = [NSString stringWithFormat:frmt, ## __VA_ARGS__]; \
  22 + DDLogError(@"%@", description); \
  23 + NSAssert(NO, description); \
  24 + }
  25 +#define DDAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %s", #condition)
  26 +
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +// Disable legacy macros
  17 +#ifndef DD_LEGACY_MACROS
  18 + #define DD_LEGACY_MACROS 0
  19 +#endif
  20 +
  21 +#import "DDLog.h"
  22 +
  23 +@class DDLogFileInfo;
  24 +
  25 +/**
  26 + * This class provides a logger to write log statements to a file.
  27 + **/
  28 +
  29 +
  30 +// Default configuration and safety/sanity values.
  31 +//
  32 +// maximumFileSize -> kDDDefaultLogMaxFileSize
  33 +// rollingFrequency -> kDDDefaultLogRollingFrequency
  34 +// maximumNumberOfLogFiles -> kDDDefaultLogMaxNumLogFiles
  35 +// logFilesDiskQuota -> kDDDefaultLogFilesDiskQuota
  36 +//
  37 +// You should carefully consider the proper configuration values for your application.
  38 +
  39 +extern unsigned long long const kDDDefaultLogMaxFileSize;
  40 +extern NSTimeInterval const kDDDefaultLogRollingFrequency;
  41 +extern NSUInteger const kDDDefaultLogMaxNumLogFiles;
  42 +extern unsigned long long const kDDDefaultLogFilesDiskQuota;
  43 +
  44 +
  45 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  46 +#pragma mark -
  47 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  48 +
  49 +/**
  50 + * The LogFileManager protocol is designed to allow you to control all aspects of your log files.
  51 + *
  52 + * The primary purpose of this is to allow you to do something with the log files after they have been rolled.
  53 + * Perhaps you want to compress them to save disk space.
  54 + * Perhaps you want to upload them to an FTP server.
  55 + * Perhaps you want to run some analytics on the file.
  56 + *
  57 + * A default LogFileManager is, of course, provided.
  58 + * The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property.
  59 + *
  60 + * This protocol provides various methods to fetch the list of log files.
  61 + *
  62 + * There are two variants: sorted and unsorted.
  63 + * If sorting is not necessary, the unsorted variant is obviously faster.
  64 + * The sorted variant will return an array sorted by when the log files were created,
  65 + * with the most recently created log file at index 0, and the oldest log file at the end of the array.
  66 + *
  67 + * You can fetch only the log file paths (full path including name), log file names (name only),
  68 + * or an array of `DDLogFileInfo` objects.
  69 + * The `DDLogFileInfo` class is documented below, and provides a handy wrapper that
  70 + * gives you easy access to various file attributes such as the creation date or the file size.
  71 + */
  72 +@protocol DDLogFileManager <NSObject>
  73 +@required
  74 +
  75 +// Public properties
  76 +
  77 +/**
  78 + * The maximum number of archived log files to keep on disk.
  79 + * For example, if this property is set to 3,
  80 + * then the LogFileManager will only keep 3 archived log files (plus the current active log file) on disk.
  81 + * Once the active log file is rolled/archived, then the oldest of the existing 3 rolled/archived log files is deleted.
  82 + *
  83 + * You may optionally disable this option by setting it to zero.
  84 + **/
  85 +@property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
  86 +
  87 +/**
  88 + * The maximum space that logs can take. On rolling logfile all old logfiles that exceed logFilesDiskQuota will
  89 + * be deleted.
  90 + *
  91 + * You may optionally disable this option by setting it to zero.
  92 + **/
  93 +@property (readwrite, assign, atomic) unsigned long long logFilesDiskQuota;
  94 +
  95 +// Public methods
  96 +
  97 +/**
  98 + * Returns the logs directory (path)
  99 + */
  100 +@property (nonatomic, readonly, copy) NSString *logsDirectory;
  101 +
  102 +/**
  103 + * Returns an array of `NSString` objects,
  104 + * each of which is the filePath to an existing log file on disk.
  105 + **/
  106 +@property (nonatomic, readonly, strong) NSArray<NSString *> *unsortedLogFilePaths;
  107 +
  108 +/**
  109 + * Returns an array of `NSString` objects,
  110 + * each of which is the fileName of an existing log file on disk.
  111 + **/
  112 +@property (nonatomic, readonly, strong) NSArray<NSString *> *unsortedLogFileNames;
  113 +
  114 +/**
  115 + * Returns an array of `DDLogFileInfo` objects,
  116 + * each representing an existing log file on disk,
  117 + * and containing important information about the log file such as it's modification date and size.
  118 + **/
  119 +@property (nonatomic, readonly, strong) NSArray<DDLogFileInfo *> *unsortedLogFileInfos;
  120 +
  121 +/**
  122 + * Just like the `unsortedLogFilePaths` method, but sorts the array.
  123 + * The items in the array are sorted by creation date.
  124 + * The first item in the array will be the most recently created log file.
  125 + **/
  126 +@property (nonatomic, readonly, strong) NSArray<NSString *> *sortedLogFilePaths;
  127 +
  128 +/**
  129 + * Just like the `unsortedLogFileNames` method, but sorts the array.
  130 + * The items in the array are sorted by creation date.
  131 + * The first item in the array will be the most recently created log file.
  132 + **/
  133 +@property (nonatomic, readonly, strong) NSArray<NSString *> *sortedLogFileNames;
  134 +
  135 +/**
  136 + * Just like the `unsortedLogFileInfos` method, but sorts the array.
  137 + * The items in the array are sorted by creation date.
  138 + * The first item in the array will be the most recently created log file.
  139 + **/
  140 +@property (nonatomic, readonly, strong) NSArray<DDLogFileInfo *> *sortedLogFileInfos;
  141 +
  142 +// Private methods (only to be used by DDFileLogger)
  143 +
  144 +/**
  145 + * Generates a new unique log file path, and creates the corresponding log file.
  146 + **/
  147 +- (NSString *)createNewLogFile;
  148 +
  149 +@optional
  150 +
  151 +// Notifications from DDFileLogger
  152 +
  153 +/**
  154 + * Called when a log file was archieved
  155 + */
  156 +- (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:));
  157 +
  158 +/**
  159 + * Called when the roll action was executed and the log was archieved
  160 + */
  161 +- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:));
  162 +
  163 +@end
  164 +
  165 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  166 +#pragma mark -
  167 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  168 +
  169 +/**
  170 + * Default log file manager.
  171 + *
  172 + * All log files are placed inside the logsDirectory.
  173 + * If a specific logsDirectory isn't specified, the default directory is used.
  174 + * On Mac, this is in `~/Library/Logs/<Application Name>`.
  175 + * On iPhone, this is in `~/Library/Caches/Logs`.
  176 + *
  177 + * Log files are named `"<bundle identifier> <date> <time>.log"`
  178 + * Example: `com.organization.myapp 2013-12-03 17-14.log`
  179 + *
  180 + * Archived log files are automatically deleted according to the `maximumNumberOfLogFiles` property.
  181 + **/
  182 +@interface DDLogFileManagerDefault : NSObject <DDLogFileManager>
  183 +
  184 +/**
  185 + * Default initializer
  186 + */
  187 +- (instancetype)init;
  188 +
  189 +/**
  190 + * Designated initialized, requires the logs directory
  191 + */
  192 +- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory NS_DESIGNATED_INITIALIZER;
  193 +
  194 +#if TARGET_OS_IPHONE
  195 +/*
  196 + * Calling this constructor you can override the default "automagically" chosen NSFileProtection level.
  197 + * Useful if you are writing a command line utility / CydiaSubstrate addon for iOS that has no NSBundle
  198 + * or like SpringBoard no BackgroundModes key in the NSBundle:
  199 + * iPhone:~ root# cycript -p SpringBoard
  200 + * cy# [NSBundle mainBundle]
  201 + * #"NSBundle </System/Library/CoreServices/SpringBoard.app> (loaded)"
  202 + * cy# [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
  203 + * null
  204 + * cy#
  205 + **/
  206 +- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel;
  207 +#endif
  208 +
  209 +/*
  210 + * Methods to override.
  211 + *
  212 + * Log files are named `"<bundle identifier> <date> <time>.log"`
  213 + * Example: `com.organization.myapp 2013-12-03 17-14.log`
  214 + *
  215 + * If you wish to change default filename, you can override following two methods.
  216 + * - `newLogFileName` method would be called on new logfile creation.
  217 + * - `isLogFile:` method would be called to filter logfiles from all other files in logsDirectory.
  218 + * You have to parse given filename and return YES if it is logFile.
  219 + *
  220 + * **NOTE**
  221 + * `newLogFileName` returns filename. If appropriate file already exists, number would be added
  222 + * to filename before extension. You have to handle this case in isLogFile: method.
  223 + *
  224 + * Example:
  225 + * - newLogFileName returns `"com.organization.myapp 2013-12-03.log"`,
  226 + * file `"com.organization.myapp 2013-12-03.log"` would be created.
  227 + * - after some time `"com.organization.myapp 2013-12-03.log"` is archived
  228 + * - newLogFileName again returns `"com.organization.myapp 2013-12-03.log"`,
  229 + * file `"com.organization.myapp 2013-12-03 2.log"` would be created.
  230 + * - after some time `"com.organization.myapp 2013-12-03 1.log"` is archived
  231 + * - newLogFileName again returns `"com.organization.myapp 2013-12-03.log"`,
  232 + * file `"com.organization.myapp 2013-12-03 3.log"` would be created.
  233 + **/
  234 +
  235 +/**
  236 + * Generates log file name with default format `"<bundle identifier> <date> <time>.log"`
  237 + * Example: `MobileSafari 2013-12-03 17-14.log`
  238 + *
  239 + * You can change it by overriding `newLogFileName` and `isLogFile:` methods.
  240 + **/
  241 +@property (readonly, copy) NSString *newLogFileName;
  242 +
  243 +/**
  244 + * Default log file name is `"<bundle identifier> <date> <time>.log"`.
  245 + * Example: `MobileSafari 2013-12-03 17-14.log`
  246 + *
  247 + * You can change it by overriding `newLogFileName` and `isLogFile:` methods.
  248 + **/
  249 +- (BOOL)isLogFile:(NSString *)fileName NS_SWIFT_NAME(isLogFile(withName:));
  250 +
  251 +/* Inherited from DDLogFileManager protocol:
  252 +
  253 + @property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
  254 + @property (readwrite, assign, atomic) NSUInteger logFilesDiskQuota;
  255 +
  256 + - (NSString *)logsDirectory;
  257 +
  258 + - (NSArray *)unsortedLogFilePaths;
  259 + - (NSArray *)unsortedLogFileNames;
  260 + - (NSArray *)unsortedLogFileInfos;
  261 +
  262 + - (NSArray *)sortedLogFilePaths;
  263 + - (NSArray *)sortedLogFileNames;
  264 + - (NSArray *)sortedLogFileInfos;
  265 +
  266 + */
  267 +
  268 +@end
  269 +
  270 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  271 +#pragma mark -
  272 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  273 +
  274 +/**
  275 + * Most users will want file log messages to be prepended with the date and time.
  276 + * Rather than forcing the majority of users to write their own formatter,
  277 + * we will supply a logical default formatter.
  278 + * Users can easily replace this formatter with their own by invoking the `setLogFormatter:` method.
  279 + * It can also be removed by calling `setLogFormatter:`, and passing a nil parameter.
  280 + *
  281 + * In addition to the convenience of having a logical default formatter,
  282 + * it will also provide a template that makes it easy for developers to copy and change.
  283 + **/
  284 +@interface DDLogFileFormatterDefault : NSObject <DDLogFormatter>
  285 +
  286 +/**
  287 + * Default initializer
  288 + */
  289 +- (instancetype)init;
  290 +
  291 +/**
  292 + * Designated initializer, requires a date formatter
  293 + */
  294 +- (instancetype)initWithDateFormatter:(NSDateFormatter *)dateFormatter NS_DESIGNATED_INITIALIZER;
  295 +
  296 +@end
  297 +
  298 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  299 +#pragma mark -
  300 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  301 +
  302 +/**
  303 + * The standard implementation for a file logger
  304 + */
  305 +@interface DDFileLogger : DDAbstractLogger <DDLogger> {
  306 + DDLogFileInfo *_currentLogFileInfo;
  307 +}
  308 +
  309 +/**
  310 + * Default initializer
  311 + */
  312 +- (instancetype)init;
  313 +
  314 +/**
  315 + * Designated initializer, requires a `DDLogFileManager` instance
  316 + */
  317 +- (instancetype)initWithLogFileManager:(id <DDLogFileManager>)logFileManager NS_DESIGNATED_INITIALIZER;
  318 +
  319 +/**
  320 + * Called when the logger is about to write message. Call super before your implementation.
  321 + */
  322 +- (void)willLogMessage NS_REQUIRES_SUPER;
  323 +
  324 +/**
  325 + * Called when the logger wrote message. Call super after your implementation.
  326 + */
  327 +- (void)didLogMessage NS_REQUIRES_SUPER;
  328 +
  329 +/**
  330 + * Writes all in-memory log data to the permanent storage. Call super before your implementation.
  331 + */
  332 +- (void)flush NS_REQUIRES_SUPER;
  333 +
  334 +/**
  335 + * Called when the logger checks archive or not current log file.
  336 + * Override this method to exdend standart behavior. By default returns NO.
  337 + */
  338 +- (BOOL)shouldArchiveRecentLogFileInfo:(DDLogFileInfo *)recentLogFileInfo;
  339 +
  340 +/**
  341 + * Log File Rolling:
  342 + *
  343 + * `maximumFileSize`:
  344 + * The approximate maximum size (in bytes) to allow log files to grow.
  345 + * If a log file is larger than this value after a log statement is appended,
  346 + * then the log file is rolled.
  347 + *
  348 + * `rollingFrequency`
  349 + * How often to roll the log file.
  350 + * The frequency is given as an `NSTimeInterval`, which is a double that specifies the interval in seconds.
  351 + * Once the log file gets to be this old, it is rolled.
  352 + *
  353 + * `doNotReuseLogFiles`
  354 + * When set, will always create a new log file at application launch.
  355 + *
  356 + * Both the `maximumFileSize` and the `rollingFrequency` are used to manage rolling.
  357 + * Whichever occurs first will cause the log file to be rolled.
  358 + *
  359 + * For example:
  360 + * The `rollingFrequency` is 24 hours,
  361 + * but the log file surpasses the `maximumFileSize` after only 20 hours.
  362 + * The log file will be rolled at that 20 hour mark.
  363 + * A new log file will be created, and the 24 hour timer will be restarted.
  364 + *
  365 + * You may optionally disable rolling due to filesize by setting `maximumFileSize` to zero.
  366 + * If you do so, rolling is based solely on `rollingFrequency`.
  367 + *
  368 + * You may optionally disable rolling due to time by setting `rollingFrequency` to zero (or any non-positive number).
  369 + * If you do so, rolling is based solely on `maximumFileSize`.
  370 + *
  371 + * If you disable both `maximumFileSize` and `rollingFrequency`, then the log file won't ever be rolled.
  372 + * This is strongly discouraged.
  373 + **/
  374 +@property (readwrite, assign) unsigned long long maximumFileSize;
  375 +
  376 +/**
  377 + * See description for `maximumFileSize`
  378 + */
  379 +@property (readwrite, assign) NSTimeInterval rollingFrequency;
  380 +
  381 +/**
  382 + * See description for `maximumFileSize`
  383 + */
  384 +@property (readwrite, assign, atomic) BOOL doNotReuseLogFiles;
  385 +
  386 +/**
  387 + * The DDLogFileManager instance can be used to retrieve the list of log files,
  388 + * and configure the maximum number of archived log files to keep.
  389 + *
  390 + * @see DDLogFileManager.maximumNumberOfLogFiles
  391 + **/
  392 +@property (strong, nonatomic, readonly) id <DDLogFileManager> logFileManager;
  393 +
  394 +/**
  395 + * When using a custom formatter you can set the `logMessage` method not to append
  396 + * `\n` character after each output. This allows for some greater flexibility with
  397 + * custom formatters. Default value is YES.
  398 + **/
  399 +@property (nonatomic, readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
  400 +
  401 +/**
  402 + * You can optionally force the current log file to be rolled with this method.
  403 + * CompletionBlock will be called on main queue.
  404 + */
  405 +- (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock NS_SWIFT_NAME(rollLogFile(withCompletion:));
  406 +
  407 +/**
  408 + * Method is deprecated.
  409 + * @deprecated Use `rollLogFileWithCompletionBlock:` method instead.
  410 + */
  411 +- (void)rollLogFile __attribute((deprecated));
  412 +
  413 +// Inherited from DDAbstractLogger
  414 +
  415 +// - (id <DDLogFormatter>)logFormatter;
  416 +// - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
  417 +
  418 +/**
  419 + * Returns the log file that should be used.
  420 + * If there is an existing log file that is suitable,
  421 + * within the constraints of `maximumFileSize` and `rollingFrequency`, then it is returned.
  422 + *
  423 + * Otherwise a new file is created and returned.
  424 + **/
  425 +@property (nonatomic, readonly, strong) DDLogFileInfo *currentLogFileInfo;
  426 +
  427 +@end
  428 +
  429 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  430 +#pragma mark -
  431 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  432 +
  433 +/**
  434 + * `DDLogFileInfo` is a simple class that provides access to various file attributes.
  435 + * It provides good performance as it only fetches the information if requested,
  436 + * and it caches the information to prevent duplicate fetches.
  437 + *
  438 + * It was designed to provide quick snapshots of the current state of log files,
  439 + * and to help sort log files in an array.
  440 + *
  441 + * This class does not monitor the files, or update it's cached attribute values if the file changes on disk.
  442 + * This is not what the class was designed for.
  443 + *
  444 + * If you absolutely must get updated values,
  445 + * you can invoke the reset method which will clear the cache.
  446 + **/
  447 +@interface DDLogFileInfo : NSObject
  448 +
  449 +@property (strong, nonatomic, readonly) NSString *filePath;
  450 +@property (strong, nonatomic, readonly) NSString *fileName;
  451 +
  452 +#if FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8)
  453 +@property (strong, nonatomic, readonly) NSDictionary<NSFileAttributeKey, id> *fileAttributes;
  454 +#else
  455 +@property (strong, nonatomic, readonly) NSDictionary<NSString *, id> *fileAttributes;
  456 +#endif
  457 +
  458 +@property (strong, nonatomic, readonly) NSDate *creationDate;
  459 +@property (strong, nonatomic, readonly) NSDate *modificationDate;
  460 +
  461 +@property (nonatomic, readonly) unsigned long long fileSize;
  462 +
  463 +@property (nonatomic, readonly) NSTimeInterval age;
  464 +
  465 +@property (nonatomic, readwrite) BOOL isArchived;
  466 +
  467 ++ (instancetype)logFileWithPath:(NSString *)filePath NS_SWIFT_UNAVAILABLE("Use init(filePath:)");
  468 +
  469 +- (instancetype)init NS_UNAVAILABLE;
  470 +- (instancetype)initWithFilePath:(NSString *)filePath NS_DESIGNATED_INITIALIZER;
  471 +
  472 +- (void)reset;
  473 +- (void)renameFile:(NSString *)newFileName NS_SWIFT_NAME(renameFile(to:));
  474 +
  475 +#if TARGET_IPHONE_SIMULATOR
  476 +
  477 +// So here's the situation.
  478 +// Extended attributes are perfect for what we're trying to do here (marking files as archived).
  479 +// This is exactly what extended attributes were designed for.
  480 +//
  481 +// But Apple screws us over on the simulator.
  482 +// Everytime you build-and-go, they copy the application into a new folder on the hard drive,
  483 +// and as part of the process they strip extended attributes from our log files.
  484 +// Normally, a copy of a file preserves extended attributes.
  485 +// So obviously Apple has gone to great lengths to piss us off.
  486 +//
  487 +// Thus we use a slightly different tactic for marking log files as archived in the simulator.
  488 +// That way it "just works" and there's no confusion when testing.
  489 +//
  490 +// The difference in method names is indicative of the difference in functionality.
  491 +// On the simulator we add an attribute by appending a filename extension.
  492 +//
  493 +// For example:
  494 +// "mylog.txt" -> "mylog.archived.txt"
  495 +// "mylog" -> "mylog.archived"
  496 +
  497 +- (BOOL)hasExtensionAttributeWithName:(NSString *)attrName;
  498 +
  499 +- (void)addExtensionAttributeWithName:(NSString *)attrName;
  500 +- (void)removeExtensionAttributeWithName:(NSString *)attrName;
  501 +
  502 +#else /* if TARGET_IPHONE_SIMULATOR */
  503 +
  504 +// Normal use of extended attributes used everywhere else,
  505 +// such as on Macs and on iPhone devices.
  506 +
  507 +- (BOOL)hasExtendedAttributeWithName:(NSString *)attrName;
  508 +
  509 +- (void)addExtendedAttributeWithName:(NSString *)attrName;
  510 +- (void)removeExtendedAttributeWithName:(NSString *)attrName;
  511 +
  512 +#endif /* if TARGET_IPHONE_SIMULATOR */
  513 +
  514 +- (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another;
  515 +- (NSComparisonResult)reverseCompareByModificationDate:(DDLogFileInfo *)another;
  516 +
  517 +@end
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +/**
  17 + * Legacy macros used for 1.9.x backwards compatibility.
  18 + *
  19 + * Imported by default when importing a DDLog.h directly and DD_LEGACY_MACROS is not defined and set to 0.
  20 + **/
  21 +#if DD_LEGACY_MACROS
  22 +
  23 +#warning CocoaLumberjack 1.9.x legacy macros enabled. \
  24 +Disable legacy macros by importing CocoaLumberjack.h or DDLogMacros.h instead of DDLog.h or add `#define DD_LEGACY_MACROS 0` before importing DDLog.h.
  25 +
  26 +#ifndef LOG_LEVEL_DEF
  27 + #define LOG_LEVEL_DEF ddLogLevel
  28 +#endif
  29 +
  30 +#define LOG_FLAG_ERROR DDLogFlagError
  31 +#define LOG_FLAG_WARN DDLogFlagWarning
  32 +#define LOG_FLAG_INFO DDLogFlagInfo
  33 +#define LOG_FLAG_DEBUG DDLogFlagDebug
  34 +#define LOG_FLAG_VERBOSE DDLogFlagVerbose
  35 +
  36 +#define LOG_LEVEL_OFF DDLogLevelOff
  37 +#define LOG_LEVEL_ERROR DDLogLevelError
  38 +#define LOG_LEVEL_WARN DDLogLevelWarning
  39 +#define LOG_LEVEL_INFO DDLogLevelInfo
  40 +#define LOG_LEVEL_DEBUG DDLogLevelDebug
  41 +#define LOG_LEVEL_VERBOSE DDLogLevelVerbose
  42 +#define LOG_LEVEL_ALL DDLogLevelAll
  43 +
  44 +#define LOG_ASYNC_ENABLED YES
  45 +
  46 +#define LOG_ASYNC_ERROR ( NO && LOG_ASYNC_ENABLED)
  47 +#define LOG_ASYNC_WARN (YES && LOG_ASYNC_ENABLED)
  48 +#define LOG_ASYNC_INFO (YES && LOG_ASYNC_ENABLED)
  49 +#define LOG_ASYNC_DEBUG (YES && LOG_ASYNC_ENABLED)
  50 +#define LOG_ASYNC_VERBOSE (YES && LOG_ASYNC_ENABLED)
  51 +
  52 +#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
  53 + [DDLog log : isAsynchronous \
  54 + level : lvl \
  55 + flag : flg \
  56 + context : ctx \
  57 + file : __FILE__ \
  58 + function : fnct \
  59 + line : __LINE__ \
  60 + tag : atag \
  61 + format : (frmt), ## __VA_ARGS__]
  62 +
  63 +#define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \
  64 + do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0)
  65 +
  66 +#define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \
  67 + LOG_MAYBE(async, lvl, flg, ctx, __PRETTY_FUNCTION__, frmt, ## __VA_ARGS__)
  68 +
  69 +#define DDLogError(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_ERROR, LOG_LEVEL_DEF, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__)
  70 +#define DDLogWarn(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_WARN, LOG_LEVEL_DEF, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__)
  71 +#define DDLogInfo(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_INFO, LOG_LEVEL_DEF, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__)
  72 +#define DDLogDebug(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_DEBUG, LOG_LEVEL_DEF, LOG_FLAG_DEBUG, 0, frmt, ##__VA_ARGS__)
  73 +#define DDLogVerbose(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_VERBOSE, LOG_LEVEL_DEF, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__)
  74 +
  75 +#endif
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +// Disable legacy macros
  17 +#ifndef DD_LEGACY_MACROS
  18 + #define DD_LEGACY_MACROS 0
  19 +#endif
  20 +
  21 +#import "DDLog.h"
  22 +
  23 +/**
  24 + * The constant/variable/method responsible for controlling the current log level.
  25 + **/
  26 +#ifndef LOG_LEVEL_DEF
  27 + #define LOG_LEVEL_DEF ddLogLevel
  28 +#endif
  29 +
  30 +/**
  31 + * Whether async should be used by log messages, excluding error messages that are always sent sync.
  32 + **/
  33 +#ifndef LOG_ASYNC_ENABLED
  34 + #define LOG_ASYNC_ENABLED YES
  35 +#endif
  36 +
  37 +/**
  38 + * This is the single macro that all other macros below compile into.
  39 + * This big multiline macro makes all the other macros easier to read.
  40 + **/
  41 +#define LOGV_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, avalist) \
  42 + [DDLog log : isAsynchronous \
  43 + level : lvl \
  44 + flag : flg \
  45 + context : ctx \
  46 + file : __FILE__ \
  47 + function : fnct \
  48 + line : __LINE__ \
  49 + tag : atag \
  50 + format : frmt \
  51 + args : avalist]
  52 +
  53 +/**
  54 + * Define version of the macro that only execute if the log level is above the threshold.
  55 + * The compiled versions essentially look like this:
  56 + *
  57 + * if (logFlagForThisLogMsg & ddLogLevel) { execute log message }
  58 + *
  59 + * When LOG_LEVEL_DEF is defined as ddLogLevel.
  60 + *
  61 + * As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels.
  62 + * This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques.
  63 + *
  64 + * Note that when compiler optimizations are enabled (as they are for your release builds),
  65 + * the log messages above your logging threshold will automatically be compiled out.
  66 + *
  67 + * (If the compiler sees LOG_LEVEL_DEF/ddLogLevel declared as a constant, the compiler simply checks to see
  68 + * if the 'if' statement would execute, and if not it strips it from the binary.)
  69 + *
  70 + * We also define shorthand versions for asynchronous and synchronous logging.
  71 + **/
  72 +#define LOGV_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, avalist) \
  73 + do { if(lvl & flg) LOGV_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, avalist); } while(0)
  74 +
  75 +/**
  76 + * Ready to use log macros with no context or tag.
  77 + **/
  78 +#define DDLogVError(frmt, avalist) LOGV_MAYBE(NO, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
  79 +#define DDLogVWarn(frmt, avalist) LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
  80 +#define DDLogVInfo(frmt, avalist) LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
  81 +#define DDLogVDebug(frmt, avalist) LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
  82 +#define DDLogVVerbose(frmt, avalist) LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
  83 +
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +#import <Foundation/Foundation.h>
  17 +
  18 +// Enable 1.9.x legacy macros if imported directly
  19 +#ifndef DD_LEGACY_MACROS
  20 + #define DD_LEGACY_MACROS 1
  21 +#endif
  22 +// DD_LEGACY_MACROS is checked in the file itself
  23 +#import "DDLegacyMacros.h"
  24 +
  25 +#if OS_OBJECT_USE_OBJC
  26 + #define DISPATCH_QUEUE_REFERENCE_TYPE strong
  27 +#else
  28 + #define DISPATCH_QUEUE_REFERENCE_TYPE assign
  29 +#endif
  30 +
  31 +@class DDLogMessage;
  32 +@class DDLoggerInformation;
  33 +@protocol DDLogger;
  34 +@protocol DDLogFormatter;
  35 +
  36 +/**
  37 + * Define the standard options.
  38 + *
  39 + * We default to only 4 levels because it makes it easier for beginners
  40 + * to make the transition to a logging framework.
  41 + *
  42 + * More advanced users may choose to completely customize the levels (and level names) to suite their needs.
  43 + * For more information on this see the "Custom Log Levels" page:
  44 + * Documentation/CustomLogLevels.md
  45 + *
  46 + * Advanced users may also notice that we're using a bitmask.
  47 + * This is to allow for custom fine grained logging:
  48 + * Documentation/FineGrainedLogging.md
  49 + *
  50 + * -- Flags --
  51 + *
  52 + * Typically you will use the LOG_LEVELS (see below), but the flags may be used directly in certain situations.
  53 + * For example, say you have a lot of warning log messages, and you wanted to disable them.
  54 + * However, you still needed to see your error and info log messages.
  55 + * You could accomplish that with the following:
  56 + *
  57 + * static const DDLogLevel ddLogLevel = DDLogFlagError | DDLogFlagInfo;
  58 + *
  59 + * When LOG_LEVEL_DEF is defined as ddLogLevel.
  60 + *
  61 + * Flags may also be consulted when writing custom log formatters,
  62 + * as the DDLogMessage class captures the individual flag that caused the log message to fire.
  63 + *
  64 + * -- Levels --
  65 + *
  66 + * Log levels are simply the proper bitmask of the flags.
  67 + *
  68 + * -- Booleans --
  69 + *
  70 + * The booleans may be used when your logging code involves more than one line.
  71 + * For example:
  72 + *
  73 + * if (LOG_VERBOSE) {
  74 + * for (id sprocket in sprockets)
  75 + * DDLogVerbose(@"sprocket: %@", [sprocket description])
  76 + * }
  77 + *
  78 + * -- Async --
  79 + *
  80 + * Defines the default asynchronous options.
  81 + * The default philosophy for asynchronous logging is very simple:
  82 + *
  83 + * Log messages with errors should be executed synchronously.
  84 + * After all, an error just occurred. The application could be unstable.
  85 + *
  86 + * All other log messages, such as debug output, are executed asynchronously.
  87 + * After all, if it wasn't an error, then it was just informational output,
  88 + * or something the application was easily able to recover from.
  89 + *
  90 + * -- Changes --
  91 + *
  92 + * You are strongly discouraged from modifying this file.
  93 + * If you do, you make it more difficult on yourself to merge future bug fixes and improvements from the project.
  94 + * Instead, create your own MyLogging.h or ApplicationNameLogging.h or CompanyLogging.h
  95 + *
  96 + * For an example of customizing your logging experience, see the "Custom Log Levels" page:
  97 + * Documentation/CustomLogLevels.md
  98 + **/
  99 +
  100 +/**
  101 + * Flags accompany each log. They are used together with levels to filter out logs.
  102 + */
  103 +typedef NS_OPTIONS(NSUInteger, DDLogFlag){
  104 + /**
  105 + * 0...00001 DDLogFlagError
  106 + */
  107 + DDLogFlagError = (1 << 0),
  108 +
  109 + /**
  110 + * 0...00010 DDLogFlagWarning
  111 + */
  112 + DDLogFlagWarning = (1 << 1),
  113 +
  114 + /**
  115 + * 0...00100 DDLogFlagInfo
  116 + */
  117 + DDLogFlagInfo = (1 << 2),
  118 +
  119 + /**
  120 + * 0...01000 DDLogFlagDebug
  121 + */
  122 + DDLogFlagDebug = (1 << 3),
  123 +
  124 + /**
  125 + * 0...10000 DDLogFlagVerbose
  126 + */
  127 + DDLogFlagVerbose = (1 << 4)
  128 +};
  129 +
  130 +/**
  131 + * Log levels are used to filter out logs. Used together with flags.
  132 + */
  133 +typedef NS_ENUM(NSUInteger, DDLogLevel){
  134 + /**
  135 + * No logs
  136 + */
  137 + DDLogLevelOff = 0,
  138 +
  139 + /**
  140 + * Error logs only
  141 + */
  142 + DDLogLevelError = (DDLogFlagError),
  143 +
  144 + /**
  145 + * Error and warning logs
  146 + */
  147 + DDLogLevelWarning = (DDLogLevelError | DDLogFlagWarning),
  148 +
  149 + /**
  150 + * Error, warning and info logs
  151 + */
  152 + DDLogLevelInfo = (DDLogLevelWarning | DDLogFlagInfo),
  153 +
  154 + /**
  155 + * Error, warning, info and debug logs
  156 + */
  157 + DDLogLevelDebug = (DDLogLevelInfo | DDLogFlagDebug),
  158 +
  159 + /**
  160 + * Error, warning, info, debug and verbose logs
  161 + */
  162 + DDLogLevelVerbose = (DDLogLevelDebug | DDLogFlagVerbose),
  163 +
  164 + /**
  165 + * All logs (1...11111)
  166 + */
  167 + DDLogLevelAll = NSUIntegerMax
  168 +};
  169 +
  170 +NS_ASSUME_NONNULL_BEGIN
  171 +
  172 +/**
  173 + * Extracts just the file name, no path or extension
  174 + *
  175 + * @param filePath input file path
  176 + * @param copy YES if we want the result to be copied
  177 + *
  178 + * @return the file name
  179 + */
  180 +FOUNDATION_EXTERN NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
  181 +
  182 +/**
  183 + * The THIS_FILE macro gives you an NSString of the file name.
  184 + * For simplicity and clarity, the file name does not include the full path or file extension.
  185 + *
  186 + * For example: DDLogWarn(@"%@: Unable to find thingy", THIS_FILE) -> @"MyViewController: Unable to find thingy"
  187 + **/
  188 +#define THIS_FILE (DDExtractFileNameWithoutExtension(__FILE__, NO))
  189 +
  190 +/**
  191 + * The THIS_METHOD macro gives you the name of the current objective-c method.
  192 + *
  193 + * For example: DDLogWarn(@"%@ - Requires non-nil strings", THIS_METHOD) -> @"setMake:model: requires non-nil strings"
  194 + *
  195 + * Note: This does NOT work in straight C functions (non objective-c).
  196 + * Instead you should use the predefined __FUNCTION__ macro.
  197 + **/
  198 +#define THIS_METHOD NSStringFromSelector(_cmd)
  199 +
  200 +
  201 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  202 +#pragma mark -
  203 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  204 +
  205 +/**
  206 + * The main class, exposes all logging mechanisms, loggers, ...
  207 + * For most of the users, this class is hidden behind the logging functions like `DDLogInfo`
  208 + */
  209 +@interface DDLog : NSObject
  210 +
  211 +/**
  212 + * Returns the singleton `DDLog`.
  213 + * The instance is used by `DDLog` class methods.
  214 + */
  215 +@property (class, nonatomic, strong, readonly) DDLog *sharedInstance;
  216 +
  217 +/**
  218 + * Provides access to the underlying logging queue.
  219 + * This may be helpful to Logger classes for things like thread synchronization.
  220 + **/
  221 +@property (class, nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE, readonly) dispatch_queue_t loggingQueue;
  222 +
  223 +/**
  224 + * Logging Primitive.
  225 + *
  226 + * This method is used by the macros or logging functions.
  227 + * It is suggested you stick with the macros as they're easier to use.
  228 + *
  229 + * @param asynchronous YES if the logging is done async, NO if you want to force sync
  230 + * @param level the log level
  231 + * @param flag the log flag
  232 + * @param context the context (if any is defined)
  233 + * @param file the current file
  234 + * @param function the current function
  235 + * @param line the current code line
  236 + * @param tag potential tag
  237 + * @param format the log format
  238 + */
  239 ++ (void)log:(BOOL)asynchronous
  240 + level:(DDLogLevel)level
  241 + flag:(DDLogFlag)flag
  242 + context:(NSInteger)context
  243 + file:(const char *)file
  244 + function:(const char *)function
  245 + line:(NSUInteger)line
  246 + tag:(id __nullable)tag
  247 + format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
  248 +
  249 +/**
  250 + * Logging Primitive.
  251 + *
  252 + * This method is used by the macros or logging functions.
  253 + * It is suggested you stick with the macros as they're easier to use.
  254 + *
  255 + * @param asynchronous YES if the logging is done async, NO if you want to force sync
  256 + * @param level the log level
  257 + * @param flag the log flag
  258 + * @param context the context (if any is defined)
  259 + * @param file the current file
  260 + * @param function the current function
  261 + * @param line the current code line
  262 + * @param tag potential tag
  263 + * @param format the log format
  264 + */
  265 +- (void)log:(BOOL)asynchronous
  266 + level:(DDLogLevel)level
  267 + flag:(DDLogFlag)flag
  268 + context:(NSInteger)context
  269 + file:(const char *)file
  270 + function:(const char *)function
  271 + line:(NSUInteger)line
  272 + tag:(id __nullable)tag
  273 + format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
  274 +
  275 +/**
  276 + * Logging Primitive.
  277 + *
  278 + * This method can be used if you have a prepared va_list.
  279 + * Similar to `log:level:flag:context:file:function:line:tag:format:...`
  280 + *
  281 + * @param asynchronous YES if the logging is done async, NO if you want to force sync
  282 + * @param level the log level
  283 + * @param flag the log flag
  284 + * @param context the context (if any is defined)
  285 + * @param file the current file
  286 + * @param function the current function
  287 + * @param line the current code line
  288 + * @param tag potential tag
  289 + * @param format the log format
  290 + * @param argList the arguments list as a va_list
  291 + */
  292 ++ (void)log:(BOOL)asynchronous
  293 + level:(DDLogLevel)level
  294 + flag:(DDLogFlag)flag
  295 + context:(NSInteger)context
  296 + file:(const char *)file
  297 + function:(const char *)function
  298 + line:(NSUInteger)line
  299 + tag:(id __nullable)tag
  300 + format:(NSString *)format
  301 + args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
  302 +
  303 +/**
  304 + * Logging Primitive.
  305 + *
  306 + * This method can be used if you have a prepared va_list.
  307 + * Similar to `log:level:flag:context:file:function:line:tag:format:...`
  308 + *
  309 + * @param asynchronous YES if the logging is done async, NO if you want to force sync
  310 + * @param level the log level
  311 + * @param flag the log flag
  312 + * @param context the context (if any is defined)
  313 + * @param file the current file
  314 + * @param function the current function
  315 + * @param line the current code line
  316 + * @param tag potential tag
  317 + * @param format the log format
  318 + * @param argList the arguments list as a va_list
  319 + */
  320 +- (void)log:(BOOL)asynchronous
  321 + level:(DDLogLevel)level
  322 + flag:(DDLogFlag)flag
  323 + context:(NSInteger)context
  324 + file:(const char *)file
  325 + function:(const char *)function
  326 + line:(NSUInteger)line
  327 + tag:(id __nullable)tag
  328 + format:(NSString *)format
  329 + args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
  330 +
  331 +/**
  332 + * Logging Primitive.
  333 + *
  334 + * This method can be used if you manualy prepared DDLogMessage.
  335 + *
  336 + * @param asynchronous YES if the logging is done async, NO if you want to force sync
  337 + * @param logMessage the log message stored in a `DDLogMessage` model object
  338 + */
  339 ++ (void)log:(BOOL)asynchronous
  340 + message:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(asynchronous:message:));
  341 +
  342 +/**
  343 + * Logging Primitive.
  344 + *
  345 + * This method can be used if you manualy prepared DDLogMessage.
  346 + *
  347 + * @param asynchronous YES if the logging is done async, NO if you want to force sync
  348 + * @param logMessage the log message stored in a `DDLogMessage` model object
  349 + */
  350 +- (void)log:(BOOL)asynchronous
  351 + message:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(asynchronous:message:));
  352 +
  353 +/**
  354 + * Since logging can be asynchronous, there may be times when you want to flush the logs.
  355 + * The framework invokes this automatically when the application quits.
  356 + **/
  357 ++ (void)flushLog;
  358 +
  359 +/**
  360 + * Since logging can be asynchronous, there may be times when you want to flush the logs.
  361 + * The framework invokes this automatically when the application quits.
  362 + **/
  363 +- (void)flushLog;
  364 +
  365 +/**
  366 + * Loggers
  367 + *
  368 + * In order for your log statements to go somewhere, you should create and add a logger.
  369 + *
  370 + * You can add multiple loggers in order to direct your log statements to multiple places.
  371 + * And each logger can be configured separately.
  372 + * So you could have, for example, verbose logging to the console, but a concise log file with only warnings & errors.
  373 + **/
  374 +
  375 +/**
  376 + * Adds the logger to the system.
  377 + *
  378 + * This is equivalent to invoking `[DDLog addLogger:logger withLogLevel:DDLogLevelAll]`.
  379 + **/
  380 ++ (void)addLogger:(id <DDLogger>)logger;
  381 +
  382 +/**
  383 + * Adds the logger to the system.
  384 + *
  385 + * This is equivalent to invoking `[DDLog addLogger:logger withLogLevel:DDLogLevelAll]`.
  386 + **/
  387 +- (void)addLogger:(id <DDLogger>)logger;
  388 +
  389 +/**
  390 + * Adds the logger to the system.
  391 + *
  392 + * The level that you provide here is a preemptive filter (for performance).
  393 + * That is, the level specified here will be used to filter out logMessages so that
  394 + * the logger is never even invoked for the messages.
  395 + *
  396 + * More information:
  397 + * When you issue a log statement, the logging framework iterates over each logger,
  398 + * and checks to see if it should forward the logMessage to the logger.
  399 + * This check is done using the level parameter passed to this method.
  400 + *
  401 + * For example:
  402 + *
  403 + * `[DDLog addLogger:consoleLogger withLogLevel:DDLogLevelVerbose];`
  404 + * `[DDLog addLogger:fileLogger withLogLevel:DDLogLevelWarning];`
  405 + *
  406 + * `DDLogError(@"oh no");` => gets forwarded to consoleLogger & fileLogger
  407 + * `DDLogInfo(@"hi");` => gets forwarded to consoleLogger only
  408 + *
  409 + * It is important to remember that Lumberjack uses a BITMASK.
  410 + * Many developers & third party frameworks may define extra log levels & flags.
  411 + * For example:
  412 + *
  413 + * `#define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000`
  414 + *
  415 + * So if you specify `DDLogLevelVerbose` to this method, you won't see the framework's trace messages.
  416 + *
  417 + * `(SOME_FRAMEWORK_LOG_FLAG_TRACE & DDLogLevelVerbose) => (01000000 & 00011111) => NO`
  418 + *
  419 + * Consider passing `DDLogLevelAll` to this method, which has all bits set.
  420 + * You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
  421 + * except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
  422 + *
  423 + * `((DDLogLevelAll ^ DDLogLevelVerbose) | DDLogLevelInfo)`
  424 + **/
  425 ++ (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level;
  426 +
  427 +/**
  428 + * Adds the logger to the system.
  429 + *
  430 + * The level that you provide here is a preemptive filter (for performance).
  431 + * That is, the level specified here will be used to filter out logMessages so that
  432 + * the logger is never even invoked for the messages.
  433 + *
  434 + * More information:
  435 + * When you issue a log statement, the logging framework iterates over each logger,
  436 + * and checks to see if it should forward the logMessage to the logger.
  437 + * This check is done using the level parameter passed to this method.
  438 + *
  439 + * For example:
  440 + *
  441 + * `[DDLog addLogger:consoleLogger withLogLevel:DDLogLevelVerbose];`
  442 + * `[DDLog addLogger:fileLogger withLogLevel:DDLogLevelWarning];`
  443 + *
  444 + * `DDLogError(@"oh no");` => gets forwarded to consoleLogger & fileLogger
  445 + * `DDLogInfo(@"hi");` => gets forwarded to consoleLogger only
  446 + *
  447 + * It is important to remember that Lumberjack uses a BITMASK.
  448 + * Many developers & third party frameworks may define extra log levels & flags.
  449 + * For example:
  450 + *
  451 + * `#define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000`
  452 + *
  453 + * So if you specify `DDLogLevelVerbose` to this method, you won't see the framework's trace messages.
  454 + *
  455 + * `(SOME_FRAMEWORK_LOG_FLAG_TRACE & DDLogLevelVerbose) => (01000000 & 00011111) => NO`
  456 + *
  457 + * Consider passing `DDLogLevelAll` to this method, which has all bits set.
  458 + * You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
  459 + * except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
  460 + *
  461 + * `((DDLogLevelAll ^ DDLogLevelVerbose) | DDLogLevelInfo)`
  462 + **/
  463 +- (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level;
  464 +
  465 +/**
  466 + * Remove the logger from the system
  467 + */
  468 ++ (void)removeLogger:(id <DDLogger>)logger;
  469 +
  470 +/**
  471 + * Remove the logger from the system
  472 + */
  473 +- (void)removeLogger:(id <DDLogger>)logger;
  474 +
  475 +/**
  476 + * Remove all the current loggers
  477 + */
  478 ++ (void)removeAllLoggers;
  479 +
  480 +/**
  481 + * Remove all the current loggers
  482 + */
  483 +- (void)removeAllLoggers;
  484 +
  485 +/**
  486 + * Return all the current loggers
  487 + */
  488 +@property (class, nonatomic, copy, readonly) NSArray<id<DDLogger>> *allLoggers;
  489 +
  490 +/**
  491 + * Return all the current loggers
  492 + */
  493 +@property (nonatomic, copy, readonly) NSArray<id<DDLogger>> *allLoggers;
  494 +
  495 +/**
  496 + * Return all the current loggers with their level (aka DDLoggerInformation).
  497 + */
  498 +@property (class, nonatomic, copy, readonly) NSArray<DDLoggerInformation *> *allLoggersWithLevel;
  499 +
  500 +/**
  501 + * Return all the current loggers with their level (aka DDLoggerInformation).
  502 + */
  503 +@property (nonatomic, copy, readonly) NSArray<DDLoggerInformation *> *allLoggersWithLevel;
  504 +
  505 +/**
  506 + * Registered Dynamic Logging
  507 + *
  508 + * These methods allow you to obtain a list of classes that are using registered dynamic logging,
  509 + * and also provides methods to get and set their log level during run time.
  510 + **/
  511 +
  512 +/**
  513 + * Returns an array with the classes that are using registered dynamic logging
  514 + */
  515 +@property (class, nonatomic, copy, readonly) NSArray<Class> *registeredClasses;
  516 +
  517 +/**
  518 + * Returns an array with the classes names that are using registered dynamic logging
  519 + */
  520 +@property (class, nonatomic, copy, readonly) NSArray<NSString*> *registeredClassNames;
  521 +
  522 +/**
  523 + * Returns the current log level for a certain class
  524 + *
  525 + * @param aClass `Class` param
  526 + */
  527 ++ (DDLogLevel)levelForClass:(Class)aClass;
  528 +
  529 +/**
  530 + * Returns the current log level for a certain class
  531 + *
  532 + * @param aClassName string param
  533 + */
  534 ++ (DDLogLevel)levelForClassWithName:(NSString *)aClassName;
  535 +
  536 +/**
  537 + * Set the log level for a certain class
  538 + *
  539 + * @param level the new level
  540 + * @param aClass `Class` param
  541 + */
  542 ++ (void)setLevel:(DDLogLevel)level forClass:(Class)aClass;
  543 +
  544 +/**
  545 + * Set the log level for a certain class
  546 + *
  547 + * @param level the new level
  548 + * @param aClassName string param
  549 + */
  550 ++ (void)setLevel:(DDLogLevel)level forClassWithName:(NSString *)aClassName;
  551 +
  552 +@end
  553 +
  554 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  555 +#pragma mark -
  556 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  557 +
  558 +/**
  559 + * This protocol describes a basic logger behavior.
  560 + * Basically, it can log messages, store a logFormatter plus a bunch of optional behaviors.
  561 + * (i.e. flush, get its loggerQueue, get its name, ...
  562 + */
  563 +@protocol DDLogger <NSObject>
  564 +
  565 +/**
  566 + * The log message method
  567 + *
  568 + * @param logMessage the message (model)
  569 + */
  570 +- (void)logMessage:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(message:));
  571 +
  572 +/**
  573 + * Formatters may optionally be added to any logger.
  574 + *
  575 + * If no formatter is set, the logger simply logs the message as it is given in logMessage,
  576 + * or it may use its own built in formatting style.
  577 + **/
  578 +@property (nonatomic, strong) id <DDLogFormatter> logFormatter;
  579 +
  580 +@optional
  581 +
  582 +/**
  583 + * Since logging is asynchronous, adding and removing loggers is also asynchronous.
  584 + * In other words, the loggers are added and removed at appropriate times with regards to log messages.
  585 + *
  586 + * - Loggers will not receive log messages that were executed prior to when they were added.
  587 + * - Loggers will not receive log messages that were executed after they were removed.
  588 + *
  589 + * These methods are executed in the logging thread/queue.
  590 + * This is the same thread/queue that will execute every logMessage: invocation.
  591 + * Loggers may use these methods for thread synchronization or other setup/teardown tasks.
  592 + **/
  593 +- (void)didAddLogger;
  594 +
  595 +/**
  596 + * Since logging is asynchronous, adding and removing loggers is also asynchronous.
  597 + * In other words, the loggers are added and removed at appropriate times with regards to log messages.
  598 + *
  599 + * - Loggers will not receive log messages that were executed prior to when they were added.
  600 + * - Loggers will not receive log messages that were executed after they were removed.
  601 + *
  602 + * These methods are executed in the logging thread/queue given in parameter.
  603 + * This is the same thread/queue that will execute every logMessage: invocation.
  604 + * Loggers may use the queue parameter to set specific values on the queue with dispatch_set_specific() function.
  605 + **/
  606 +- (void)didAddLoggerInQueue:(dispatch_queue_t)queue;
  607 +
  608 +/**
  609 + * See the above description for `didAddLoger`
  610 + */
  611 +- (void)willRemoveLogger;
  612 +
  613 +/**
  614 + * Some loggers may buffer IO for optimization purposes.
  615 + * For example, a database logger may only save occasionaly as the disk IO is slow.
  616 + * In such loggers, this method should be implemented to flush any pending IO.
  617 + *
  618 + * This allows invocations of DDLog's flushLog method to be propogated to loggers that need it.
  619 + *
  620 + * Note that DDLog's flushLog method is invoked automatically when the application quits,
  621 + * and it may be also invoked manually by the developer prior to application crashes, or other such reasons.
  622 + **/
  623 +- (void)flush;
  624 +
  625 +/**
  626 + * Each logger is executed concurrently with respect to the other loggers.
  627 + * Thus, a dedicated dispatch queue is used for each logger.
  628 + * Logger implementations may optionally choose to provide their own dispatch queue.
  629 + **/
  630 +@property (nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE, readonly) dispatch_queue_t loggerQueue;
  631 +
  632 +/**
  633 + * If the logger implementation does not choose to provide its own queue,
  634 + * one will automatically be created for it.
  635 + * The created queue will receive its name from this method.
  636 + * This may be helpful for debugging or profiling reasons.
  637 + **/
  638 +@property (nonatomic, readonly) NSString *loggerName;
  639 +
  640 +@end
  641 +
  642 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  643 +#pragma mark -
  644 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  645 +
  646 +/**
  647 + * This protocol describes the behavior of a log formatter
  648 + */
  649 +@protocol DDLogFormatter <NSObject>
  650 +@required
  651 +
  652 +/**
  653 + * Formatters may optionally be added to any logger.
  654 + * This allows for increased flexibility in the logging environment.
  655 + * For example, log messages for log files may be formatted differently than log messages for the console.
  656 + *
  657 + * For more information about formatters, see the "Custom Formatters" page:
  658 + * Documentation/CustomFormatters.md
  659 + *
  660 + * The formatter may also optionally filter the log message by returning nil,
  661 + * in which case the logger will not log the message.
  662 + **/
  663 +- (NSString * __nullable)formatLogMessage:(DDLogMessage *)logMessage NS_SWIFT_NAME(format(message:));
  664 +
  665 +@optional
  666 +
  667 +/**
  668 + * A single formatter instance can be added to multiple loggers.
  669 + * These methods provides hooks to notify the formatter of when it's added/removed.
  670 + *
  671 + * This is primarily for thread-safety.
  672 + * If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
  673 + * Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter),
  674 + * it could possibly use these hooks to switch to thread-safe versions of the code.
  675 + **/
  676 +- (void)didAddToLogger:(id <DDLogger>)logger;
  677 +
  678 +/**
  679 + * A single formatter instance can be added to multiple loggers.
  680 + * These methods provides hooks to notify the formatter of when it's added/removed.
  681 + *
  682 + * This is primarily for thread-safety.
  683 + * If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
  684 + * Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter),
  685 + * it could possibly use these hooks to switch to thread-safe versions of the code or use dispatch_set_specific()
  686 +.* to add its own specific values.
  687 + **/
  688 +- (void)didAddToLogger:(id <DDLogger>)logger inQueue:(dispatch_queue_t)queue;
  689 +
  690 +/**
  691 + * See the above description for `didAddToLogger:`
  692 + */
  693 +- (void)willRemoveFromLogger:(id <DDLogger>)logger;
  694 +
  695 +@end
  696 +
  697 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  698 +#pragma mark -
  699 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  700 +
  701 +/**
  702 + * This protocol describes a dynamic logging component
  703 + */
  704 +@protocol DDRegisteredDynamicLogging
  705 +
  706 +/**
  707 + * Implement these methods to allow a file's log level to be managed from a central location.
  708 + *
  709 + * This is useful if you'd like to be able to change log levels for various parts
  710 + * of your code from within the running application.
  711 + *
  712 + * Imagine pulling up the settings for your application,
  713 + * and being able to configure the logging level on a per file basis.
  714 + *
  715 + * The implementation can be very straight-forward:
  716 + *
  717 + * ```
  718 + * + (int)ddLogLevel
  719 + * {
  720 + * return ddLogLevel;
  721 + * }
  722 + *
  723 + * + (void)ddSetLogLevel:(DDLogLevel)level
  724 + * {
  725 + * ddLogLevel = level;
  726 + * }
  727 + * ```
  728 + **/
  729 +@property (class, nonatomic, readwrite, setter=ddSetLogLevel:) DDLogLevel ddLogLevel;
  730 +
  731 +@end
  732 +
  733 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  734 +#pragma mark -
  735 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  736 +
  737 +#ifndef NS_DESIGNATED_INITIALIZER
  738 + #define NS_DESIGNATED_INITIALIZER
  739 +#endif
  740 +
  741 +/**
  742 + * Log message options, allow copying certain log elements
  743 + */
  744 +typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
  745 + /**
  746 + * Use this to use a copy of the file path
  747 + */
  748 + DDLogMessageCopyFile = 1 << 0,
  749 + /**
  750 + * Use this to use a copy of the function name
  751 + */
  752 + DDLogMessageCopyFunction = 1 << 1,
  753 + /**
  754 + * Use this to use avoid a copy of the message
  755 + */
  756 + DDLogMessageDontCopyMessage = 1 << 2
  757 +};
  758 +
  759 +/**
  760 + * The `DDLogMessage` class encapsulates information about the log message.
  761 + * If you write custom loggers or formatters, you will be dealing with objects of this class.
  762 + **/
  763 +@interface DDLogMessage : NSObject <NSCopying>
  764 +{
  765 + // Direct accessors to be used only for performance
  766 + @public
  767 + NSString *_message;
  768 + DDLogLevel _level;
  769 + DDLogFlag _flag;
  770 + NSInteger _context;
  771 + NSString *_file;
  772 + NSString *_fileName;
  773 + NSString *_function;
  774 + NSUInteger _line;
  775 + id _tag;
  776 + DDLogMessageOptions _options;
  777 + NSDate *_timestamp;
  778 + NSString *_threadID;
  779 + NSString *_threadName;
  780 + NSString *_queueLabel;
  781 +}
  782 +
  783 +/**
  784 + * Default `init` for empty messages.
  785 + */
  786 +- (instancetype)init NS_DESIGNATED_INITIALIZER;
  787 +
  788 +/**
  789 + * Standard init method for a log message object.
  790 + * Used by the logging primitives. (And the macros use the logging primitives.)
  791 + *
  792 + * If you find need to manually create logMessage objects, there is one thing you should be aware of:
  793 + *
  794 + * If no flags are passed, the method expects the file and function parameters to be string literals.
  795 + * That is, it expects the given strings to exist for the duration of the object's lifetime,
  796 + * and it expects the given strings to be immutable.
  797 + * In other words, it does not copy these strings, it simply points to them.
  798 + * This is due to the fact that __FILE__ and __FUNCTION__ are usually used to specify these parameters,
  799 + * so it makes sense to optimize and skip the unnecessary allocations.
  800 + * However, if you need them to be copied you may use the options parameter to specify this.
  801 + *
  802 + * @param message the message
  803 + * @param level the log level
  804 + * @param flag the log flag
  805 + * @param context the context (if any is defined)
  806 + * @param file the current file
  807 + * @param function the current function
  808 + * @param line the current code line
  809 + * @param tag potential tag
  810 + * @param options a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction.
  811 + * @param timestamp the log timestamp
  812 + *
  813 + * @return a new instance of a log message model object
  814 + */
  815 +- (instancetype)initWithMessage:(NSString *)message
  816 + level:(DDLogLevel)level
  817 + flag:(DDLogFlag)flag
  818 + context:(NSInteger)context
  819 + file:(NSString *)file
  820 + function:(NSString * __nullable)function
  821 + line:(NSUInteger)line
  822 + tag:(id __nullable)tag
  823 + options:(DDLogMessageOptions)options
  824 + timestamp:(NSDate * __nullable)timestamp NS_DESIGNATED_INITIALIZER;
  825 +
  826 +/**
  827 + * Read-only properties
  828 + **/
  829 +
  830 +/**
  831 + * The log message
  832 + */
  833 +@property (readonly, nonatomic) NSString *message;
  834 +@property (readonly, nonatomic) DDLogLevel level;
  835 +@property (readonly, nonatomic) DDLogFlag flag;
  836 +@property (readonly, nonatomic) NSInteger context;
  837 +@property (readonly, nonatomic) NSString *file;
  838 +@property (readonly, nonatomic) NSString *fileName;
  839 +@property (readonly, nonatomic) NSString * __nullable function;
  840 +@property (readonly, nonatomic) NSUInteger line;
  841 +@property (readonly, nonatomic) id __nullable tag;
  842 +@property (readonly, nonatomic) DDLogMessageOptions options;
  843 +@property (readonly, nonatomic) NSDate *timestamp;
  844 +@property (readonly, nonatomic) NSString *threadID; // ID as it appears in NSLog calculated from the machThreadID
  845 +@property (readonly, nonatomic) NSString *threadName;
  846 +@property (readonly, nonatomic) NSString *queueLabel;
  847 +
  848 +@end
  849 +
  850 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  851 +#pragma mark -
  852 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  853 +
  854 +/**
  855 + * The `DDLogger` protocol specifies that an optional formatter can be added to a logger.
  856 + * Most (but not all) loggers will want to support formatters.
  857 + *
  858 + * However, writting getters and setters in a thread safe manner,
  859 + * while still maintaining maximum speed for the logging process, is a difficult task.
  860 + *
  861 + * To do it right, the implementation of the getter/setter has strict requiremenets:
  862 + * - Must NOT require the `logMessage:` method to acquire a lock.
  863 + * - Must NOT require the `logMessage:` method to access an atomic property (also a lock of sorts).
  864 + *
  865 + * To simplify things, an abstract logger is provided that implements the getter and setter.
  866 + *
  867 + * Logger implementations may simply extend this class,
  868 + * and they can ACCESS THE FORMATTER VARIABLE DIRECTLY from within their `logMessage:` method!
  869 + **/
  870 +@interface DDAbstractLogger : NSObject <DDLogger>
  871 +{
  872 + // Direct accessors to be used only for performance
  873 + @public
  874 + id <DDLogFormatter> _logFormatter;
  875 + dispatch_queue_t _loggerQueue;
  876 +}
  877 +
  878 +@property (nonatomic, strong, nullable) id <DDLogFormatter> logFormatter;
  879 +@property (nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE) dispatch_queue_t loggerQueue;
  880 +
  881 +// For thread-safety assertions
  882 +
  883 +/**
  884 + * Return YES if the current logger uses a global queue for logging
  885 + */
  886 +@property (nonatomic, readonly, getter=isOnGlobalLoggingQueue) BOOL onGlobalLoggingQueue;
  887 +
  888 +/**
  889 + * Return YES if the current logger uses the internal designated queue for logging
  890 + */
  891 +@property (nonatomic, readonly, getter=isOnInternalLoggerQueue) BOOL onInternalLoggerQueue;
  892 +
  893 +@end
  894 +
  895 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  896 +#pragma mark -
  897 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  898 +
  899 +@interface DDLoggerInformation : NSObject
  900 +
  901 +@property (nonatomic, readonly) id <DDLogger> logger;
  902 +@property (nonatomic, readonly) DDLogLevel level;
  903 +
  904 ++ (DDLoggerInformation *)informationWithLogger:(id <DDLogger>)logger
  905 + andLevel:(DDLogLevel)level;
  906 +
  907 +@end
  908 +
  909 +NS_ASSUME_NONNULL_END
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +// Disable legacy macros
  17 +#ifndef DD_LEGACY_MACROS
  18 + #define DD_LEGACY_MACROS 0
  19 +#endif
  20 +
  21 +#import "DDLog.h"
  22 +
  23 +/**
  24 + * The constant/variable/method responsible for controlling the current log level.
  25 + **/
  26 +#ifndef LOG_LEVEL_DEF
  27 + #define LOG_LEVEL_DEF ddLogLevel
  28 +#endif
  29 +
  30 +/**
  31 + * Whether async should be used by log messages, excluding error messages that are always sent sync.
  32 + **/
  33 +#ifndef LOG_ASYNC_ENABLED
  34 + #define LOG_ASYNC_ENABLED YES
  35 +#endif
  36 +
  37 +/**
  38 + * These are the two macros that all other macros below compile into.
  39 + * These big multiline macros makes all the other macros easier to read.
  40 + **/
  41 +#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
  42 + [DDLog log : isAsynchronous \
  43 + level : lvl \
  44 + flag : flg \
  45 + context : ctx \
  46 + file : __FILE__ \
  47 + function : fnct \
  48 + line : __LINE__ \
  49 + tag : atag \
  50 + format : (frmt), ## __VA_ARGS__]
  51 +
  52 +#define LOG_MACRO_TO_DDLOG(ddlog, isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
  53 + [ddlog log : isAsynchronous \
  54 + level : lvl \
  55 + flag : flg \
  56 + context : ctx \
  57 + file : __FILE__ \
  58 + function : fnct \
  59 + line : __LINE__ \
  60 + tag : atag \
  61 + format : (frmt), ## __VA_ARGS__]
  62 +
  63 +/**
  64 + * Define version of the macro that only execute if the log level is above the threshold.
  65 + * The compiled versions essentially look like this:
  66 + *
  67 + * if (logFlagForThisLogMsg & ddLogLevel) { execute log message }
  68 + *
  69 + * When LOG_LEVEL_DEF is defined as ddLogLevel.
  70 + *
  71 + * As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels.
  72 + * This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques.
  73 + *
  74 + * Note that when compiler optimizations are enabled (as they are for your release builds),
  75 + * the log messages above your logging threshold will automatically be compiled out.
  76 + *
  77 + * (If the compiler sees LOG_LEVEL_DEF/ddLogLevel declared as a constant, the compiler simply checks to see
  78 + * if the 'if' statement would execute, and if not it strips it from the binary.)
  79 + *
  80 + * We also define shorthand versions for asynchronous and synchronous logging.
  81 + **/
  82 +#define LOG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
  83 + do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
  84 +
  85 +#define LOG_MAYBE_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ...) \
  86 + do { if(lvl & flg) LOG_MACRO_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
  87 +
  88 +/**
  89 + * Ready to use log macros with no context or tag.
  90 + **/
  91 +#define DDLogError(frmt, ...) LOG_MAYBE(NO, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  92 +#define DDLogWarn(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  93 +#define DDLogInfo(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  94 +#define DDLogDebug(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  95 +#define DDLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  96 +
  97 +#define DDLogErrorToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, NO, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  98 +#define DDLogWarnToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  99 +#define DDLogInfoToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  100 +#define DDLogDebugToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  101 +#define DDLogVerboseToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +#import <Foundation/Foundation.h>
  17 +
  18 +// Disable legacy macros
  19 +#ifndef DD_LEGACY_MACROS
  20 + #define DD_LEGACY_MACROS 0
  21 +#endif
  22 +
  23 +#import "DDLog.h"
  24 +
  25 +/**
  26 + * This class provides a logger for the Apple os_log facility.
  27 + **/
  28 +@interface DDOSLogger : DDAbstractLogger <DDLogger>
  29 +
  30 +/**
  31 + * Singleton method
  32 + *
  33 + * @return the shared instance
  34 + */
  35 +@property (class, readonly, strong) DDOSLogger *sharedInstance;
  36 +
  37 +@end
  1 +// Software License Agreement (BSD License)
  2 +//
  3 +// Copyright (c) 2010-2016, Deusty, LLC
  4 +// All rights reserved.
  5 +//
  6 +// Redistribution and use of this software in source and binary forms,
  7 +// with or without modification, are permitted provided that the following conditions are met:
  8 +//
  9 +// * Redistributions of source code must retain the above copyright notice,
  10 +// this list of conditions and the following disclaimer.
  11 +//
  12 +// * Neither the name of Deusty nor the names of its contributors may be used
  13 +// to endorse or promote products derived from this software without specific
  14 +// prior written permission of Deusty, LLC.
  15 +
  16 +// Disable legacy macros
  17 +#ifndef DD_LEGACY_MACROS
  18 + #define DD_LEGACY_MACROS 0
  19 +#endif
  20 +
  21 +#import "DDLog.h"
  22 +
  23 +#define LOG_CONTEXT_ALL INT_MAX
  24 +
  25 +#pragma clang diagnostic push
  26 +#pragma clang diagnostic ignored "-Wunused-function"
  27 +#if !(TARGET_OS_OSX)
  28 + // iOS or tvOS or watchOS
  29 + #import <UIKit/UIColor.h>
  30 + typedef UIColor DDColor;
  31 + static inline DDColor* DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
  32 +#elif defined(DD_CLI) || !__has_include(<AppKit/NSColor.h>)
  33 + // OS X CLI
  34 + #import "CLIColor.h"
  35 + typedef CLIColor DDColor;
  36 + static inline DDColor* DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
  37 +#else
  38 + // OS X with AppKit
  39 + #import <AppKit/NSColor.h>
  40 + typedef NSColor DDColor;
  41 + static inline DDColor* DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
  42 +#endif
  43 +#pragma clang diagnostic pop
  44 +
  45 +
  46 +/**
  47 + * This class provides a logger for Terminal output or Xcode console output,
  48 + * depending on where you are running your code.
  49 + *
  50 + * As described in the "Getting Started" page,
  51 + * the traditional NSLog() function directs it's output to two places:
  52 + *
  53 + * - Apple System Log (so it shows up in Console.app)
  54 + * - StdErr (if stderr is a TTY, so log statements show up in Xcode console)
  55 + *
  56 + * To duplicate NSLog() functionality you can simply add this logger and an asl logger.
  57 + * However, if you instead choose to use file logging (for faster performance),
  58 + * you may choose to use only a file logger and a tty logger.
  59 + **/
  60 +@interface DDTTYLogger : DDAbstractLogger <DDLogger>
  61 +
  62 +/**
  63 + * Singleton method
  64 + */
  65 +@property (class, readonly, strong) DDTTYLogger *sharedInstance;
  66 +
  67 +/* Inherited from the DDLogger protocol:
  68 + *
  69 + * Formatters may optionally be added to any logger.
  70 + *
  71 + * If no formatter is set, the logger simply logs the message as it is given in logMessage,
  72 + * or it may use its own built in formatting style.
  73 + *
  74 + * More information about formatters can be found here:
  75 + * Documentation/CustomFormatters.md
  76 + *
  77 + * The actual implementation of these methods is inherited from DDAbstractLogger.
  78 +
  79 + - (id <DDLogFormatter>)logFormatter;
  80 + - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
  81 +
  82 + */
  83 +
  84 +/**
  85 + * Want to use different colors for different log levels?
  86 + * Enable this property.
  87 + *
  88 + * If you run the application via the Terminal (not Xcode),
  89 + * the logger will map colors to xterm-256color or xterm-color (if available).
  90 + *
  91 + * Xcode does NOT natively support colors in the Xcode debugging console.
  92 + * You'll need to install the XcodeColors plugin to see colors in the Xcode console.
  93 + * https://github.com/robbiehanson/XcodeColors
  94 + *
  95 + * The default value is NO.
  96 + **/
  97 +@property (readwrite, assign) BOOL colorsEnabled;
  98 +
  99 +/**
  100 + * When using a custom formatter you can set the `logMessage` method not to append
  101 + * `\n` character after each output. This allows for some greater flexibility with
  102 + * custom formatters. Default value is YES.
  103 + **/
  104 +@property (nonatomic, readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
  105 +
  106 +/**
  107 + * The default color set (foregroundColor, backgroundColor) is:
  108 + *
  109 + * - DDLogFlagError = (red, nil)
  110 + * - DDLogFlagWarning = (orange, nil)
  111 + *
  112 + * You can customize the colors however you see fit.
  113 + * Please note that you are passing a flag, NOT a level.
  114 + *
  115 + * GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:DDLogFlagInfo]; // <- Good :)
  116 + * BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:DDLogLevelInfo]; // <- BAD! :(
  117 + *
  118 + * DDLogFlagInfo = 0...00100
  119 + * DDLogLevelInfo = 0...00111 <- Would match DDLogFlagInfo and DDLogFlagWarning and DDLogFlagError
  120 + *
  121 + * If you run the application within Xcode, then the XcodeColors plugin is required.
  122 + *
  123 + * If you run the application from a shell, then DDTTYLogger will automatically map the given color to
  124 + * the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.)
  125 + *
  126 + * This method invokes setForegroundColor:backgroundColor:forFlag:context: and applies it to `LOG_CONTEXT_ALL`.
  127 + **/
  128 +- (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(DDLogFlag)mask;
  129 +
  130 +/**
  131 + * Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
  132 + *
  133 + * A logging context is often used to identify log messages coming from a 3rd party framework,
  134 + * although logging context's can be used for many different functions.
  135 + *
  136 + * Use LOG_CONTEXT_ALL to set the deafult color for all contexts that have no specific color set defined.
  137 + *
  138 + * Logging context's are explained in further detail here:
  139 + * Documentation/CustomContext.md
  140 + **/
  141 +- (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(DDLogFlag)mask context:(NSInteger)ctxt;
  142 +
  143 +/**
  144 + * Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile.
  145 + * For example, you could do something like this:
  146 + *
  147 + * static NSString *const PurpleTag = @"PurpleTag";
  148 + *
  149 + * #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
  150 + *
  151 + * And then where you configure CocoaLumberjack:
  152 + *
  153 + * purple = DDMakeColor((64/255.0), (0/255.0), (128/255.0));
  154 + *
  155 + * or any UIColor/NSColor constructor.
  156 + *
  157 + * Note: For CLI OS X projects that don't link with AppKit use CLIColor objects instead
  158 + *
  159 + * [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
  160 + * [DDLog addLogger:[DDTTYLogger sharedInstance]];
  161 + *
  162 + * This would essentially give you a straight NSLog replacement that prints in purple:
  163 + *
  164 + * DDLogPurple(@"I'm a purple log message!");
  165 + **/
  166 +- (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forTag:(id <NSCopying>)tag;
  167 +
  168 +/**
  169 + * Clearing color profiles.
  170 + **/
  171 +- (void)clearColorsForFlag:(DDLogFlag)mask;
  172 +- (void)clearColorsForFlag:(DDLogFlag)mask context:(NSInteger)context;
  173 +- (void)clearColorsForTag:(id <NSCopying>)tag;
  174 +- (void)clearColorsForAllFlags;
  175 +- (void)clearColorsForAllTags;
  176 +- (void)clearAllColors;
  177 +
  178 +@end
  1 +/*
  2 + * This file is part of the HHWebImage package.
  3 + * (c) Olivier Poitrey <rs@dailymotion.com>
  4 + *
  5 + * For the full copyright and license information, please view the LICENSE
  6 + * file that was distributed with this source code.
  7 + */
  8 +
  9 +#import "HHWebImageCompat.h"
  10 +
  11 +#if HH_MAC
  12 +
  13 +// A subclass of `NSBitmapImageRep` to fix that GIF loop count issue because `NSBitmapImageRep` will reset `NSImageCurrentFrameDuration` by using `kCGImagePropertyGIFDelayTime` but not `kCGImagePropertyGIFUnclampedDelayTime`.
  14 +// Built in GIF coder use this instead of `NSBitmapImageRep` for better GIF rendering. If you do not want this, only enable `HHWebImageImageIOCoder`, which just call `NSImage` API and actually use `NSBitmapImageRep` for GIF image.
  15 +
  16 +@interface HHAnimatedImageRep : NSBitmapImageRep
  17 +
  18 +@end
  19 +
  20 +#endif
  1 +//
  2 +// HHCameraImage.h
  3 +// camera_Demo
  4 +//
  5 +// Created by shmily on 15/10/20.
  6 +// Copyright © 2015年 shmilyAshen. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import <UIKit/UIKit.h>
  11 +
  12 +@interface HHCameraImageModel : NSObject
  13 +
  14 +/// 全尺寸图像
  15 +@property(nonatomic,strong)NSString *fullPath;
  16 +
  17 +@property(nonatomic,strong)NSString *scalledPath;
  18 +
  19 ++ (instancetype)cameraImageWithFullPath:(NSString *)fullPath scalledPath:(NSString *)scalledPath;
  20 +
  21 +- (bool)isMp4;
  22 +
  23 +
  24 +@end
  1 +//
  2 +// HHCameraUtil.h
  3 +// CameraLibrary
  4 +//
  5 +// Created by shmily on 16/5/25.
  6 +// Copyright © 2016年 HHPacs. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import <UIKit/UIKit.h>
  11 +
  12 +// 图片是否压缩临界点
  13 +#define HHImgReduceSize 1000000
  14 +
  15 +@class AVAssetExportSession;
  16 +
  17 +typedef enum : NSUInteger {
  18 + ProTypePacs,
  19 + ProTypeUser
  20 +} ProType;
  21 +
  22 +
  23 +@interface HHCameraUtil : NSObject
  24 +
  25 +/// 是否应该被压缩
  26 +@property(nonatomic,assign)BOOL shouldReduce;
  27 +
  28 +/// 家庭医生使用
  29 +@property(nonatomic, assign)ProType type;
  30 +
  31 +/// 单例
  32 ++ (instancetype)shareInstance;
  33 +
  34 +/// 获取图片bundle
  35 +//+ (NSBundle *)getBundle;
  36 +
  37 +/// 根据图片名获取图片
  38 ++ (UIImage *)getImage:(NSString *)imgName;
  39 +
  40 +/// 获取视频的缩略图
  41 +/// @param videoURL 视频的URL
  42 +/// @param time 截图时间
  43 ++ (UIImage *)thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time;
  44 +
  45 +/// 根据视频路径获取对应缩略图
  46 +//+ (UIImage *)thumImageForVideo:(NSString *)videoPath;
  47 +
  48 +/// 能否被压缩(小于200k不被压缩)
  49 ++ (BOOL)isCanReduce:(UIImage *)image;
  50 +
  51 ++ (BOOL)isCanReduceFile:(NSString *)imgPath;
  52 +
  53 +/// 压缩图像后覆盖原图
  54 ++ (BOOL)reduceImage:(UIImage *)img path:(NSString *)path;
  55 +
  56 ++ (BOOL)isImage:(NSString *)path;
  57 +
  58 +/// 创建图片的本地路径
  59 +///
  60 +/// @param prefix 文件头
  61 ++ (NSString *)createDocumentPath:(NSString *)prefix;
  62 +
  63 +// 获取图片(视频)缩略图路径
  64 ++ (NSString *)getScallPath:(NSString *)fullPath;
  65 +
  66 +/// 写入文件
  67 ++ (NSString *)writeImageToFile:(UIImage *)image;
  68 +
  69 ++ (NSString *)writeImageToFile:(UIImage *)image scale:(CGSize)size fullPath:(NSString *)fullPath;
  70 +
  71 ++ (NSString *)writeScaledImg:(UIImage *)image scale:(CGSize)size fullPath:(NSString *)fullPath;
  72 +
  73 +/// 压缩图片
  74 ++ (void)zipImages:(NSArray<NSString *> *)imgPaths;
  75 +
  76 ++ (UIImage *)fixOrientation:(UIImage *)aImag;
  77 +
  78 ++ (void)videoFixOrientation: (NSURL *)url path:(NSString *)path finished:(void (^)(AVAssetExportSession *))finishBlock;
  79 +
  80 ++ (Boolean)isIPad;
  81 +
  82 +@end
  1 +/*
  2 + * This file is part of the HHWebImage package.
  3 + * (c) Olivier Poitrey <rs@dailymotion.com>
  4 + *
  5 + * For the full copyright and license information, please view the LICENSE
  6 + * file that was distributed with this source code.
  7 + */
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import "HHWebImageCompat.h"
  11 +#import "HHImageCacheConfig.h"
  12 +
  13 +typedef NS_ENUM(NSInteger, HHImageCacheType) {
  14 + /**
  15 + * The image wasn't available the HHWebImage caches, but was downloaded from the web.
  16 + */
  17 + HHImageCacheTypeNone,
  18 + /**
  19 + * The image was obtained from the disk cache.
  20 + */
  21 + HHImageCacheTypeDisk,
  22 + /**
  23 + * The image was obtained from the memory cache.
  24 + */
  25 + HHImageCacheTypeMemory
  26 +};
  27 +
  28 +typedef NS_OPTIONS(NSUInteger, HHImageCacheOptions) {
  29 + /**
  30 + * By default, we do not query disk data when the image is cached in memory. This mask can force to query disk data at the same time.
  31 + */
  32 + HHImageCacheQueryDataWhenInMemory = 1 << 0,
  33 + /**
  34 + * By default, we query the memory cache synchronously, disk cache asynchronously. This mask can force to query disk cache synchronously.
  35 + */
  36 + HHImageCacheQueryDiskSync = 1 << 1
  37 +};
  38 +
  39 +typedef void(^HHCacheQueryCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, HHImageCacheType cacheType);
  40 +
  41 +typedef void(^HHWebImageCheckCacheCompletionBlock)(BOOL isInCache);
  42 +
  43 +typedef void(^HHWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);
  44 +
  45 +
  46 +/**
  47 + * HHImageCache maintains a memory cache and an optional disk cache. Disk cache write operations are performed
  48 + * asynchronous so it doesn’t add unnecessary latency to the UI.
  49 + */
  50 +@interface HHImageCache : NSObject
  51 +
  52 +#pragma mark - Properties
  53 +
  54 +/**
  55 + * Cache Config object - storing all kind of settings
  56 + */
  57 +@property (nonatomic, nonnull, readonly) HHImageCacheConfig *config;
  58 +
  59 +/**
  60 + * The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory.
  61 + */
  62 +@property (assign, nonatomic) NSUInteger maxMemoryCost;
  63 +
  64 +/**
  65 + * The maximum number of objects the cache should hold.
  66 + */
  67 +@property (assign, nonatomic) NSUInteger maxMemoryCountLimit;
  68 +
  69 +#pragma mark - Singleton and initialization
  70 +
  71 +/**
  72 + * Returns global shared cache instance
  73 + *
  74 + * @return HHImageCache global instance
  75 + */
  76 ++ (nonnull instancetype)sharedImageCache;
  77 +
  78 +/**
  79 + * Init a new cache store with a specific namespace
  80 + *
  81 + * @param ns The namespace to use for this cache store
  82 + */
  83 +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns;
  84 +
  85 +/**
  86 + * Init a new cache store with a specific namespace and directory
  87 + *
  88 + * @param ns The namespace to use for this cache store
  89 + * @param directory Directory to cache disk images in
  90 + */
  91 +- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns
  92 + diskCacheDirectory:(nonnull NSString *)directory NS_DESIGNATED_INITIALIZER;
  93 +
  94 +#pragma mark - Cache paths
  95 +
  96 +- (nullable NSString *)makeDiskCachePath:(nonnull NSString*)fullNamespace;
  97 +
  98 +/**
  99 + * Add a read-only cache path to search for images pre-cached by HHImageCache
  100 + * Useful if you want to bundle pre-loaded images with your app
  101 + *
  102 + * @param path The path to use for this read-only cache path
  103 + */
  104 +- (void)addReadOnlyCachePath:(nonnull NSString *)path;
  105 +
  106 +#pragma mark - Store Ops
  107 +
  108 +/**
  109 + * Asynchronously store an image into memory and disk cache at the given key.
  110 + *
  111 + * @param image The image to store
  112 + * @param key The unique image cache key, usually it's image absolute URL
  113 + * @param completionBlock A block executed after the operation is finished
  114 + */
  115 +- (void)storeImage:(nullable UIImage *)image
  116 + forKey:(nullable NSString *)key
  117 + completion:(nullable HHWebImageNoParamsBlock)completionBlock;
  118 +
  119 +/**
  120 + * Asynchronously store an image into memory and disk cache at the given key.
  121 + *
  122 + * @param image The image to store
  123 + * @param key The unique image cache key, usually it's image absolute URL
  124 + * @param toDisk Store the image to disk cache if YES
  125 + * @param completionBlock A block executed after the operation is finished
  126 + */
  127 +- (void)storeImage:(nullable UIImage *)image
  128 + forKey:(nullable NSString *)key
  129 + toDisk:(BOOL)toDisk
  130 + completion:(nullable HHWebImageNoParamsBlock)completionBlock;
  131 +
  132 +/**
  133 + * Asynchronously store an image into memory and disk cache at the given key.
  134 + *
  135 + * @param image The image to store
  136 + * @param imageData The image data as returned by the server, this representation will be used for disk storage
  137 + * instead of converting the given image object into a storable/compressed image format in order
  138 + * to save quality and CPU
  139 + * @param key The unique image cache key, usually it's image absolute URL
  140 + * @param toDisk Store the image to disk cache if YES
  141 + * @param completionBlock A block executed after the operation is finished
  142 + */
  143 +- (void)storeImage:(nullable UIImage *)image
  144 + imageData:(nullable NSData *)imageData
  145 + forKey:(nullable NSString *)key
  146 + toDisk:(BOOL)toDisk
  147 + completion:(nullable HHWebImageNoParamsBlock)completionBlock;
  148 +
  149 +/**
  150 + * Synchronously store image NSData into disk cache at the given key.
  151 + *
  152 + * @warning This method is synchronous, make sure to call it from the ioQueue
  153 + *
  154 + * @param imageData The image data to store
  155 + * @param key The unique image cache key, usually it's image absolute URL
  156 + */
  157 +- (void)storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key;
  158 +
  159 +#pragma mark - Query and Retrieve Ops
  160 +
  161 +/**
  162 + * Async check if image exists in disk cache already (does not load the image)
  163 + *
  164 + * @param key the key describing the url
  165 + * @param completionBlock the block to be executed when the check is done.
  166 + * @note the completion block will be always executed on the main queue
  167 + */
  168 +- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable HHWebImageCheckCacheCompletionBlock)completionBlock;
  169 +
  170 +/**
  171 + * Sync check if image data exists in disk cache already (does not load the image)
  172 + *
  173 + * @param key the key describing the url
  174 + */
  175 +- (BOOL)diskImageDataExistsWithKey:(nullable NSString *)key;
  176 +
  177 +/**
  178 + * Operation that queries the cache asynchronously and call the completion when done.
  179 + *
  180 + * @param key The unique key used to store the wanted image
  181 + * @param doneBlock The completion block. Will not get called if the operation is cancelled
  182 + *
  183 + * @return a NSOperation instance containing the cache op
  184 + */
  185 +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable HHCacheQueryCompletedBlock)doneBlock;
  186 +
  187 +/**
  188 + * Operation that queries the cache asynchronously and call the completion when done.
  189 + *
  190 + * @param key The unique key used to store the wanted image
  191 + * @param options A mask to specify options to use for this cache query
  192 + * @param doneBlock The completion block. Will not get called if the operation is cancelled
  193 + *
  194 + * @return a NSOperation instance containing the cache op
  195 + */
  196 +- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key options:(HHImageCacheOptions)options done:(nullable HHCacheQueryCompletedBlock)doneBlock;
  197 +
  198 +/**
  199 + * Query the memory cache synchronously.
  200 + *
  201 + * @param key The unique key used to store the image
  202 + */
  203 +- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key;
  204 +
  205 +/**
  206 + * Query the disk cache synchronously.
  207 + *
  208 + * @param key The unique key used to store the image
  209 + */
  210 +- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key;
  211 +
  212 +/**
  213 + * Query the cache (memory and or disk) synchronously after checking the memory cache.
  214 + *
  215 + * @param key The unique key used to store the image
  216 + */
  217 +- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key;
  218 +
  219 +#pragma mark - Remove Ops
  220 +
  221 +/**
  222 + * Remove the image from memory and disk cache asynchronously
  223 + *
  224 + * @param key The unique image cache key
  225 + * @param completion A block that should be executed after the image has been removed (optional)
  226 + */
  227 +- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable HHWebImageNoParamsBlock)completion;
  228 +
  229 +/**
  230 + * Remove the image from memory and optionally disk cache asynchronously
  231 + *
  232 + * @param key The unique image cache key
  233 + * @param fromDisk Also remove cache entry from disk if YES
  234 + * @param completion A block that should be executed after the image has been removed (optional)
  235 + */
  236 +- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable HHWebImageNoParamsBlock)completion;
  237 +
  238 +#pragma mark - Cache clean Ops
  239 +
  240 +/**
  241 + * Clear all memory cached images
  242 + */
  243 +- (void)clearMemory;
  244 +
  245 +/**
  246 + * Async clear all disk cached images. Non-blocking method - returns immediately.
  247 + * @param completion A block that should be executed after cache expiration completes (optional)
  248 + */
  249 +- (void)clearDiskOnCompletion:(nullable HHWebImageNoParamsBlock)completion;
  250 +
  251 +/**
  252 + * Async remove all expired cached image from disk. Non-blocking method - returns immediately.
  253 + * @param completionBlock A block that should be executed after cache expiration completes (optional)
  254 + */
  255 +- (void)deleteOldFilesWithCompletionBlock:(nullable HHWebImageNoParamsBlock)completionBlock;
  256 +
  257 +#pragma mark - Cache Info
  258 +
  259 +/**
  260 + * Get the size used by the disk cache
  261 + */
  262 +- (NSUInteger)getSize;
  263 +
  264 +/**
  265 + * Get the number of images in the disk cache
  266 + */
  267 +- (NSUInteger)getDiskCount;
  268 +
  269 +/**
  270 + * Asynchronously calculate the disk cache's size.
  271 + */
  272 +- (void)calculateSizeWithCompletionBlock:(nullable HHWebImageCalculateSizeBlock)completionBlock;
  273 +
  274 +#pragma mark - Cache Paths
  275 +
  276 +/**
  277 + * Get the cache path for a certain key (needs the cache path root folder)
  278 + *
  279 + * @param key the key (can be obtained from url using cacheKeyForURL)
  280 + * @param path the cache path root folder
  281 + *
  282 + * @return the cache path
  283 + */
  284 +- (nullable NSString *)cachePathForKey:(nullable NSString *)key inPath:(nonnull NSString *)path;
  285 +
  286 +/**
  287 + * Get the default cache path for a certain key
  288 + *
  289 + * @param key the key (can be obtained from url using cacheKeyForURL)
  290 + *
  291 + * @return the default cache path
  292 + */
  293 +- (nullable NSString *)defaultCachePathForKey:(nullable NSString *)key;
  294 +
  295 +@end
  1 +/*
  2 + * This file is part of the HHWebImage package.
  3 + * (c) Olivier Poitrey <rs@dailymotion.com>
  4 + *
  5 + * For the full copyright and license information, please view the LICENSE
  6 + * file that was distributed with this source code.
  7 + */
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import "HHWebImageCompat.h"
  11 +
  12 +@interface HHImageCacheConfig : NSObject
  13 +
  14 +/**
  15 + * Decompressing images that are downloaded and cached can improve performance but can consume lot of memory.
  16 + * Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.
  17 + */
  18 +@property (assign, nonatomic) BOOL shouldDecompressImages;
  19 +
  20 +/**
  21 + * disable iCloud backup [defaults to YES]
  22 + */
  23 +@property (assign, nonatomic) BOOL shouldDisableiCloud;
  24 +
  25 +/**
  26 + * use memory cache [defaults to YES]
  27 + */
  28 +@property (assign, nonatomic) BOOL shouldCacheImagesInMemory;
  29 +
  30 +/**
  31 + * The reading options while reading cache from disk.
  32 + * Defaults to 0. You can set this to `NHHataReadingMappedIfSafe` to improve performance.
  33 + */
  34 +@property (assign, nonatomic) NSDataReadingOptions diskCacheReadingOptions;
  35 +
  36 +/**
  37 + * The writing options while writing cache to disk.
  38 + * Defaults to `NSDataWritingAtomic`. You can set this to `NSDataWritingWithoutOverwriting` to prevent overwriting an existing file.
  39 + */
  40 +@property (assign, nonatomic) NSDataWritingOptions diskCacheWritingOptions;
  41 +
  42 +/**
  43 + * The maximum length of time to keep an image in the cache, in seconds.
  44 + */
  45 +@property (assign, nonatomic) NSInteger maxCacheAge;
  46 +
  47 +/**
  48 + * The maximum size of the cache, in bytes.
  49 + */
  50 +@property (assign, nonatomic) NSUInteger maxCacheSize;
  51 +
  52 +@end
  1 +//
  2 +// HHIndefiniteAnimatedView.h
  3 +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
  4 +//
  5 +// Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +
  10 +@interface HHIndefiniteAnimatedView : UIView
  11 +
  12 +@property (nonatomic, assign) CGFloat strokeThickness;
  13 +@property (nonatomic, assign) CGFloat radius;
  14 +@property (nonatomic, strong) UIColor *strokeColor;
  15 +
  16 +@end
  17 +
  1 +// Generated by Apple Swift version 4.1.2 (swiftlang-902.0.54 clang-902.0.39.2)
  2 +#pragma clang diagnostic push
  3 +#pragma clang diagnostic ignored "-Wgcc-compat"
  4 +
  5 +#if !defined(__has_include)
  6 +# define __has_include(x) 0
  7 +#endif
  8 +#if !defined(__has_attribute)
  9 +# define __has_attribute(x) 0
  10 +#endif
  11 +#if !defined(__has_feature)
  12 +# define __has_feature(x) 0
  13 +#endif
  14 +#if !defined(__has_warning)
  15 +# define __has_warning(x) 0
  16 +#endif
  17 +
  18 +#if __has_include(<swift/objc-prologue.h>)
  19 +# include <swift/objc-prologue.h>
  20 +#endif
  21 +
  22 +#pragma clang diagnostic ignored "-Wauto-import"
  23 +#include <objc/NSObject.h>
  24 +#include <stdint.h>
  25 +#include <stddef.h>
  26 +#include <stdbool.h>
  27 +
  28 +#if !defined(SWIFT_TYPEDEFS)
  29 +# define SWIFT_TYPEDEFS 1
  30 +# if __has_include(<uchar.h>)
  31 +# include <uchar.h>
  32 +# elif !defined(__cplusplus)
  33 +typedef uint_least16_t char16_t;
  34 +typedef uint_least32_t char32_t;
  35 +# endif
  36 +typedef float swift_float2 __attribute__((__ext_vector_type__(2)));
  37 +typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
  38 +typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
  39 +typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
  40 +typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
  41 +typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
  42 +typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
  43 +typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
  44 +typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
  45 +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2)));
  46 +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3)));
  47 +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
  48 +#endif
  49 +
  50 +#if !defined(SWIFT_PASTE)
  51 +# define SWIFT_PASTE_HELPER(x, y) x##y
  52 +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
  53 +#endif
  54 +#if !defined(SWIFT_METATYPE)
  55 +# define SWIFT_METATYPE(X) Class
  56 +#endif
  57 +#if !defined(SWIFT_CLASS_PROPERTY)
  58 +# if __has_feature(objc_class_property)
  59 +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
  60 +# else
  61 +# define SWIFT_CLASS_PROPERTY(...)
  62 +# endif
  63 +#endif
  64 +
  65 +#if __has_attribute(objc_runtime_name)
  66 +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
  67 +#else
  68 +# define SWIFT_RUNTIME_NAME(X)
  69 +#endif
  70 +#if __has_attribute(swift_name)
  71 +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
  72 +#else
  73 +# define SWIFT_COMPILE_NAME(X)
  74 +#endif
  75 +#if __has_attribute(objc_method_family)
  76 +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
  77 +#else
  78 +# define SWIFT_METHOD_FAMILY(X)
  79 +#endif
  80 +#if __has_attribute(noescape)
  81 +# define SWIFT_NOESCAPE __attribute__((noescape))
  82 +#else
  83 +# define SWIFT_NOESCAPE
  84 +#endif
  85 +#if __has_attribute(warn_unused_result)
  86 +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
  87 +#else
  88 +# define SWIFT_WARN_UNUSED_RESULT
  89 +#endif
  90 +#if __has_attribute(noreturn)
  91 +# define SWIFT_NORETURN __attribute__((noreturn))
  92 +#else
  93 +# define SWIFT_NORETURN
  94 +#endif
  95 +#if !defined(SWIFT_CLASS_EXTRA)
  96 +# define SWIFT_CLASS_EXTRA
  97 +#endif
  98 +#if !defined(SWIFT_PROTOCOL_EXTRA)
  99 +# define SWIFT_PROTOCOL_EXTRA
  100 +#endif
  101 +#if !defined(SWIFT_ENUM_EXTRA)
  102 +# define SWIFT_ENUM_EXTRA
  103 +#endif
  104 +#if !defined(SWIFT_CLASS)
  105 +# if __has_attribute(objc_subclassing_restricted)
  106 +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
  107 +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
  108 +# else
  109 +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
  110 +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
  111 +# endif
  112 +#endif
  113 +
  114 +#if !defined(SWIFT_PROTOCOL)
  115 +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
  116 +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
  117 +#endif
  118 +
  119 +#if !defined(SWIFT_EXTENSION)
  120 +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
  121 +#endif
  122 +
  123 +#if !defined(OBJC_DESIGNATED_INITIALIZER)
  124 +# if __has_attribute(objc_designated_initializer)
  125 +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
  126 +# else
  127 +# define OBJC_DESIGNATED_INITIALIZER
  128 +# endif
  129 +#endif
  130 +#if !defined(SWIFT_ENUM_ATTR)
  131 +# if defined(__has_attribute) && __has_attribute(enum_extensibility)
  132 +# define SWIFT_ENUM_ATTR __attribute__((enum_extensibility(open)))
  133 +# else
  134 +# define SWIFT_ENUM_ATTR
  135 +# endif
  136 +#endif
  137 +#if !defined(SWIFT_ENUM)
  138 +# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_ATTR SWIFT_ENUM_EXTRA _name : _type
  139 +# if __has_feature(generalized_swift_name)
  140 +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR SWIFT_ENUM_EXTRA _name : _type
  141 +# else
  142 +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name)
  143 +# endif
  144 +#endif
  145 +#if !defined(SWIFT_UNAVAILABLE)
  146 +# define SWIFT_UNAVAILABLE __attribute__((unavailable))
  147 +#endif
  148 +#if !defined(SWIFT_UNAVAILABLE_MSG)
  149 +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
  150 +#endif
  151 +#if !defined(SWIFT_AVAILABILITY)
  152 +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
  153 +#endif
  154 +#if !defined(SWIFT_DEPRECATED)
  155 +# define SWIFT_DEPRECATED __attribute__((deprecated))
  156 +#endif
  157 +#if !defined(SWIFT_DEPRECATED_MSG)
  158 +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
  159 +#endif
  160 +#if __has_feature(attribute_diagnose_if_objc)
  161 +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning")))
  162 +#else
  163 +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)
  164 +#endif
  165 +#if __has_feature(modules)
  166 +@import Foundation;
  167 +@import CoreLocation;
  168 +@import ObjectiveC;
  169 +@import UIKit;
  170 +@import CoreGraphics;
  171 +@import Photos;
  172 +#endif
  173 +
  174 +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
  175 +#pragma clang diagnostic ignored "-Wduplicate-method-arg"
  176 +#if __has_warning("-Wpragma-clang-attribute")
  177 +# pragma clang diagnostic ignored "-Wpragma-clang-attribute"
  178 +#endif
  179 +#pragma clang diagnostic ignored "-Wunknown-pragmas"
  180 +#pragma clang diagnostic ignored "-Wnullability"
  181 +
  182 +#if __has_attribute(external_source_symbol)
  183 +# pragma push_macro("any")
  184 +# undef any
  185 +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="HHMedicSDK",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol))
  186 +# pragma pop_macro("any")
  187 +#endif
  188 +
  189 +
  190 +
  191 +
  192 +
  193 +
  194 +
  195 +
  196 +
  197 +
  198 +SWIFT_CLASS("_TtC10HHMedicSDK16HHAccountManager")
  199 +@interface HHAccountManager : NSObject
  200 +- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
  201 +@end
  202 +
  203 +
  204 +
  205 +
  206 +
  207 +
  208 +SWIFT_CLASS("_TtC10HHMedicSDK11HHDateUtils")
  209 +@interface HHDateUtils : NSObject
  210 +- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
  211 +@end
  212 +
  213 +
  214 +
  215 +
  216 +
  217 +
  218 +
  219 +
  220 +SWIFT_CLASS("_TtC10HHMedicSDK18HHFileCacheManager")
  221 +@interface HHFileCacheManager : NSObject
  222 +- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
  223 +@end
  224 +
  225 +
  226 +
  227 +
  228 +
  229 +
  230 +
  231 +
  232 +SWIFT_CLASS("_TtC10HHMedicSDK6HHMSDK")
  233 +@interface HHMSDK : NSObject
  234 +- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
  235 +@end
  236 +
  237 +
  238 +
  239 +
  240 +SWIFT_CLASS("_TtC10HHMedicSDK23HHMediaStatusCheckUtils")
  241 +@interface HHMediaStatusCheckUtils : NSObject
  242 +- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
  243 +@end
  244 +
  245 +
  246 +SWIFT_CLASS("_TtC10HHMedicSDK13HHNetObserver")
  247 +@interface HHNetObserver : NSObject
  248 +- (nonnull instancetype)init SWIFT_UNAVAILABLE;
  249 ++ (nonnull instancetype)new SWIFT_DEPRECATED_MSG("-init is unavailable");
  250 +@end
  251 +
  252 +@class NSCoder;
  253 +@class UIWindow;
  254 +@class UICollectionView;
  255 +@class UICollectionViewCell;
  256 +@class UIScrollView;
  257 +
  258 +SWIFT_CLASS("_TtC10HHMedicSDK11HHPagerView")
  259 +@interface HHPagerView : UIView <UICollectionViewDataSource, UICollectionViewDelegate>
  260 +- (nonnull instancetype)initWithFrame:(CGRect)frame SWIFT_UNAVAILABLE;
  261 +- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
  262 +- (void)layoutSubviews;
  263 +- (void)willMoveToWindow:(UIWindow * _Nullable)newWindow;
  264 +- (void)prepareForInterfaceBuilder;
  265 +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView * _Nonnull)collectionView SWIFT_WARN_UNUSED_RESULT;
  266 +- (NSInteger)collectionView:(UICollectionView * _Nonnull)collectionView numberOfItemsInSection:(NSInteger)section SWIFT_WARN_UNUSED_RESULT;
  267 +- (UICollectionViewCell * _Nonnull)collectionView:(UICollectionView * _Nonnull)collectionView cellForItemAtIndexPath:(NSIndexPath * _Nonnull)indexPath SWIFT_WARN_UNUSED_RESULT;
  268 +- (BOOL)collectionView:(UICollectionView * _Nonnull)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath * _Nonnull)indexPath SWIFT_WARN_UNUSED_RESULT;
  269 +- (void)collectionView:(UICollectionView * _Nonnull)collectionView didHighlightItemAtIndexPath:(NSIndexPath * _Nonnull)indexPath;
  270 +- (BOOL)collectionView:(UICollectionView * _Nonnull)collectionView shouldSelectItemAtIndexPath:(NSIndexPath * _Nonnull)indexPath SWIFT_WARN_UNUSED_RESULT;
  271 +- (void)collectionView:(UICollectionView * _Nonnull)collectionView didSelectItemAtIndexPath:(NSIndexPath * _Nonnull)indexPath;
  272 +- (void)collectionView:(UICollectionView * _Nonnull)collectionView willDisplayCell:(UICollectionViewCell * _Nonnull)cell forItemAtIndexPath:(NSIndexPath * _Nonnull)indexPath;
  273 +- (void)collectionView:(UICollectionView * _Nonnull)collectionView didEndDisplayingCell:(UICollectionViewCell * _Nonnull)cell forItemAtIndexPath:(NSIndexPath * _Nonnull)indexPath;
  274 +- (void)scrollViewDidScroll:(UIScrollView * _Nonnull)scrollView;
  275 +- (void)scrollViewWillBeginDragging:(UIScrollView * _Nonnull)scrollView;
  276 +- (void)scrollViewWillEndDragging:(UIScrollView * _Nonnull)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(CGPoint * _Nonnull)targetContentOffset;
  277 +- (void)scrollViewDidEndDecelerating:(UIScrollView * _Nonnull)scrollView;
  278 +- (void)scrollViewDidEndScrollingAnimation:(UIScrollView * _Nonnull)scrollView;
  279 +@end
  280 +
  281 +typedef SWIFT_ENUM(NSInteger, HHPagerViewTransformerType) {
  282 + HHPagerViewTransformerTypeCrossFading = 0,
  283 + HHPagerViewTransformerTypeZoomOut = 1,
  284 + HHPagerViewTransformerTypeDepth = 2,
  285 + HHPagerViewTransformerTypeOverlap = 3,
  286 + HHPagerViewTransformerTypeLinear = 4,
  287 + HHPagerViewTransformerTypeCoverFlow = 5,
  288 + HHPagerViewTransformerTypeFerrisWheel = 6,
  289 + HHPagerViewTransformerTypeInvertedFerrisWheel = 7,
  290 + HHPagerViewTransformerTypeCubic = 8,
  291 +};
  292 +
  293 +@class UIViewController;
  294 +
  295 +SWIFT_CLASS("_TtC10HHMedicSDK23HHPhotoPickerController")
  296 +@interface HHPhotoPickerController : UINavigationController
  297 +- (void)viewDidLoad;
  298 +- (nonnull instancetype)initWithNavigationBarClass:(Class _Nullable)navigationBarClass toolbarClass:(Class _Nullable)toolbarClass OBJC_DESIGNATED_INITIALIZER SWIFT_AVAILABILITY(ios,introduced=5.0);
  299 +- (nonnull instancetype)initWithRootViewController:(UIViewController * _Nonnull)rootViewController OBJC_DESIGNATED_INITIALIZER;
  300 +- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
  301 +- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
  302 +@end
  303 +
  304 +
  305 +/// 全局配置
  306 +SWIFT_CLASS("_TtC10HHMedicSDK12HHSDKOptions")
  307 +@interface HHSDKOptions : NSObject
  308 +- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
  309 +@end
  310 +
  311 +
  312 +
  313 +
  314 +
  315 +
  316 +
  317 +
  318 +
  319 +
  320 +
  321 +
  322 +
  323 +
  324 +
  325 +
  326 +
  327 +
  328 +
  329 +
  330 +
  331 +
  332 +
  333 +
  334 +
  335 +
  336 +
  337 +
  338 +
  339 +
  340 +
  341 +
  342 +
  343 +
  344 +
  345 +
  346 +
  347 +@class UITapGestureRecognizer;
  348 +@class NSTimer;
  349 +
  350 +@interface UIView (SWIFT_EXTENSION(HHMedicSDK))
  351 +- (void)handleToastTapped:(UITapGestureRecognizer * _Nonnull)recognizer;
  352 +- (void)toastTimerDidFinish:(NSTimer * _Nonnull)timer;
  353 +@end
  354 +
  355 +
  356 +
  357 +
  358 +
  359 +
  360 +
  361 +
  362 +
  363 +
  364 +
  365 +#if __has_attribute(external_source_symbol)
  366 +# pragma clang attribute pop
  367 +#endif
  368 +#pragma clang diagnostic pop
  1 +#ifdef __OBJC__
  2 +#import <UIKit/UIKit.h>
  3 +#else
  4 +#ifndef FOUNDATION_EXPORT
  5 +#if defined(__cplusplus)
  6 +#define FOUNDATION_EXPORT extern "C"
  7 +#else
  8 +#define FOUNDATION_EXPORT extern
  9 +#endif
  10 +#endif
  11 +#endif
  12 +
  13 +#import "CocoaLumberjack.h"
  14 +#import "DDAbstractDatabaseLogger.h"
  15 +#import "DDASLLogCapture.h"
  16 +#import "DDASLLogger.h"
  17 +#import "DDAssertMacros.h"
  18 +#import "DDFileLogger.h"
  19 +#import "DDLegacyMacros.h"
  20 +#import "DDLog+LOGV.h"
  21 +#import "DDLog.h"
  22 +#import "DDLogMacros.h"
  23 +#import "DDOSLogger.h"
  24 +#import "DDTTYLogger.h"
  25 +#import "HHIndefiniteAnimatedView.h"
  26 +#import "HHProgressAnimatedView.h"
  27 +#import "HHProgressHUD.h"
  28 +#import "HHRadialGradientLayer.h"
  29 +#import "internal.h"
  30 +#import "ijksdl.h"
  31 +#import "ijksdl_class.h"
  32 +#import "ijksdl_endian.h"
  33 +#import "ijksdl_error.h"
  34 +#import "ijksdl_fourcc.h"
  35 +#import "ijksdl_gles2.h"
  36 +#import "ijksdl_inc_internal.h"
  37 +#import "ijksdl_log.h"
  38 +#import "ijksdl_misc.h"
  39 +#import "ijksdl_mutex.h"
  40 +#import "ijksdl_stdinc.h"
  41 +#import "ijksdl_thread.h"
  42 +#import "ijksdl_timer.h"
  43 +#import "ijksdl_video.h"
  44 +#import "ijksdl_vout.h"
  45 +#import "IJKSDLGLView.h"
  46 +#import "ijksdl_ios.h"
  47 +#import "ijksdl_vout_overlay_videotoolbox.h"
  48 +#import "NTESGLView.h"
  49 +#import "CGGeometry+RSKImageCropper.h"
  50 +#import "RSKImageCropper.h"
  51 +#import "RSKImageCropViewController+Protected.h"
  52 +#import "RSKImageCropViewController.h"
  53 +#import "RSKImageScrollView.h"
  54 +#import "RSKTouchView.h"
  55 +#import "UIApplication+RSKImageCropper.h"
  56 +#import "UIImage+RSKImageCropper.h"
  57 +#import "HHCameraImageModel.h"
  58 +#import "PhotoPicker.h"
  59 +#import "HHCameraUtil.h"
  60 +#import "HHPHAssetManager.h"
  61 +#import "HHAnimatedImageRep.h"
  62 +#import "HHImageCache.h"
  63 +#import "HHImageCacheConfig.h"
  64 +#import "HHWebImageCoder.h"
  65 +#import "HHWebImageCoderHelper.h"
  66 +#import "HHWebImageCodersManager.h"
  67 +#import "HHWebImageCompat.h"
  68 +#import "HHWebImageDownloader.h"
  69 +#import "HHWebImageDownloaderOperation.h"
  70 +#import "HHWebImageFrame.h"
  71 +#import "HHWebImageGIFCoder.h"
  72 +#import "HHWebImageImageIOCoder.h"
  73 +#import "HHWebImageManager.h"
  74 +#import "HHWebImageOperation.h"
  75 +#import "HHWebImagePrefetcher.h"
  76 +#import "HHWebImageTransition.h"
  77 +#import "NSData+hhImageContentType.h"
  78 +#import "NSImage+hhWebCache.h"
  79 +#import "UIButton+hhWebCache.h"
  80 +#import "UIImage+hhForceDecode.h"
  81 +#import "UIImage+hhGIF.h"
  82 +#import "UIImage+hhMultiFormat.h"
  83 +#import "UIImageView+hhHighlightedWebCache.h"
  84 +#import "UIImageView+hhWebCache.h"
  85 +#import "UIView+hhWebCache.h"
  86 +#import "UIView+hhWebCacheOperation.h"
  87 +
  88 +FOUNDATION_EXPORT double HHMedicSDKVersionNumber;
  89 +FOUNDATION_EXPORT const unsigned char HHMedicSDKVersionString[];
  90 +
  1 +//
  2 +// HHPHAssetManager.h
  3 +// CameraLibrary
  4 +//
  5 +// Created by shmily on 16/3/16.
  6 +// Copyright © 2016年 HHPacs. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +#import <Photos/Photos.h>
  11 +
  12 +@interface HHPHAssetManager : NSObject
  13 +
  14 +- (void)tranformImage:(PHAsset *)asset finished:(void (^)(NSData *fullData,NSData *scaledData))finishBlock;
  15 +
  16 +// 返回填充的缩略图
  17 ++ (UIImage *)image:(UIImage *)image fillSize: (CGSize)viewsize;
  18 +
  19 ++ (NSString*)createFilePath:(NSString *)aFileName;
  20 +
  21 +/// 是否有缓存
  22 ++ (BOOL)isWriteCache:(NSString *)aPath setData:(NSData *)aData;
  23 +
  24 ++ (instancetype)shareManager;
  25 +
  26 +@end
  1 +//
  2 +// HHProgressAnimatedView.h
  3 +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
  4 +//
  5 +// Copyright (c) 2017-2018 Tobias Tiemerding. All rights reserved.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +
  10 +@interface HHProgressAnimatedView : UIView
  11 +
  12 +@property (nonatomic, assign) CGFloat radius;
  13 +@property (nonatomic, assign) CGFloat strokeThickness;
  14 +@property (nonatomic, strong) UIColor *strokeColor;
  15 +@property (nonatomic, assign) CGFloat strokeEnd;
  16 +
  17 +@end
  1 +//
  2 +// SVProgressHUD.h
  3 +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
  4 +//
  5 +// Copyright (c) 2011-2018 Sam Vermette and contributors. All rights reserved.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +#import <AvailabilityMacros.h>
  10 +
  11 +extern NSString * _Nonnull const HHProgressHUDDidReceiveTouchEventNotification;
  12 +extern NSString * _Nonnull const HHProgressHUDDidTouchDownInsideNotification;
  13 +extern NSString * _Nonnull const HHProgressHUDWillDisappearNotification;
  14 +extern NSString * _Nonnull const HHProgressHUDDidDisappearNotification;
  15 +extern NSString * _Nonnull const HHProgressHUDWillAppearNotification;
  16 +extern NSString * _Nonnull const HHProgressHUDDidAppearNotification;
  17 +
  18 +extern NSString * _Nonnull const HHProgressHUDStatusUserInfoKey;
  19 +
  20 +typedef NS_ENUM(NSInteger, HHProgressHUDStyle) {
  21 + HHProgressHUDStyleLight, // default style, white HUD with black text, HUD background will be blurred
  22 + HHProgressHUDStyleDark, // black HUD and white text, HUD background will be blurred
  23 + HHProgressHUDStyleCustom // uses the fore- and background color properties
  24 +};
  25 +
  26 +typedef NS_ENUM(NSUInteger, HHProgressHUDMaskType) {
  27 + HHProgressHUDMaskTypeNone = 1, // default mask type, allow user interactions while HUD is displayed
  28 + HHProgressHUDMaskTypeClear, // don't allow user interactions with background objects
  29 + HHProgressHUDMaskTypeBlack, // don't allow user interactions with background objects and dim the UI in the back of the HUD (as seen in iOS 7 and above)
  30 + HHProgressHUDMaskTypeGradient, // don't allow user interactions with background objects and dim the UI with a a-la UIAlertView background gradient (as seen in iOS 6)
  31 + HHProgressHUDMaskTypeCustom // don't allow user interactions with background objects and dim the UI in the back of the HUD with a custom color
  32 +};
  33 +
  34 +typedef NS_ENUM(NSUInteger, HHProgressHUDAnimationType) {
  35 + HHProgressHUDAnimationTypeFlat, // default animation type, custom flat animation (indefinite animated ring)
  36 + HHProgressHUDAnimationTypeNative // iOS native UIActivityIndicatorView
  37 +};
  38 +
  39 +typedef void (^HHProgressHUDShowCompletion)(void);
  40 +typedef void (^HHProgressHUDDismissCompletion)(void);
  41 +
  42 +@interface HHProgressHUD : UIView
  43 +
  44 +#pragma mark - Customization
  45 +
  46 +@property (assign, nonatomic) HHProgressHUDStyle defaultStyle UI_APPEARANCE_SELECTOR; // default is HHProgressHUDStyleLight
  47 +@property (assign, nonatomic) HHProgressHUDMaskType defaultMaskType UI_APPEARANCE_SELECTOR; // default is HHProgressHUDMaskTypeNone
  48 +@property (assign, nonatomic) HHProgressHUDAnimationType defaultAnimationType UI_APPEARANCE_SELECTOR; // default is HHProgressHUDAnimationTypeFlat
  49 +@property (strong, nonatomic, nullable) UIView *containerView; // if nil then use default window level
  50 +@property (assign, nonatomic) CGSize minimumSize UI_APPEARANCE_SELECTOR; // default is CGSizeZero, can be used to avoid resizing for a larger message
  51 +@property (assign, nonatomic) CGFloat ringThickness UI_APPEARANCE_SELECTOR; // default is 2 pt
  52 +@property (assign, nonatomic) CGFloat ringRadius UI_APPEARANCE_SELECTOR; // default is 18 pt
  53 +@property (assign, nonatomic) CGFloat ringNoTextRadius UI_APPEARANCE_SELECTOR; // default is 24 pt
  54 +@property (assign, nonatomic) CGFloat cornerRadius UI_APPEARANCE_SELECTOR; // default is 14 pt
  55 +@property (strong, nonatomic, nonnull) UIFont *font UI_APPEARANCE_SELECTOR; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]
  56 +@property (strong, nonatomic, nonnull) UIColor *backgroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor whiteColor]
  57 +@property (strong, nonatomic, nonnull) UIColor *foregroundColor UI_APPEARANCE_SELECTOR; // default is [UIColor blackColor]
  58 +@property (strong, nonatomic, nonnull) UIColor *backgroundLayerColor UI_APPEARANCE_SELECTOR;// default is [UIColor colorWithWhite:0 alpha:0.4]
  59 +@property (assign, nonatomic) CGSize imageViewSize UI_APPEARANCE_SELECTOR; // default is 28x28 pt
  60 +@property (assign, nonatomic) BOOL shouldTintImages UI_APPEARANCE_SELECTOR; // default is YES
  61 +@property (strong, nonatomic, nonnull) UIImage *infoImage UI_APPEARANCE_SELECTOR; // default is the bundled info image provided by Freepik
  62 +@property (strong, nonatomic, nonnull) UIImage *successImage UI_APPEARANCE_SELECTOR; // default is the bundled success image provided by Freepik
  63 +@property (strong, nonatomic, nonnull) UIImage *errorImage UI_APPEARANCE_SELECTOR; // default is the bundled error image provided by Freepik
  64 +@property (strong, nonatomic, nonnull) UIView *viewForExtension UI_APPEARANCE_SELECTOR; // default is nil, only used if #define HH_APP_EXTENSIONS is set
  65 +@property (assign, nonatomic) NSTimeInterval graceTimeInterval; // default is 0 seconds
  66 +@property (assign, nonatomic) NSTimeInterval minimumDismissTimeInterval; // default is 5.0 seconds
  67 +@property (assign, nonatomic) NSTimeInterval maximumDismissTimeInterval; // default is CGFLOAT_MAX
  68 +
  69 +@property (assign, nonatomic) UIOffset offsetFromCenter UI_APPEARANCE_SELECTOR; // default is 0, 0
  70 +
  71 +@property (assign, nonatomic) NSTimeInterval fadeInAnimationDuration UI_APPEARANCE_SELECTOR; // default is 0.15
  72 +@property (assign, nonatomic) NSTimeInterval fadeOutAnimationDuration UI_APPEARANCE_SELECTOR; // default is 0.15
  73 +
  74 +@property (assign, nonatomic) UIWindowLevel maxSupportedWindowLevel; // default is UIWindowLevelNormal
  75 +
  76 +@property (assign, nonatomic) BOOL hapticsEnabled; // default is NO
  77 +
  78 ++ (void)setDefaultStyle:(HHProgressHUDStyle)style; // default is HHProgressHUDStyleLight
  79 ++ (void)setDefaultMaskType:(HHProgressHUDMaskType)maskType; // default is HHProgressHUDMaskTypeNone
  80 ++ (void)setDefaultAnimationType:(HHProgressHUDAnimationType)type; // default is HHProgressHUDAnimationTypeFlat
  81 ++ (void)setContainerView:(nullable UIView*)containerView; // default is window level
  82 ++ (void)setMinimumSize:(CGSize)minimumSize; // default is CGSizeZero, can be used to avoid resizing for a larger message
  83 ++ (void)setRingThickness:(CGFloat)ringThickness; // default is 2 pt
  84 ++ (void)setRingRadius:(CGFloat)radius; // default is 18 pt
  85 ++ (void)setRingNoTextRadius:(CGFloat)radius; // default is 24 pt
  86 ++ (void)setCornerRadius:(CGFloat)cornerRadius; // default is 14 pt
  87 ++ (void)setBorderColor:(nonnull UIColor*)color; // default is nil
  88 ++ (void)setBorderWidth:(CGFloat)width; // default is 0
  89 ++ (void)setFont:(nonnull UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]
  90 ++ (void)setForegroundColor:(nonnull UIColor*)color; // default is [UIColor blackColor], only used for HHProgressHUDStyleCustom
  91 ++ (void)setBackgroundColor:(nonnull UIColor*)color; // default is [UIColor whiteColor], only used for HHProgressHUDStyleCustom
  92 ++ (void)setBackgroundLayerColor:(nonnull UIColor*)color; // default is [UIColor colorWithWhite:0 alpha:0.5], only used for HHProgressHUDMaskTypeCustom
  93 ++ (void)setImageViewSize:(CGSize)size; // default is 28x28 pt
  94 ++ (void)setShouldTintImages:(BOOL)shouldTintImages; // default is YES
  95 ++ (void)setInfoImage:(nonnull UIImage*)image; // default is the bundled info image provided by Freepik
  96 ++ (void)setSuccessImage:(nonnull UIImage*)image; // default is the bundled success image provided by Freepik
  97 ++ (void)setErrorImage:(nonnull UIImage*)image; // default is the bundled error image provided by Freepik
  98 ++ (void)setViewForExtension:(nonnull UIView*)view; // default is nil, only used if #define HH_APP_EXTENSIONS is set
  99 ++ (void)setGraceTimeInterval:(NSTimeInterval)interval; // default is 0 seconds
  100 ++ (void)setMinimumDismissTimeInterval:(NSTimeInterval)interval; // default is 5.0 seconds
  101 ++ (void)setMaximumDismissTimeInterval:(NSTimeInterval)interval; // default is infinite
  102 ++ (void)setFadeInAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds
  103 ++ (void)setFadeOutAnimationDuration:(NSTimeInterval)duration; // default is 0.15 seconds
  104 ++ (void)setMaxSupportedWindowLevel:(UIWindowLevel)windowLevel; // default is UIWindowLevelNormal
  105 ++ (void)setHapticsEnabled:(BOOL)hapticsEnabled; // default is NO
  106 +
  107 +#pragma mark - Show Methods
  108 +
  109 ++ (void)show;
  110 ++ (void)showWithMaskType:(HHProgressHUDMaskType)maskType __attribute__((deprecated("Use show and setDefaultMaskType: instead.")));
  111 ++ (void)showWithStatus:(nullable NSString*)status;
  112 ++ (void)showWithStatus:(nullable NSString*)status maskType:(HHProgressHUDMaskType)maskType __attribute__((deprecated("Use showWithStatus: and setDefaultMaskType: instead.")));
  113 +
  114 ++ (void)showProgress:(float)progress;
  115 ++ (void)showProgress:(float)progress maskType:(HHProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress: and setDefaultMaskType: instead.")));
  116 ++ (void)showProgress:(float)progress status:(nullable NSString*)status;
  117 ++ (void)showProgress:(float)progress status:(nullable NSString*)status maskType:(HHProgressHUDMaskType)maskType __attribute__((deprecated("Use showProgress:status: and setDefaultMaskType: instead.")));
  118 +
  119 ++ (void)setStatus:(nullable NSString*)status; // change the HUD loading status while it's showing
  120 +
  121 +// stops the activity indicator, shows a glyph + status, and dismisses the HUD a little bit later
  122 ++ (void)showInfoWithStatus:(nullable NSString*)status;
  123 ++ (void)showInfoWithStatus:(nullable NSString*)status maskType:(HHProgressHUDMaskType)maskType __attribute__((deprecated("Use showInfoWithStatus: and setDefaultMaskType: instead.")));
  124 ++ (void)showSuccessWithStatus:(nullable NSString*)status;
  125 ++ (void)showSuccessWithStatus:(nullable NSString*)status maskType:(HHProgressHUDMaskType)maskType __attribute__((deprecated("Use showSuccessWithStatus: and setDefaultMaskType: instead.")));
  126 ++ (void)showErrorWithStatus:(nullable NSString*)status;
  127 ++ (void)showErrorWithStatus:(nullable NSString*)status maskType:(HHProgressHUDMaskType)maskType __attribute__((deprecated("Use showErrorWithStatus: and setDefaultMaskType: instead.")));
  128 +
  129 +// shows a image + status, use white PNGs with the imageViewSize (default is 28x28 pt)
  130 ++ (void)showImage:(nonnull UIImage*)image status:(nullable NSString*)status;
  131 ++ (void)showImage:(nonnull UIImage*)image status:(nullable NSString*)status maskType:(HHProgressHUDMaskType)maskType __attribute__((deprecated("Use showImage:status: and setDefaultMaskType: instead.")));
  132 +
  133 ++ (void)setOffsetFromCenter:(UIOffset)offset;
  134 ++ (void)resetOffsetFromCenter;
  135 +
  136 ++ (void)popActivity; // decrease activity count, if activity count == 0 the HUD is dismissed
  137 ++ (void)dismiss;
  138 ++ (void)dismissWithCompletion:(nullable HHProgressHUDDismissCompletion)completion;
  139 ++ (void)dismissWithDelay:(NSTimeInterval)delay;
  140 ++ (void)dismissWithDelay:(NSTimeInterval)delay completion:(nullable HHProgressHUDDismissCompletion)completion;
  141 +
  142 ++ (BOOL)isVisible;
  143 +
  144 ++ (NSTimeInterval)displayDurationForString:(nullable NSString*)string;
  145 +
  146 +@end
  147 +
  1 +//
  2 +// HHRadialGradientLayer.h
  3 +// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
  4 +//
  5 +// Copyright (c) 2014-2018 Tobias Tiemerding. All rights reserved.
  6 +//
  7 +
  8 +#import <QuartzCore/QuartzCore.h>
  9 +
  10 +@interface HHRadialGradientLayer : CALayer
  11 +
  12 +@property (nonatomic) CGPoint gradientCenter;
  13 +
  14 +@end
  1 +/*
  2 + * This file is part of the HHWebImage package.
  3 + * (c) Olivier Poitrey <rs@dailymotion.com>
  4 + *
  5 + * For the full copyright and license information, please view the LICENSE
  6 + * file that was distributed with this source code.
  7 + */
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import "HHWebImageCompat.h"
  11 +#import "NSData+hhImageContentType.h"
  12 +
  13 +/**
  14 + A Boolean value indicating whether to scale down large images during decompressing. (NSNumber)
  15 + */
  16 +FOUNDATION_EXPORT NSString * _Nonnull const HHWebImageCoderScaleDownLargeImagesKey;
  17 +
  18 +/**
  19 + Return the shared device-dependent RGB color space created with CGColorSpaceCreateDeviceRGB.
  20 +
  21 + @return The device-dependent RGB color space
  22 + */
  23 +CG_EXTERN CGColorSpaceRef _Nonnull HHCGColorSpaceGetDeviceRGB(void);
  24 +
  25 +/**
  26 + Check whether CGImageRef contains alpha channel.
  27 +
  28 + @param imageRef The CGImageRef
  29 + @return Return YES if CGImageRef contains alpha channel, otherwise return NO
  30 + */
  31 +CG_EXTERN BOOL HHCGImageRefContainsAlpha(_Nullable CGImageRef imageRef);
  32 +
  33 +
  34 +/**
  35 + This is the image coder protocol to provide custom image decoding/encoding.
  36 + These methods are all required to implement.
  37 + @note Pay attention that these methods are not called from main queue.
  38 + */
  39 +@protocol HHWebImageCoder <NSObject>
  40 +
  41 +@required
  42 +#pragma mark - Decoding
  43 +/**
  44 + Returns YES if this coder can decode some data. Otherwise, the data should be passed to another coder.
  45 +
  46 + @param data The image data so we can look at it
  47 + @return YES if this coder can decode the data, NO otherwise
  48 + */
  49 +- (BOOL)canDecodeFromData:(nullable NSData *)data;
  50 +
  51 +/**
  52 + Decode the image data to image.
  53 +
  54 + @param data The image data to be decoded
  55 + @return The decoded image from data
  56 + */
  57 +- (nullable UIImage *)decodedImageWithData:(nullable NSData *)data;
  58 +
  59 +/**
  60 + Decompress the image with original image and image data.
  61 +
  62 + @param image The original image to be decompressed
  63 + @param data The pointer to original image data. The pointer itself is nonnull but image data can be null. This data will set to cache if needed. If you do not need to modify data at the sametime, ignore this param.
  64 + @param optionsDict A dictionary containing any decompressing options. Pass {HHWebImageCoderScaleDownLargeImagesKey: @(YES)} to scale down large images
  65 + @return The decompressed image
  66 + */
  67 +- (nullable UIImage *)decompressedImageWithImage:(nullable UIImage *)image
  68 + data:(NSData * _Nullable * _Nonnull)data
  69 + options:(nullable NSDictionary<NSString*, NSObject*>*)optionsDict;
  70 +
  71 +#pragma mark - Encoding
  72 +
  73 +/**
  74 + Returns YES if this coder can encode some image. Otherwise, it should be passed to another coder.
  75 +
  76 + @param format The image format
  77 + @return YES if this coder can encode the image, NO otherwise
  78 + */
  79 +- (BOOL)canEncodeToFormat:(HHImageFormat)format;
  80 +
  81 +/**
  82 + Encode the image to image data.
  83 +
  84 + @param image The image to be encoded
  85 + @param format The image format to encode, you should note `HHImageFormatUndefined` format is also possible
  86 + @return The encoded image data
  87 + */
  88 +- (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(HHImageFormat)format;
  89 +
  90 +@end
  91 +
  92 +
  93 +/**
  94 + This is the image coder protocol to provide custom progressive image decoding.
  95 + These methods are all required to implement.
  96 + @note Pay attention that these methods are not called from main queue.
  97 + */
  98 +@protocol HHWebImageProgressiveCoder <HHWebImageCoder>
  99 +
  100 +@required
  101 +/**
  102 + Returns YES if this coder can incremental decode some data. Otherwise, it should be passed to another coder.
  103 +
  104 + @param data The image data so we can look at it
  105 + @return YES if this coder can decode the data, NO otherwise
  106 + */
  107 +- (BOOL)canIncrementallyDecodeFromData:(nullable NSData *)data;
  108 +
  109 +/**
  110 + Incremental decode the image data to image.
  111 +
  112 + @param data The image data has been downloaded so far
  113 + @param finished Whether the download has finished
  114 + @warning because incremental decoding need to keep the decoded context, we will alloc a new instance with the same class for each download operation to avoid conflicts
  115 + @return The decoded image from data
  116 + */
  117 +- (nullable UIImage *)incrementallyDecodedImageWithData:(nullable NSData *)data finished:(BOOL)finished;
  118 +
  119 +@end
  1 +/*
  2 + * This file is part of the HHWebImage package.
  3 + * (c) Olivier Poitrey <rs@dailymotion.com>
  4 + *
  5 + * For the full copyright and license information, please view the LICENSE
  6 + * file that was distributed with this source code.
  7 + */
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import "HHWebImageCompat.h"
  11 +#import "HHWebImageFrame.h"
  12 +
  13 +@interface HHWebImageCoderHelper : NSObject
  14 +
  15 +/**
  16 + Return an animated image with frames array.
  17 + For UIKit, this will apply the patch and then create animated UIImage. The patch is because that `+[UIImage animatedImageWithImages:duration:]` just use the average of duration for each image. So it will not work if different frame has different duration. Therefore we repeat the specify frame for specify times to let it work.
  18 + For AppKit, NSImage does not support animates other than GIF. This will try to encode the frames to GIF format and then create an animated NSImage for rendering. Attention the animated image may loss some detail if the input frames contain full alpha channel because GIF only supports 1 bit alpha channel. (For 1 pixel, either transparent or not)
  19 +
  20 + @param frames The frames array. If no frames or frames is empty, return nil
  21 + @return A animated image for rendering on UIImageView(UIKit) or NSImageView(AppKit)
  22 + */
  23 ++ (UIImage * _Nullable)animatedImageWithFrames:(NSArray<HHWebImageFrame *> * _Nullable)frames;
  24 +
  25 +/**
  26 + Return frames array from an animated image.
  27 + For UIKit, this will unapply the patch for the description above and then create frames array. This will also work for normal animated UIImage.
  28 + For AppKit, NSImage does not support animates other than GIF. This will try to decode the GIF imageRep and then create frames array.
  29 +
  30 + @param animatedImage A animated image. If it's not animated, return nil
  31 + @return The frames array
  32 + */
  33 ++ (NSArray<HHWebImageFrame *> * _Nullable)framesFromAnimatedImage:(UIImage * _Nullable)animatedImage;
  34 +
  35 +#if HH_UIKIT || HH_WATCH
  36 +/**
  37 + Convert an EXIF image orientation to an iOS one.
  38 +
  39 + @param exifOrientation EXIF orientation
  40 + @return iOS orientation
  41 + */
  42 ++ (UIImageOrientation)imageOrientationFromEXIFOrientation:(NSInteger)exifOrientation;
  43 +/**
  44 + Convert an iOS orientation to an EXIF image orientation.
  45 +
  46 + @param imageOrientation iOS orientation
  47 + @return EXIF orientation
  48 + */
  49 ++ (NSInteger)exifOrientationFromImageOrientation:(UIImageOrientation)imageOrientation;
  50 +#endif
  51 +
  52 +@end
  1 +/*
  2 + * This file is part of the HHWebImage package.
  3 + * (c) Olivier Poitrey <rs@dailymotion.com>
  4 + *
  5 + * For the full copyright and license information, please view the LICENSE
  6 + * file that was distributed with this source code.
  7 + */
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import "HHWebImageCoder.h"
  11 +
  12 +/**
  13 + Global object holding the array of coders, so that we avoid passing them from object to object.
  14 + Uses a priority queue behind scenes, which means the latest added coders have the highest priority.
  15 + This is done so when encoding/decoding something, we go through the list and ask each coder if they can handle the current data.
  16 + That way, users can add their custom coders while preserving our existing prebuilt ones
  17 +
  18 + Note: the `coders` getter will return the coders in their reversed order
  19 + Example:
  20 + - by default we internally set coders = `IOCoder`, `WebPCoder`. (`GIFCoder` is not recommended to add only if you want to get GIF support without `FLAnimatedImage`)
  21 + - calling `coders` will return `@[WebPCoder, IOCoder]`
  22 + - call `[addCoder:[MyCrazyCoder new]]`
  23 + - calling `coders` now returns `@[MyCrazyCoder, WebPCoder, IOCoder]`
  24 +
  25 + Coders
  26 + ------
  27 + A coder must conform to the `HHWebImageCoder` protocol or even to `HHWebImageProgressiveCoder` if it supports progressive decoding
  28 + Conformance is important because that way, they will implement `canDecodeFromData` or `canEncodeToFormat`
  29 + Those methods are called on each coder in the array (using the priority order) until one of them returns YES.
  30 + That means that coder can decode that data / encode to that format
  31 + */
  32 +@interface HHWebImageCodersManager : NSObject<HHWebImageCoder>
  33 +
  34 +/**
  35 + Shared reusable instance
  36 + */
  37 ++ (nonnull instancetype)sharedInstance;
  38 +
  39 +/**
  40 + All coders in coders manager. The coders array is a priority queue, which means the later added coder will have the highest priority
  41 + */
  42 +@property (nonatomic, strong, readwrite, nullable) NSArray<HHWebImageCoder>* coders;
  43 +
  44 +/**
  45 + Add a new coder to the end of coders array. Which has the highest priority.
  46 +
  47 + @param coder coder
  48 + */
  49 +- (void)addCoder:(nonnull id<HHWebImageCoder>)coder;
  50 +
  51 +/**
  52 + Remove a coder in the coders array.
  53 +
  54 + @param coder coder
  55 + */
  56 +- (void)removeCoder:(nonnull id<HHWebImageCoder>)coder;
  57 +
  58 +@end
  1 +/*
  2 + * This file is part of the HHWebImage package.
  3 + * (c) Olivier Poitrey <rs@dailymotion.com>
  4 + * (c) Jamie Pinkham
  5 + *
  6 + * For the full copyright and license information, please view the LICENSE
  7 + * file that was distributed with this source code.
  8 + */
  9 +
  10 +#import <TargetConditionals.h>
  11 +
  12 +#ifdef __OBJC_GC__
  13 + #error HHWebImage does not support Objective-C Garbage Collection
  14 +#endif
  15 +
  16 +// Apple's defines from TargetConditionals.h are a bit weird.
  17 +// Seems like TARGET_OS_MAC is always defined (on all platforms).
  18 +// To determine if we are running on OSX, we can only rely on TARGET_OS_IPHONE=0 and all the other platforms
  19 +#if !TARGET_OS_IPHONE && !TARGET_OS_IOS && !TARGET_OS_TV && !TARGET_OS_WATCH
  20 + #define HH_MAC 1
  21 +#else
  22 + #define HH_MAC 0
  23 +#endif
  24 +
  25 +// iOS and tvOS are very similar, UIKit exists on both platforms
  26 +// Note: watchOS also has UIKit, but it's very limited
  27 +#if TARGET_OS_IOS || TARGET_OS_TV
  28 + #define HH_UIKIT 1
  29 +#else
  30 + #define HH_UIKIT 0
  31 +#endif
  32 +
  33 +#if TARGET_OS_IOS
  34 + #define HH_IOS 1
  35 +#else
  36 + #define HH_IOS 0
  37 +#endif
  38 +
  39 +#if TARGET_OS_TV
  40 + #define HH_TV 1
  41 +#else
  42 + #define HH_TV 0
  43 +#endif
  44 +
  45 +#if TARGET_OS_WATCH
  46 + #define HH_WATCH 1
  47 +#else
  48 + #define HH_WATCH 0
  49 +#endif
  50 +
  51 +
  52 +#if HH_MAC
  53 + #import <AppKit/AppKit.h>
  54 + #ifndef UIImage
  55 + #define UIImage NSImage
  56 + #endif
  57 + #ifndef UIImageView
  58 + #define UIImageView NSImageView
  59 + #endif
  60 + #ifndef UIView
  61 + #define UIView NSView
  62 + #endif
  63 +#else
  64 + #if __IPHONE_OS_VERSION_MIN_REQUIRED != 20000 && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
  65 + #error HHWebImage doesn't support Deployment Target version < 5.0
  66 + #endif
  67 +
  68 + #if HH_UIKIT
  69 + #import <UIKit/UIKit.h>
  70 + #endif
  71 + #if HH_WATCH
  72 + #import <WatchKit/WatchKit.h>
  73 + #endif
  74 +#endif
  75 +
  76 +#ifndef NS_ENUM
  77 +#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
  78 +#endif
  79 +
  80 +#ifndef NS_OPTIONS
  81 +#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type
  82 +#endif
  83 +
  84 +FOUNDATION_EXPORT UIImage *HHScaledImageForKey(NSString *key, UIImage *image);
  85 +
  86 +typedef void(^HHWebImageNoParamsBlock)(void);
  87 +
  88 +FOUNDATION_EXPORT NSString *const HHWebImageErrorDomain;
  89 +
  90 +#ifndef dispatch_queue_async_safe
  91 +#define dispatch_queue_async_safe(queue, block)\
  92 + if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(queue)) == 0) {\
  93 + block();\
  94 + } else {\
  95 + dispatch_async(queue, block);\
  96 + }
  97 +#endif
  98 +
  99 +#ifndef dispatch_main_async_safe
  100 +#define dispatch_main_async_safe(block) dispatch_queue_async_safe(dispatch_get_main_queue(), block)
  101 +#endif