Repository: kongcup/ZMConfuse Branch: master Commit: 5409be7b310a Files: 108 Total size: 825.2 KB Directory structure: gitextract_ihm3ftmh/ ├── .gitignore ├── LICENSE ├── README.md ├── resCustom.txt ├── reskeys.txt ├── shakefun/ │ ├── LICENSE │ ├── README.md │ ├── shakefun/ │ │ ├── AFNetworking/ │ │ │ ├── AFHTTPRequestOperation.h │ │ │ ├── AFHTTPRequestOperation.m │ │ │ ├── AFHTTPRequestOperationManager.h │ │ │ ├── AFHTTPRequestOperationManager.m │ │ │ ├── AFHTTPSessionManager.h │ │ │ ├── AFHTTPSessionManager.m │ │ │ ├── AFNetworkReachabilityManager.h │ │ │ ├── AFNetworkReachabilityManager.m │ │ │ ├── AFNetworking.h │ │ │ ├── AFSecurityPolicy.h │ │ │ ├── AFSecurityPolicy.m │ │ │ ├── AFURLConnectionOperation.h │ │ │ ├── AFURLConnectionOperation.m │ │ │ ├── AFURLRequestSerialization.h │ │ │ ├── AFURLRequestSerialization.m │ │ │ ├── AFURLResponseSerialization.h │ │ │ ├── AFURLResponseSerialization.m │ │ │ ├── AFURLSessionManager.h │ │ │ └── AFURLSessionManager.m │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj/ │ │ │ ├── LaunchScreen.xib │ │ │ └── Main.storyboard │ │ ├── CollectViewController.h │ │ ├── CollectViewController.m │ │ ├── Images.xcassets/ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── MagicalRecord/ │ │ │ ├── Categories/ │ │ │ │ ├── DataImport/ │ │ │ │ │ ├── MagicalImportFunctions.h │ │ │ │ │ ├── MagicalImportFunctions.m │ │ │ │ │ ├── NSAttributeDescription+MagicalDataImport.h │ │ │ │ │ ├── NSAttributeDescription+MagicalDataImport.m │ │ │ │ │ ├── NSEntityDescription+MagicalDataImport.h │ │ │ │ │ ├── NSEntityDescription+MagicalDataImport.m │ │ │ │ │ ├── NSNumber+MagicalDataImport.h │ │ │ │ │ ├── NSNumber+MagicalDataImport.m │ │ │ │ │ ├── NSObject+MagicalDataImport.h │ │ │ │ │ ├── NSObject+MagicalDataImport.m │ │ │ │ │ ├── NSRelationshipDescription+MagicalDataImport.h │ │ │ │ │ ├── NSRelationshipDescription+MagicalDataImport.m │ │ │ │ │ ├── NSString+MagicalDataImport.h │ │ │ │ │ └── NSString+MagicalDataImport.m │ │ │ │ ├── NSManagedObject/ │ │ │ │ │ ├── NSManagedObject+MagicalAggregation.h │ │ │ │ │ ├── NSManagedObject+MagicalAggregation.m │ │ │ │ │ ├── NSManagedObject+MagicalDataImport.h │ │ │ │ │ ├── NSManagedObject+MagicalDataImport.m │ │ │ │ │ ├── NSManagedObject+MagicalFinders.h │ │ │ │ │ ├── NSManagedObject+MagicalFinders.m │ │ │ │ │ ├── NSManagedObject+MagicalRecord.h │ │ │ │ │ ├── NSManagedObject+MagicalRecord.m │ │ │ │ │ ├── NSManagedObject+MagicalRequests.h │ │ │ │ │ └── NSManagedObject+MagicalRequests.m │ │ │ │ ├── NSManagedObjectContext/ │ │ │ │ │ ├── NSManagedObjectContext+MagicalObserving.h │ │ │ │ │ ├── NSManagedObjectContext+MagicalObserving.m │ │ │ │ │ ├── NSManagedObjectContext+MagicalRecord.h │ │ │ │ │ ├── NSManagedObjectContext+MagicalRecord.m │ │ │ │ │ ├── NSManagedObjectContext+MagicalSaves.h │ │ │ │ │ ├── NSManagedObjectContext+MagicalSaves.m │ │ │ │ │ ├── NSManagedObjectContext+MagicalThreading.h │ │ │ │ │ └── NSManagedObjectContext+MagicalThreading.m │ │ │ │ ├── NSManagedObjectModel+MagicalRecord.h │ │ │ │ ├── NSManagedObjectModel+MagicalRecord.m │ │ │ │ ├── NSPersistentStore+MagicalRecord.h │ │ │ │ ├── NSPersistentStore+MagicalRecord.m │ │ │ │ ├── NSPersistentStoreCoordinator+MagicalRecord.h │ │ │ │ └── NSPersistentStoreCoordinator+MagicalRecord.m │ │ │ ├── Core/ │ │ │ │ ├── MagicalRecord+Actions.h │ │ │ │ ├── MagicalRecord+Actions.m │ │ │ │ ├── MagicalRecord+ErrorHandling.h │ │ │ │ ├── MagicalRecord+ErrorHandling.m │ │ │ │ ├── MagicalRecord+Options.h │ │ │ │ ├── MagicalRecord+Options.m │ │ │ │ ├── MagicalRecord+Setup.h │ │ │ │ ├── MagicalRecord+Setup.m │ │ │ │ ├── MagicalRecord+ShorthandSupport.h │ │ │ │ ├── MagicalRecord+ShorthandSupport.m │ │ │ │ ├── MagicalRecord+iCloud.h │ │ │ │ ├── MagicalRecord+iCloud.m │ │ │ │ ├── MagicalRecord.h │ │ │ │ ├── MagicalRecord.m │ │ │ │ └── MagicalRecordShorthand.h │ │ │ └── CoreData+MagicalRecord.h │ │ ├── PrefixHeader.pch │ │ ├── SVProgressHUD/ │ │ │ ├── SVProgressHUD.h │ │ │ └── SVProgressHUD.m │ │ ├── URLEntity.h │ │ ├── URLEntity.m │ │ ├── ViewController.h │ │ ├── ViewController.m │ │ ├── main.m │ │ └── shakefun.xcdatamodeld/ │ │ ├── .xccurrentversion │ │ └── shakefun.xcdatamodel/ │ │ └── contents │ ├── shakefun.xcodeproj/ │ │ ├── project.pbxproj │ │ └── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── shakefunTests/ │ ├── Info.plist │ └── shakefunTests.m ├── zmconfuse.sh ├── zmreplacewords/ │ ├── zmreplacewords/ │ │ └── main.c │ └── zmreplacewords.xcodeproj/ │ ├── project.pbxproj │ └── project.xcworkspace/ │ └── contents.xcworkspacedata └── zmreplacewords.run ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Xcode # build/ *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata *.xccheckout *.moved-aside DerivedData *.hmap *.ipa *.xcuserstate # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control # #Pods/ ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 kongcup Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # ZMConfuse ZMConfuse 是一个命令行脚本。用于对使用Objective-C为开发语言的应用进行代码混淆。混淆的内容包括文件名、类名、协议名、函数名。 混淆实际是对上述内容的关键字提取之后进行md5加密,使得工程的可读性降低,已达到增加应用安全性的目的。 欢迎联系交流 Email:zm53373581@163.com QQGroup:175070221 混淆效果图: ![image](https://github.com/kongcup/ZMConfuse/raw/master/confuse.png) ================================================ FILE: resCustom.txt ================================================ ================================================ FILE: reskeys.txt ================================================ A ABAddressBook ABAddressFormatting ABGroup ABMultiValue ABNewPersonViewController ABNewPersonViewControllerDelegate ABPeoplePickerNavigationController ABPeoplePickerNavigationControllerDelegate ABPerson ABPersonViewController ABPersonViewControllerDelegate ABRecord ABRecordWithAddressBook ABSource ABUnknownPersonViewController ABUnknownPersonViewControllerDelegate ACAccount ACAccountCredential ACAccountStore ACAccountType ACError ADBannerView ADBannerViewDelegate ADBannerView_Deprecated ADClient ADInterstitialAd ADInterstitialAdDelegate ALAsset ALAssetRepresentation ALAssetsFilter ALAssetsGroup ALAssetsLibrary AMSymbol API ASIdentifierManager AUComponent AUGraph AVAnimation AVAsset AVAssetExportSession AVAssetImageGenerator AVAssetReader AVAssetReaderAudioMixOutput AVAssetReaderOutput AVAssetReaderOutputMetadataAdaptor AVAssetReaderSampleReferenceOutput AVAssetReaderTrackOutput AVAssetReaderVideoCompositionOutput AVAssetResourceLoader AVAssetResourceLoaderDelegate AVAssetResourceLoadingContentInformationRequest AVAssetResourceLoadingDataRequest AVAssetResourceLoadingRequest AVAssetResourceRenewalRequest AVAssetTrack AVAssetTrackGroup AVAssetTrackSegment AVAssetWriter AVAssetWriterInput AVAssetWriterInputGroup AVAssetWriterInputMetadataAdaptor AVAssetWriterInputPassDescription AVAssetWriterInputPixelBufferAdaptor AVAsynchronousKeyValueLoading AVAsynchronousVideoCompositionRequest AVAudio3DMixing AVAudioBuffer AVAudioChannelLayout AVAudioEngine AVAudioEnvironmentDistanceAttenuationParameters AVAudioEnvironmentNode AVAudioEnvironmentReverbParameters AVAudioFile AVAudioFormat AVAudioIONode AVAudioInputNode AVAudioMix AVAudioMixInputParameters AVAudioMixerNode AVAudioMixing AVAudioNode AVAudioOutputNode AVAudioPCMBuffer AVAudioPlayer AVAudioPlayerDelegate AVAudioPlayerNode AVAudioProcessingSettings AVAudioRecorder AVAudioRecorderDelegate AVAudioSession AVAudioSessionChannelDescription AVAudioSessionDataSourceDescription AVAudioSessionDelegate AVAudioSessionPortDescription AVAudioSessionRouteDescription AVAudioSettings AVAudioStereoMixing AVAudioTime AVAudioTypes AVAudioUnit AVAudioUnitDelay AVAudioUnitDistortion AVAudioUnitEQ AVAudioUnitEQFilterParameters AVAudioUnitEffect AVAudioUnitGenerator AVAudioUnitMIDIInstrument AVAudioUnitReverb AVAudioUnitSampler AVAudioUnitTimeEffect AVAudioUnitTimePitch AVAudioUnitVarispeed AVBase AVCaptureAudioChannel AVCaptureAudioDataOutput AVCaptureAudioDataOutputSampleBufferDelegate AVCaptureAudioFileOutput AVCaptureAudioPreviewOutput AVCaptureAutoExposureBracketedStillImageSettings AVCaptureBracketedStillImageSettings AVCaptureConnection AVCaptureDevice AVCaptureDeviceFormat AVCaptureDeviceInput AVCaptureDeviceInputSource AVCaptureFileOutput AVCaptureFileOutputDelegate AVCaptureFileOutputRecordingDelegate AVCaptureInput AVCaptureInputPort AVCaptureManualExposureBracketedStillImageSettings AVCaptureMetadataOutput AVCaptureMetadataOutputObjectsDelegate AVCaptureMovieFileOutput AVCaptureOutput AVCaptureScreenInput AVCaptureSession AVCaptureStillImageOutput AVCaptureVideoDataOutput AVCaptureVideoDataOutputSampleBufferDelegate AVCaptureVideoPreviewLayer AVComposition AVCompositionTrack AVCompositionTrackSegment AVError AVFoundation AVFrameRateRange AVKit AVKitDefines AVMIDIPlayer AVMediaFormat AVMediaSelectionGroup AVMediaSelectionOption AVMetadataFaceObject AVMetadataFormat AVMetadataIdentifiers AVMetadataItem AVMetadataItemFilter AVMetadataMachineReadableCodeObject AVMetadataObject AVMutableAudioMix AVMutableAudioMixInputParameters AVMutableComposition AVMutableCompositionTrack AVMutableMetadataItem AVMutableTimedMetadataGroup AVMutableVideoComposition AVMutableVideoCompositionInstruction AVMutableVideoCompositionLayerInstruction AVOutputSettingsAssistant AVPlayer AVPlayerItem AVPlayerItemAccessLog AVPlayerItemAccessLogEvent AVPlayerItemErrorLog AVPlayerItemErrorLogEvent AVPlayerItemLegibleOutput AVPlayerItemLegibleOutputPushDelegate AVPlayerItemMetadataOutput AVPlayerItemMetadataOutputPushDelegate AVPlayerItemOutput AVPlayerItemOutputPullDelegate AVPlayerItemOutputPushDelegate AVPlayerItemTrack AVPlayerItemVideoOutput AVPlayerLayer AVPlayerMediaSelectionCriteria AVPlayerViewController AVPlayerViewController_iAdPreroll AVQueuePlayer AVSampleBufferDisplayLayer AVSpeechSynthesis AVSpeechSynthesisVoice AVSpeechSynthesizer AVSpeechSynthesizerDelegate AVSpeechUtterance AVSynchronizedLayer AVTextStyleRule AVTime AVTimedMetadataGroup AVURLAsset AVUtilities AVVideoCompositing AVVideoComposition AVVideoCompositionCoreAnimationTool AVVideoCompositionInstruction AVVideoCompositionLayerInstruction AVVideoCompositionRenderContext AVVideoCompositionValidationHandling AVVideoSettings Accelerate Accounts AccountsDefines AdSupport AddressBook AddressBookDefines AddressBookUI Alpha AppDelegate AppIcon AssetsLibrary AudioBufferList AudioChannelLayout AudioCodecs AudioComponent AudioConverter AudioFile AudioFileStream AudioFormat AudioOutputUnit AudioQueue AudioServices AudioSession AudioStreamBasicDescription AudioToolbox AudioUnit AudioUnitParameters AudioUnitProperties Base BasicImageTypes CAAction CAAnimation CAAnimationGroup CABTMIDICentralViewController CABTMIDILocalPeripheralViewController CABase CABasicAnimation CADisplayLink CAEAGLLayer CAEmitterBehavior CAEmitterCell CAEmitterLayer CAFFile CAGradientLayer CAInterAppAudioSwitcherView CAInterAppAudioTransportView CAKeyframeAnimation CALayer CAMediaTiming CAMediaTimingFunction CAMetalDrawable CAMetalLayer CAPropertyAnimation CAReplicatorLayer CAScrollLayer CAShapeLayer CATextLayer CATiledLayer CATransaction CATransform3D CATransform3DValue CATransformLayer CATransition CAValueFunction CBATTRequest CBAdvertisementData CBAttribute CBCentral CBCentralManager CBCentralManagerConstants CBCentralManagerDelegate CBCharacteristic CBDefines CBDescriptor CBError CBPeer CBPeripheral CBPeripheralDelegate CBPeripheralManager CBPeripheralManagerConstants CBPeripheralManagerDelegate CBService CBUUID CFArray CFAttributedString CFAvailability CFBag CFBase CFBinaryHeap CFBitVector CFBundle CFByteOrder CFCalendar CFCharacterSet CFData CFDate CFDateFormatter CFDictionary CFError CFFTPStream CFFileDescriptor CFFileSecurity CFHTTPAuthentication CFHTTPMessage CFHTTPStream CFHost CFLocale CFMachPort CFMessagePort CFNetDiagnostics CFNetServices CFNetwork CFNetworkDefs CFNetworkErrors CFNotificationCenter CFNumber CFNumberFormatter CFPlugIn CFPlugInCOM CFPreferences CFPropertyList CFProxySupport CFRunLoop CFSet CFSocket CFSocketStream CFStream CFString CFStringEncodingExt CFStringTokenizer CFTimeZone CFTree CFURL CFURLAccess CFURLEnumerator CFUUID CFUtilities CGAffineTransform CGAffineTransformValue CGBase CGBitmapContext CGColor CGColorRef CGColorSpace CGContext CGDataConsumer CGDataProvider CGError CGFloat CGFont CGFunction CGGeometry CGGradient CGImage CGImageDestination CGImageMetadata CGImageProperties CGImageSource CGImageWithOptions CGLayer CGPDFArray CGPDFContentStream CGPDFContext CGPDFDictionary CGPDFDocument CGPDFObject CGPDFOperatorTable CGPDFPage CGPDFScanner CGPDFStream CGPDFString CGPath CGPattern CGPointValue CGRectValue CGShading CGSizeValue CGVectorValue CIColor CIColorKernel CIContext CIDetector CIFaceFeature CIFeature CIFilter CIFilterConstructor CIImage CIKernel CIQRCodeFeature CIRectangleFeature CIVector CIWarpKernel CKAsset CKContainer CKDatabase CKDatabaseOperation CKDefines CKDiscoverAllContactsOperation CKDiscoverUserInfosOperation CKDiscoveredUserInfo CKError CKFetchNotificationChangesOperation CKFetchRecordChangesOperation CKFetchRecordZonesOperation CKFetchRecordsOperation CKFetchSubscriptionsOperation CKLocationSortDescriptor CKMarkNotificationsReadOperation CKModifyBadgeOperation CKModifyRecordZonesOperation CKModifyRecordsOperation CKModifySubscriptionsOperation CKNotification CKNotificationID CKNotificationInfo CKOperation CKQuery CKQueryCursor CKQueryNotification CKQueryOperation CKRecord CKRecordID CKRecordValue CKRecordZone CKRecordZoneID CKRecordZoneNotification CKReference CKServerChangeToken CKSubscription CLAvailability CLBeacon CLBeaconRegion CLCircularRegion CLError CLErrorDomain CLFloor CLGeocoder CLHeading CLLocation CLLocationManager CLLocationManager+CLVisitExtensions CLLocationManagerDelegate CLPlacemark CLRegion CLVisit CMAccelerometer CMAccelerometerData CMAltimeter CMAltitude CMAltitudeData CMAttachment CMAttitude CMAudioClock CMAudioFormatDescriptionRef CMAvailability CMBase CMBlockBuffer CMBufferQueue CMClockRef CMDeviceMotion CMError CMErrorDomain CMFormatDescription CMFormatDescriptionBridge CMFormatDescriptionRef CMGyro CMGyroData CMLogItem CMMagnetometer CMMagnetometerData CMMemoryPool CMMetadata CMMotionActivity CMMotionActivityManager CMMotionManager CMPedometer CMPedometerData CMSampleBuffer CMSimpleQueue CMStepCounter CMSync CMTextMarkup CMTime CMTimeMappingValue CMTimeRange CMTimeRangeValue CMTimeValue CMTimebaseRef CMVideoFormatDescriptionRef CTCall CTCallCenter CTCarrier CTDefines CTFont CTFontCollection CTFontDescriptor CTFontManager CTFontManagerErrors CTFontTraits CTFrame CTFramesetter CTGlyphInfo CTLine CTParagraphStyle CTRubyAnnotation CTRun CTRunDelegate CTStringAttributes CTSubscriber CTSubscriberInfo CTTelephonyNetworkInfo CTTextTab CTTypesetter CVBase CVBuffer CVHostTime CVImageBuffer CVMetalTexture CVMetalTextureCache CVOpenGLESTexture CVOpenGLESTextureCache CVPixelBuffer CVPixelBufferPool CVPixelFormatDescription CVReturn CaptiveNetwork CipherSuite CloudKit Contents Conversion Convolution CoreAnimation CoreAudio CoreAudioKit CoreAudioTypes CoreAuthentication CoreBluetooth CoreData CoreDataDefines CoreDataErrors CoreFoundation CoreGraphics CoreImage CoreImageDefines CoreLocation CoreMIDI CoreMedia CoreMotion CoreTelephony CoreTelephonyDefines CoreText CoreVideo Current DHCPClientPreferences DNSSearchDomainMatch DNSServerAddressMatch EAAccessory EAAccessoryDelegate EAAccessoryManager EAGL EAGLContext EAGLDrawable EAGLSharegroup EASession EAWiFiUnconfiguredAccessory EAWiFiUnconfiguredAccessoryBrowser EAWiFiUnconfiguredAccessoryBrowserDelegate EKAlarm EKCalendar EKCalendarChooser EKCalendarChooserDelegate EKCalendarItem EKError EKEvent EKEventEditViewController EKEventEditViewDelegate EKEventStore EKEventViewController EKEventViewDelegate EKObject EKParticipant EKRecurrenceDayOfWeek EKRecurrenceEnd EKRecurrenceRule EKReminder EKSource EKStructuredLocation EKTypes ES1 ES2 ES3 EventKit EventKitDefines EventKitUI EventKitUIDefines ExtendedAudioFile ExternalAccessory ExternalAccessoryDefines Foundation FoundationErrors Frameworks GCController GCControllerAxisInput GCControllerButtonInput GCControllerDirectionPad GCControllerElement GCExtendedGamepad GCExtendedGamepadSnapshot GCGamepad GCGamepadSnapshot GCMotion GET GKAchievement GKAchievementChallenge GKAchievementDescription GKAchievementViewController GKAchievementViewControllerDelegate GKChallenge GKChallengeEventHandler GKChallengeEventHandlerDelegate GKChallengeListener GKDefines GKError GKEventListener GKFriendRequestComposeViewController GKFriendRequestComposeViewControllerDelegate GKGameCenterControllerDelegate GKGameCenterViewController GKInvite GKInviteEventListener GKLeaderboard GKLeaderboardSet GKLeaderboardViewController GKLeaderboardViewControllerDelegate GKLocalPlayer GKLocalPlayerListener GKMatch GKMatchDelegate GKMatchRequest GKMatchmaker GKMatchmakerViewController GKMatchmakerViewControllerDelegate GKNotificationBanner GKPeerPickerController GKPeerPickerControllerDelegate GKPlayer GKPublicConstants GKPublicProtocols GKSavedGame GKSavedGameListener GKScore GKScoreChallenge GKSession GKSessionDelegate GKSessionError GKTurnBasedEventHandler GKTurnBasedEventHandlerDelegate GKTurnBasedEventListener GKTurnBasedExchange GKTurnBasedExchangeReply GKTurnBasedMatch GKTurnBasedMatchmakerViewController GKTurnBasedMatchmakerViewControllerDelegate GKTurnBasedParticipant GKVoiceChat GKVoiceChatClient GKVoiceChatService GLEngine GLKBaseEffect GLKEffectProperty GLKEffectPropertyFog GLKEffectPropertyLight GLKEffectPropertyMaterial GLKEffectPropertyTexture GLKEffectPropertyTransform GLKEffects GLKMath GLKMathTypes GLKMathUtils GLKMatrix3 GLKMatrix4 GLKMatrixStack GLKNamedEffect GLKQuaternion GLKReflectionMapEffect GLKSkyboxEffect GLKTextureInfo GLKTextureLoader GLKVector2 GLKVector3 GLKVector4 GLKView GLKViewController GLKViewControllerDelegate GLKViewDelegate GLKit GLKitBase GSS GameController GameKit Geometry HEAD HKAnchoredObjectQuery HKBiologicalSexObject HKBloodTypeObject HKCategorySample HKCategoryType HKCharacteristicType HKCorrelation HKCorrelationQuery HKCorrelationType HKDefines HKHealthStore HKMetadata HKObject HKObjectType HKObserverQuery HKQuantity HKQuantitySample HKQuantityType HKQuery HKSample HKSampleQuery HKSampleType HKSource HKSourceQuery HKStatistics HKStatisticsCollection HKStatisticsCollectionQuery HKStatisticsQuery HKTypeIdentifiers HKUnit HKWorkout HKWorkoutEvent HKWorkoutType HMAccessory HMAccessoryBrowser HMAccessoryBrowserDelegate HMAccessoryDelegate HMAction HMActionSet HMCharacteristic HMCharacteristicDefines HMCharacteristicMetadata HMCharacteristicWriteAction HMDefines HMError HMHome HMHomeDelegate HMHomeManager HMHomeManagerDelegate HMRoom HMService HMServiceGroup HMTimerTrigger HMTrigger HMUser HMZone HTTPAdditionalHeaders HTTPBody HTTPBodyStream HTTPCookieAcceptPolicy HTTPCookieStorage HTTPMaximumConnectionsPerHost HTTPMethod HTTPOnly HTTPShouldHandleCookies HTTPShouldSetCookies HTTPShouldUsePipelining Headers HealthKit Histogram HomeKit IKESecurityAssociationParameters IOBufferDuration IOKit ISO ISOCountryCodes ISOCurrencyCodes ISOLanguageCodes ISOcountryCode ImageIO ImageIOBase Images Info JSBase JSContext JSContextRef JSExport JSGlobalContextRef JSManagedValue JSONObjectWithData JSONObjectWithStream JSObjectRef JSStringRef JSStringRefCF JSValue JSValueRef JSVirtualMachine JavaScript JavaScriptCore LAContext LAError LAPublicDefines LaunchScreen Libraries LinearAlgebra LocalAuthentication M4V MAAudibleMedia MACaptionAppearance MADefinitions MCAdvertiserAssistant MCAdvertiserAssistantDelegate MCBrowserViewController MCBrowserViewControllerDelegate MCError MCNearbyServiceAdvertiser MCNearbyServiceAdvertiserDelegate MCNearbyServiceBrowser MCNearbyServiceBrowserDelegate MCPeerID MCSession MCSessionDelegate MFMailComposeViewController MFMailComposeViewControllerDelegate MFMessageComposeViewController MFMessageComposeViewControllerDelegate MIDIDriver MIDINetworkConnection MIDINetworkHost MIDINetworkSession MIDIServices MIDISetup MIDIThruConnection MIMEType MKAnnotation MKAnnotationView MKCircle MKCircleRenderer MKCircleView MKCoordinateSpanValue MKCoordinateValue MKDirections MKDirectionsRequest MKDirectionsResponse MKDirectionsTypes MKDistanceFormatter MKETAResponse MKFoundation MKGeodesicPolyline MKGeometry MKLocalSearch MKLocalSearchRequest MKLocalSearchResponse MKMapCamera MKMapItem MKMapSnapshot MKMapSnapshotOptions MKMapSnapshotter MKMapView MKMapViewDelegate MKMultiPoint MKOverlay MKOverlayPathRenderer MKOverlayPathView MKOverlayRenderer MKOverlayView MKPinAnnotationView MKPlacemark MKPointAnnotation MKPolygon MKPolygonRenderer MKPolygonView MKPolyline MKPolylineRenderer MKPolylineView MKReverseGeocoder MKReverseGeocoderDelegate MKRoute MKRouteStep MKShape MKTileOverlay MKTileOverlayRenderer MKTypes MKUserLocation MKUserTrackingBarButtonItem MOV MP3 MP4 MPChangePlaybackRateCommand MPChangePlaybackRateCommandEvent MPContentItem MPFeedbackCommand MPFeedbackCommandEvent MPMediaEntity MPMediaItem MPMediaItemCollection MPMediaLibrary MPMediaPickerController MPMediaPickerControllerDelegate MPMediaPlayback MPMediaPlaylist MPMediaQuery MPMediaQuerySection MPMoviePlayerController MPMoviePlayerController_iAdPreroll MPMoviePlayerViewController MPMusicPlayerController MPNowPlayingInfoCenter MPPlayableContentDataSource MPPlayableContentDelegate MPPlayableContentManager MPPlayableContentManagerContext MPRatingCommand MPRatingCommandEvent MPRemoteCommand MPRemoteCommandCenter MPRemoteCommandEvent MPSeekCommandEvent MPSkipIntervalCommand MPSkipIntervalCommandEvent MPVolumeSettings MPVolumeView MTAudioProcessingTap MTAudioProcessingTapRef MTLArgument MTLArrayType MTLBlitCommandEncoder MTLBuffer MTLCommandBuffer MTLCommandEncoder MTLCommandQueue MTLCompileOptions MTLComputeCommandEncoder MTLComputePipeline MTLComputePipelineReflection MTLComputePipelineState MTLDefines MTLDepthStencil MTLDepthStencilDescriptor MTLDepthStencilState MTLDevice MTLDrawable MTLFunction MTLLibrary MTLParallelRenderCommandEncoder MTLPixelFormat MTLRenderCommandEncoder MTLRenderPass MTLRenderPassAttachmentDescriptor MTLRenderPassColorAttachmentDescriptor MTLRenderPassColorAttachmentDescriptorArray MTLRenderPassDepthAttachmentDescriptor MTLRenderPassDescriptor MTLRenderPassStencilAttachmentDescriptor MTLRenderPipeline MTLRenderPipelineColorAttachmentDescriptor MTLRenderPipelineColorAttachmentDescriptorArray MTLRenderPipelineDescriptor MTLRenderPipelineReflection MTLRenderPipelineState MTLResource MTLSampler MTLSamplerDescriptor MTLSamplerState MTLStencilDescriptor MTLStructMember MTLStructType MTLTexture MTLTextureDescriptor MTLTypes MTLVertexAttribute MTLVertexAttributeDescriptor MTLVertexAttributeDescriptorArray MTLVertexBufferLayoutDescriptor MTLVertexBufferLayoutDescriptorArray MTLVertexDescriptor Main MapKit MediaAccessibility MediaPlayer MediaPlayerDefines MediaToolbox MessageUI Metal MobileCoreServices Morphology MultipeerConnectivity MusicDevice MusicPlayer NCWidgetController NCWidgetProviding NEEvaluateConnectionRule NEOnDemandRule NEOnDemandRuleConnect NEOnDemandRuleDisconnect NEOnDemandRuleEvaluateConnection NEOnDemandRuleIgnore NEVPNConnection NEVPNIKEv2SecurityAssociationParameters NEVPNManager NEVPNProtocol NEVPNProtocolIKEv2 NEVPNProtocolIPSec NKAssetDownload NKIssue NKLibrary NKNSURLConnectionAdditions NSArray NSAssertionHandler NSAsynchronousFetchRequest NSAsynchronousFetchResult NSAtomicStore NSAtomicStoreCacheNode NSAttributeDescription NSAttributedString NSAutoreleasePool NSBatchUpdateRequest NSBatchUpdateResult NSBlockOperation NSBundle NSByteCountFormatter NSByteOrder NSCache NSCacheDelegate NSCachedURLResponse NSCalendar NSCharacterSet NSCoder NSCoding NSComparisonPredicate NSCompoundPredicate NSCondition NSConditionLock NSConstantString NSCopying NSCountedSet NSData NSDataDetector NSDate NSDateComponents NSDateComponentsFormatter NSDateFormatter NSDateIntervalFormatter NSDecimal NSDecimalNumber NSDecimalNumberBehaviors NSDecimalNumberHandler NSDictionary NSDirectoryEnumerator NSDiscardableContent NSEnergyFormatter NSEntityDescription NSEntityMapping NSEntityMigrationPolicy NSEnumerator NSError NSEvent NSException NSExpression NSExpressionDescription NSExtensionContext NSExtensionItem NSExtensionRequestHandling NSFastEnumeration NSFetchRequest NSFetchRequestExpression NSFetchedPropertyDescription NSFetchedResultsController NSFetchedResultsControllerDelegate NSFetchedResultsSectionInfo NSFileAccessIntent NSFileCoordinator NSFileCoordinatorReadingWithoutChanges NSFileCoordinatorWritingForDeleting NSFileCoordinatorWritingForMerging NSFileCoordinatorWritingForReplacing NSFileHandle NSFileManager NSFileManagerDelegate NSFilePresenter NSFileProviderExtension NSFileSecurity NSFileVersion NSFileWrapper NSFormatter NSHTTPCookie NSHTTPCookieStorage NSHTTPURLResponse NSHashTable NSIncrementalStore NSIncrementalStoreNode NSIndexPath NSIndexSet NSInputStream NSInvocation NSInvocationOperation NSItemProvider NSJSONSerialization NSKeyValueCoding NSKeyValueObserving NSKeyedArchiver NSKeyedArchiverDelegate NSKeyedUnarchiver NSKeyedUnarchiverDelegate NSLayoutConstraint NSLayoutManager NSLayoutManagerDelegate NSLengthFormatter NSLinguisticTagger NSLocale NSLock NSLocking NSMachPort NSMachPortDelegate NSManagedObject NSManagedObjectContext NSManagedObjectID NSManagedObjectModel NSMapTable NSMappingModel NSMassFormatter NSMergeConflict NSMergePolicy NSMessagePort NSMetadata NSMetadataAttributes NSMetadataItem NSMetadataQuery NSMetadataQueryAttributeValueTuple NSMetadataQueryDelegate NSMetadataQueryResultGroup NSMethodSignature NSMigrationManager NSMutableArray NSMutableAttributedString NSMutableCharacterSet NSMutableCopying NSMutableData NSMutableDictionary NSMutableIndexSet NSMutableOrderedSet NSMutableSet NSMutableString NSMutableURLRequest NSNetService NSNetServiceBrowser NSNetServiceBrowserDelegate NSNetServiceDelegate NSNetServices NSNotification NSNotificationCenter NSNotificationQueue NSNull NSNumber NSNumberFormatter NSObjCRuntime NSObject NSOperation NSOperationQueue NSOrderedSet NSOrthography NSOutputStream NSParagraphStyle NSPathUtilities NSPersistentStore NSPersistentStoreAsynchronousResult NSPersistentStoreCoordinator NSPersistentStoreRequest NSPersistentStoreResult NSPipe NSPointerArray NSPointerFunctions NSPort NSPortDelegate NSPredicate NSProcessInfo NSProgress NSPropertyDescription NSPropertyList NSPropertyListSerialization NSPropertyMapping NSProxy NSPurgeableData NSRange NSRecursiveLock NSRegularExpression NSRelationshipDescription NSRunLoop NSSaveChangesRequest NSScanner NSSecureCoding NSSet NSShadow NSSimpleCString NSSocketPort NSSortDescriptor NSStream NSStreamDelegate NSString NSStringDrawing NSStringEncoding NSText NSTextAttachment NSTextAttachmentContainer NSTextCheckingResult NSTextContainer NSTextLayoutOrientationProvider NSTextStorage NSTextStorageDelegate NSThread NSTimeZone NSTimer NSURL NSURLAuthenticationChallenge NSURLAuthenticationChallengeSender NSURLCache NSURLComponents NSURLConnection NSURLConnectionDataDelegate NSURLConnectionDelegate NSURLConnectionDownloadDelegate NSURLCredential NSURLCredentialStorage NSURLError NSURLProtectionSpace NSURLProtocol NSURLProtocolClient NSURLQueryItem NSURLRequest NSURLResponse NSURLSession NSURLSessionConfiguration NSURLSessionDataDelegate NSURLSessionDataTask NSURLSessionDelegate NSURLSessionDownloadDelegate NSURLSessionDownloadTask NSURLSessionTask NSURLSessionTaskDelegate NSURLSessionUploadTask NSUUID NSUbiquitousKeyValueStore NSUndoManager NSUserActivity NSUserActivityDelegate NSUserDefaults NSValue NSValueTransformer NSXMLParser NSXMLParserDelegate NSZone NS_AVAILABLE NS_DEPRECATED NS_DEPRECATED_IOS NS_DEPRECATED_MAC NS_RETURNS_INNER_POINTER NetworkExtension NewsstandKit NotificationCenter OpenAL OpenGLES PATCH PHAdjustmentData PHAsset PHAssetChangeRequest PHAssetCollectionChangeRequest PHChange PHCollection PHCollectionListChangeRequest PHContentEditingController PHContentEditingInput PHContentEditingOutput PHFetchOptions PHFetchResult PHImageManager PHObject PHPhotoLibrary PKAddPassesViewController PKAddPassesViewControllerDelegate PKDefines PKError PKObject PKPass PKPassLibrary PKPayment PKPaymentAuthorizationViewController PKPaymentAuthorizationViewControllerDelegate PKPaymentButton PKPaymentPass PKPaymentRequest PKPaymentSummaryItem PKPaymentToken PKPushCredentials PKPushPayload PKPushRegistry PKPushRegistryDelegate PKShippingMethod PMSymbol PUT PassKit Photos PhotosTypes PhotosUI PushKit QLBase QLPreviewController QLPreviewControllerDataSource QLPreviewControllerDelegate QLPreviewItem QuartzCore QuickLook RSSI Resources SCDynamicStore SCDynamicStoreCopyDHCPInfo SCDynamicStoreCopySpecific SCDynamicStoreKey SCENEKIT_AVAILABLE SCNAction SCNActionable SCNAnimatable SCNAnimation SCNAnimationEvent SCNBase SCNBoundingVolume SCNBox SCNCamera SCNCapsule SCNCone SCNConstraint SCNCylinder SCNFloor SCNGeometry SCNGeometryElement SCNGeometrySource SCNHitTestResult SCNIKConstraint SCNJavascript SCNLevelOfDetail SCNLight SCNLookAtConstraint SCNMaterial SCNMaterialProperty SCNMatrix4Value SCNMorpher SCNNode SCNNodeRendererDelegate SCNParametricGeometry SCNParticlePropertyController SCNParticleSystem SCNPhysicsBallSocketJoint SCNPhysicsBehavior SCNPhysicsBody SCNPhysicsContact SCNPhysicsContactDelegate SCNPhysicsField SCNPhysicsHingeJoint SCNPhysicsShape SCNPhysicsSliderJoint SCNPhysicsVehicle SCNPhysicsVehicleWheel SCNPhysicsWorld SCNPlane SCNProgram SCNProgramDelegate SCNPyramid SCNRenderer SCNScene SCNSceneExportDelegate SCNSceneRenderer SCNSceneRendererDelegate SCNSceneSource SCNShadable SCNShape SCNSkinner SCNSphere SCNTechnique SCNTechniqueSupport SCNText SCNTorus SCNTransaction SCNTransformConstraint SCNTube SCNVector3Value SCNVector4Value SCNView SCNetwork SCNetworkConfiguration SCNetworkConnection SCNetworkReachability SCPreferences SCPreferencesPath SCPreferencesSetSpecific SCSchemaDefinitions SFNTLayoutTypes SFNTTypes SK3DNode SKAction SKConstraint SKCropNode SKDownload SKEffectNode SKEmitterNode SKError SKFieldNode SKKeyframeSequence SKLabelNode SKLightNode SKMutableTexture SKNode SKPayment SKPaymentQueue SKPaymentTransaction SKPaymentTransactionObserver SKPhysicsBody SKPhysicsContact SKPhysicsJoint SKPhysicsWorld SKProduct SKProductsRequest SKProductsRequestDelegate SKReachConstraints SKReceiptRefreshRequest SKRegion SKRequest SKRequestDelegate SKScene SKShader SKShapeNode SKSpriteNode SKStoreProductViewController SKStoreProductViewControllerDelegate SKTexture SKTextureAtlas SKTransition SKUniform SKVideoNode SKView SLComposeServiceViewController SLComposeSheetConfigurationItem SLComposeViewController SLRequest SLServiceTypes SSIDMatch SSLPinningMode SSReadingList SafariServices SceneKit SceneKitTypes SceneKit_simd SecAccessControl SecBase SecCertificate SecIdentity SecImportExport SecItem SecKey SecPolicy SecRandom SecSharedCredential SecTrust SecureTransport Security SharedUtils Social SocialDefines SpriteKit SpriteKitBase StoreKit StoreKitDefines Support SystemConfiguration TLSMaximumSupportedProtocol TLSMinimumSupportedProtocol TWRequest TWTweetComposeViewController TXTRecordData The Transform Twitter UIAcceleration UIAccelerometer UIAccelerometerDelegate UIAccessibility UIAccessibilityAdditions UIAccessibilityConstants UIAccessibilityCustomAction UIAccessibilityElement UIAccessibilityIdentification UIAccessibilityReadingContent UIAccessibilityZoom UIActionSheet UIActionSheetDelegate UIActivity UIActivityIndicatorView UIActivityItemProvider UIActivityItemSource UIActivityViewController UIAdaptivePresentationControllerDelegate UIAlert UIAlertController UIAlertView UIAlertViewDelegate UIAlertViewDelegate> UIAppearance UIAppearanceContainer UIApplication UIApplicationDelegate UIAttachmentBehavior UIBarButtonItem UIBarCommon UIBarItem UIBarPositioning UIBarPositioningDelegate UIBezierPath UIButton UICollectionView UICollectionViewCell UICollectionViewController UICollectionViewDataSource UICollectionViewDelegate UICollectionViewDelegateFlowLayout UICollectionViewFlowLayout UICollectionViewLayout UICollectionViewTransitionLayout UICollisionBehavior UICollisionBehaviorDelegate UIColor UIContentContainer UIControl UICoordinateSpace UID UIDataDetectors UIDataSourceModelAssociation UIDatePicker UIDelegate UIDevice UIDocument UIDocumentInteractionController UIDocumentInteractionControllerDelegate UIDocumentMenuDelegate UIDocumentMenuViewController UIDocumentPickerDelegate UIDocumentPickerExtensionViewController UIDocumentPickerViewController UIDynamicAnimator UIDynamicAnimatorDelegate UIDynamicBehavior UIDynamicItem UIDynamicItemBehavior UIEdgeInsetsValue UIEvent UIFont UIFontDescriptor UIGeometry UIGestureRecognizer UIGestureRecognizerDelegate UIGestureRecognizerSubclass UIGraphics UIGravityBehavior UIGuidedAccessRestrictions UIImage UIImageAsset UIImagePickerController UIImagePickerControllerDelegate UIImageView UIInputView UIInputViewAudioFeedback UIInputViewController UIInterface UIKeyInput UIKit UIKitDefines UILabel UILayoutSupport UILexicon UILocalNotification UILocalizedIndexedCollation UILongPressGestureRecognizer UIManagedDocument UIMenuController UIMotionEffect UIMutableUserNotificationAction UIMutableUserNotificationCategory UINavigationBar UINavigationBarDelegate UINavigationController UINavigationControllerDelegate UINib UINibDeclarations UINibLoading UIObjectRestoration UIOffsetValue UIPageControl UIPageViewController UIPageViewControllerDataSource UIPageViewControllerDelegate UIPanGestureRecognizer UIPasteboard UIPickerView UIPickerViewAccessibilityDelegate UIPickerViewDataSource UIPickerViewDelegate UIPinchGestureRecognizer UIPopoverBackgroundView UIPopoverBackgroundViewMethods UIPopoverController UIPopoverControllerDelegate UIPopoverPresentationController UIPopoverPresentationControllerDelegate UIPopoverSupport UIPresentationController UIPrintError UIPrintFormatter UIPrintInfo UIPrintInteractionController UIPrintInteractionControllerDelegate UIPrintPageRenderer UIPrintPaper UIPrinter UIPrinterPickerController UIPrinterPickerControllerDelegate UIProgressView UIPushBehavior UIReferenceLibraryViewController UIRefreshControl UIResponder UIRotationGestureRecognizer UIScreen UIScreenEdgePanGestureRecognizer UIScreenMode UIScrollView UIScrollViewAccessibilityDelegate UIScrollViewDelegate UISearchBar UISearchBarDelegate UISearchController UISearchControllerDelegate UISearchDisplayController UISearchDisplayDelegate UISearchResultsUpdating UISegmentedControl UISlider UISnapBehavior UISplitViewController UISplitViewControllerDelegate UIStateRestoration UIStateRestoring UIStepper UIStoryboard UIStoryboardPopoverSegue UIStoryboardSegue UIStringDrawing UISwipeGestureRecognizer UISwitch UITabBar UITabBarController UITabBarControllerDelegate UITabBarDelegate UITabBarItem UITableView UITableViewCell UITableViewController UITableViewDataSource UITableViewDelegate UITableViewHeaderFooterView UITapGestureRecognizer UITextChecker UITextDocumentProxy UITextField UITextFieldDelegate UITextInput UITextInputDelegate UITextInputTokenizer UITextInputTraits UITextSelecting UITextView UITextViewDelegate UIToolbar UIToolbarDelegate UITouch UITraitCollection UITraitEnvironment UIUserNotificationAction UIUserNotificationCategory UIUserNotificationSettings UIVibrancyEffect UIVideoEditorController UIVideoEditorControllerDelegate UIView UIViewController UIViewControllerAnimatedTransitioning UIViewControllerContextTransitioning UIViewControllerInteractiveTransitioning UIViewControllerRestoration UIViewControllerTransitionCoordinator UIViewControllerTransitionCoordinatorContext UIViewControllerTransitioning UIViewControllerTransitioningDelegate UIViewControlleriAdAdditions UIVisualEffectView UIWebView UIWebViewDelegate UIWindow URI URIRepresentation URL URLAssetWithURL URLByAppendingPathComponent URLByAppendingPathExtension URLByDeletingLastPathComponent URLByDeletingPathExtension URLByResolvingAliasFileAtURL URLByResolvingBookmarkData URLByResolvingSymlinksInPath URLByStandardizingPath URLCache URLCredentialStorage URLForAuxiliaryExecutable URLForDirectory URLForItemWithPersistentIdentifier URLForKey URLForPersistentStore URLForPublishingUbiquitousItemAtURL URLForResource URLForTilePath URLForUbiquityContainerIdentifier URLFragmentAllowedCharacterSet URLHandleUsingCache URLHostAllowedCharacterSet URLPasswordAllowedCharacterSet URLPathAllowedCharacterSet URLProtocol URLProtocolDidFinishLoading URLQueryAllowedCharacterSet URLRelativeToURL URLRequest URLResourceDidCancelLoading URLResourceDidFinishLoading URLSession URLSessionDidFinishEventsForBackgroundURLSession URLTemplate URLUserAllowedCharacterSet URLWithString URLs URLsForDirectory URLsForResourcesWithExtension UTCoreTypes UTI UTType UUID UUIDString UUIDWithCFUUID UUIDWithData UUIDWithNSUUID UUIDWithString UserInterfaceState VTBase VTCompressionProperties VTCompressionSession VTDecompressionProperties VTDecompressionSession VTErrors VTFrameSilo VTMultiPassStorage VTSession VTVideoEncoderList Versions VideoToolbox ViewController W WKAccessibilityImageRegion WKBackForwardList WKBackForwardListItem WKDefines WKError WKFoundation WKFrameInfo WKInterfaceButton WKInterfaceController WKInterfaceDate WKInterfaceDevice WKInterfaceGroup WKInterfaceImage WKInterfaceLabel WKInterfaceMap WKInterfaceObject WKInterfaceSeparator WKInterfaceSlider WKInterfaceSwitch WKInterfaceTable WKInterfaceTimer WKNavigation WKNavigationAction WKNavigationDelegate WKNavigationResponse WKPreferences WKProcessPool WKScriptMessage WKScriptMessageHandler WKUIDelegate WKUserContentController WKUserNotificationInterfaceController WKUserScript WKWebView WKWebViewConfiguration WKWindowFeatures WatchKit WebKit WebKitAvailability WebKitLegacy X Y Z a abbreviation abbreviationDictionary abbreviationForDate abortParsing absoluteDate absolutePath absoluteString absoluteURL abstract acceleration accelerometer accelerometerActive accelerometerAvailable accelerometerData accelerometerUpdateInterval acceptCallID acceptConnectionFromPeer acceptConnectionInBackgroundAndNotify acceptConnectionInBackgroundAndNotifyForModes acceptInputForMode acceptInviteWithCompletionHandler access accessGranted accessInstanceVariablesDirectly accessLog accessibilityActivate accessibilityActivationPoint accessibilityContainer accessibilityContentForLineNumber accessibilityCustomActions accessibilityDecrement accessibilityElementAtIndex accessibilityElementCount accessibilityElementDidBecomeFocused accessibilityElementDidLoseFocus accessibilityElementIsFocused accessibilityElements accessibilityElementsHidden accessibilityFrame accessibilityFrameForLineNumber accessibilityHint accessibilityIdentifier accessibilityIncrement accessibilityLabel accessibilityLanguage accessibilityLineNumberForPoint accessibilityNavigationStyle accessibilityPageContent accessibilityPath accessibilityPerformEscape accessibilityPerformMagicTap accessibilityScroll accessibilityScrollStatusForScrollView accessibilityTraits accessibilityValue accessibilityViewIsModal accessories accessory accessoryAction accessoryBrowser accessoryDidDisconnect accessoryDidUpdateName accessoryDidUpdateReachability accessoryDidUpdateServices accessoryType accessoryView accommodatePresentedItemDeletionWithCompletionHandler accommodatePresentedSubitemDeletionAtURL account accountDescription accountStatusWithCompletionHandler accountType accountTypeDescription accountTypeWithAccountTypeIdentifier accountWithIdentifier accounts accountsWithAccountType accuracy achievedDescription achievement achievementDelegate achievementViewControllerDidFinish acquireFunction action actionAtItemEnd actionForKey actionForLayer actionInProgress actionSets actionSheet actionSheetCancel actionSheetStyle actionWithTitle actions actionsForContext actionsForTarget activateConstraints activatePaymentPass activationMode activationState active activeExchanges activeFormat activeInputModes activeInputSource activeProcessorCount activeVideoMaxFrameDuration activeVideoMinFrameDuration activeVideoStabilizationMode activityCategory activityDidFinish activityImage activityIndicatorViewStyle activityTitle activityType activityViewController activityViewControllerPlaceholderItem actualScaleFactor actualTrackingAdjustment actually adType adaptive adaptivePresentationStyle adaptivePresentationStyleForPresentationController adaptivePresentationStyleForTraitCollection addAccessory addAction addActionSet addActionSetWithName addAlarm addAngularVelocity addAnimation addAnnotation addAnnotations addArcWithCenter addAsset addAssetWithRequest addAssets addAssetsGroupAlbumWithName addAttachmentData addAttachmentURL addAttribute addAttributes addBehavior addBoundaryTimeObserverForTimes addBoundaryWithIdentifier addButtonWithTitle addCacheNodes addCachedImage addCachedImageWithData addCharactersInRange addCharactersInString addChild addChildBehavior addChildCollections addChildNode addChildViewController addClientToSegments addClip addCompletedHandler addConnection addConstraint addConstraints addContact addCurveToPoint addDependency addEntriesFromDictionary addExecutionBlock addFilePresenter addFileWithPath addFileWrapper addFilterPredicate addGestureRecognizer addHomeWithName addImage addIndex addIndexes addIndexesInRange addInput addInputGroup addInputWithNoConnections addIssueWithName addItem addItems addJoint addKeyframeValue addKeyframeWithRelativeStartTime addLayoutManager addLineToPoint addLinearVelocity addManagedReference addMenuItemWithImage addMenuItemWithImageNamed addMenuItemWithItemIcon addModifierForProperties addMotionEffect addMultiPartData addMultipartData addMutableTrackWithMediaType addObject addObjects addObjectsFromArray addObserver addObserverForName addOperation addOperationWithBlock addOperations addOptionWithTitle addOutput addOutputWithNoConnections addOverlay addOverlays addParticleSystem addPasses addPassesViewControllerDidFinish addPayment addPeriodicTimeObserverForInterval addPersistentStoreWithType addPlayersToMatch addPointer addPort addPrintFormatter addQuadCurveToPoint addReadingListItemWithURL addRecipientPlayers addRecipientsWithEmailAddresses addRecipientsWithPlayerIDs addRecurrenceRule addRegularFileWithContents addRoom addRoomWithName addSamples addScheduledHandler addScriptMessageHandler addService addServiceGroupWithName addSublayer addSubscriberForFileURL addSubview addSuiteNamed addSymbolicLinkWithDestination addTarget addTargetWithHandler addTextContainer addTextFieldWithConfigurationHandler addTimeInterval addTimer addToRunLoop addTrackAssociationWithTrackOfInput addTransactionObserver addTrigger addURL addUniform addUserInfoEntriesFromDictionary addUserScript addUserWithCompletionHandler addValue addVersionOfItemAtURL addZoneWithName additionalContentForURL additive address addressBook addressCheckingResultWithRange addressComponents addressDictionary addresses adjustTextPositionByCharacterOffset adjustingExposure adjustingFocus adjustingWhiteBalance adjustmentData adjustsFontSizeToFitWidth adjustsImageWhenDisabled adjustsImageWhenHighlighted adjustsLetterSpacingToFitWidth administrativeArea advanceIntervalForDelegateInvocation advanceSimulationTime advanceToNextInputMode advanceToNextItem advertiser advertiserAssistantDidDismissInvitation advertiserAssistantWillPresentInvitation advertisingIdentifier advertisingSection advertisingTrackingEnabled advisoryNotices affectedByGravity affectedByPhysicsFields affectedStores affineTransform aggregationStyle airPlayVideoActive al alarmWithAbsoluteDate alarmWithRelativeOffset alarms albumArtist albumArtistPersistentID albumPersistentID albumTitle albumTrackCount albumTrackNumber albumsQuery alc alertAction alertActionLocalizationKey alertBody alertControllerWithTitle alertLaunchImage alertLocalizationArgs alertLocalizationKey alertTitle alertView alertViewCancel alertViewShouldEnableFirstOtherButton alertViewStyle alias alignment alignmentMode alignmentRectForFrame alignmentRectInsets allAssets allBehaviors allBundles allContactedBodies allControlEvents allCredentials allDay allExportPresets allFrameworks allHTTPHeaderFields allHeaderFields allKeys allKeysForObject allLanguages allMetadata allObjects allPhotos allScripts allTargets allTokens allTouches allValues allVideos alloc allocWithZone allowDeferredLocationUpdatesUntilTraveled allowEvaluation allowableMovement allowedClasses allowedEntityTypes allowedExternalEntityURLs allowedUnits allows allowsActions allowsAddingToAddressBook allowsAirPlay allowsAirPlayVideo allowsBackForwardNavigationGestures allowsCachingHighQualityImages allowsCalendarPreview allowsCameraControl allowsCellularAccess allowsContentModifications allowsEdgeAntialiasing allowsEditing allowsEditingTextAttributes allowsEmptySelection allowsExternalBinaryDataStorage allowsExternalPlayback allowsFloats allowsFractionalUnits allowsGroupOpacity allowsImageEditing allowsInlineMediaPlayback allowsKeyedCoding allowsMagnification allowsMultipleSelection allowsMultipleSelectionDuringEditing allowsNaturalLanguage allowsNonContiguousLayout allowsNonnumericFormatting allowsPickingMultipleItems allowsResizing allowsResting allowsReverseTransformation allowsRotation allowsSelection allowsSelectionDuringEditing allowsTransparency allowsVOIP allowsWeakReference alpha alphaBlendOperation alphaRange alphaSpeed alphaState alphaToCoverageEnabled alphaToOneEnabled alphanumericCharacterSet alternateName alternativeInterpretations alternativeStrings altitude alwaysBounceHorizontal alwaysBounceVertical alwaysCopiesSampleData alwaysDiscardsLateVideoFrames alwaysShowsDecimalSeparator ambient ambientColor amount analog anchorA anchorB anchorDate anchorPoint anchorPointZ andPredicateWithSubpredicates angle angularDamping angularResistance angularVelocity angularVelocityFactor angularVelocityForItem animateAlongsideTransition animateAlongsideTransitionInView animateKeyframesWithDuration animateTransition animateWithDuration animateWithTextures animatedImageNamed animatedImageWithImages animatedResizableImageNamed animatesDrop animation animationControllerForDismissedController animationControllerForPresentedController animationDidStart animationDidStop animationDuration animationEnded animationEventWithKeyTime animationEvents animationForKey animationImages animationKeys animationRepeatCount animationSpeed animationTimingFunction animationTool animationWithKeyPath animations annotation annotationVisibleRect annotations annotationsInMapRect antialiased antialiasingMode anyObject aperture apertureMode appStoreReceiptURL appearance appearanceForTraitCollection appearanceWhenContainedIn appendAttributedString appendBytes appendData appendFormat appendPath appendPixelBuffer appendSampleBuffer appendString appendTimedMetadataGroup applicableRenderingAlgorithms application applicationData applicationDidBecomeActive applicationDidEnterBackground applicationDidFinishLaunching applicationDidReceiveMemoryWarning applicationFinishedRestoringState applicationFrame applicationIconBadgeNumber applicationMusicPlayer applicationProtectedDataDidBecomeAvailable applicationProtectedDataWillBecomeUnavailable applicationSignificantTimeChange applicationState applicationSupportsShakeToEdit applicationUsername applicationWillEnterForeground applicationWillResignActive applicationWillTerminate appliesMediaSelectionCriteriaAutomatically appliesPreferredTrackTransform apply applyAngularImpulse applyBrakingForce applyEngineForce applyFillPropertiesToContext applyForce applyImpulse applyLayoutAttributes applyStrokePropertiesToContext applyTorque applyTransform applyWithExtent apportionsSegmentWidthsByContent approximateLocation archiveRootObject archivedDataWithRootObject archiver archiverDidFinish archiverWillFinish areAnimationsEnabled area areasOfInterest arguments argumentsRetained arithmetic array arrayByAddingObject arrayByAddingObjectsFromArray arrayForKey arrayLength arrayType arrayWithArray arrayWithCapacity arrayWithContentsOfFile arrayWithContentsOfURL arrayWithObject arrayWithObjects arrivalDate arrowBase arrowDirection arrowHeight arrowOffset artist artistPersistentID artistsQuery artwork ascender ascending aspectRatioThumbnail asset assetCollectionSubtype assetCollectionType assetContentChanged assetForURL assetImageGeneratorWithAsset assetReaderAudioMixOutputWithAudioTracks assetReaderOutputMetadataAdaptorWithAssetReaderTrackOutput assetReaderSampleReferenceOutputWithTrack assetReaderTrackOutput assetReaderTrackOutputWithTrack assetReaderVideoCompositionOutputWithVideoTracks assetReaderWithAsset assetTrack assetURL assetWithURL assetWriterInput assetWriterInputGroupWithInputs assetWriterInputMetadataAdaptorWithAssetWriterInput assetWriterInputPixelBufferAdaptorWithAssetWriterInput assetWriterInputWithMediaType assetWriterWithURL assignAccessory assignObject associateSourceInstance associatedMediaSelectionOptionInMediaSelectionGroup associatedServiceType associatedTracksOfType asynchronous atEnd atlasNamed atlasWithDictionary atmosphereUnit atomic attachNode attachedBehaviorType attachedToDevice attachmentBoundsForTextContainer attachmentSizeForGlyphAtIndex attachments attemptRecoveryFromError attemptRotationToDeviceOrientation attendees attenuationEndDistance attenuationFalloffExponent attenuationStartDistance attitude attitudeReferenceFrame attribute attributeForKey attributeIndex attributeMappings attributeType attributeValueClassName attributedContentText attributedPlaceholder attributedStringForNil attributedStringForNotANumber attributedStringForObjectValue attributedStringForZero attributedStringWithAttachment attributedSubstringFromRange attributedText attributedTitle attributedTitleForState attributes attributesAtIndex attributesByName attributesOfFileSystemForPath attributesOfItemAtPath audioChannels audioComponentDescription audioMix audioMixInputParameters audioMixInputParametersWithTrack audioOutputDeviceUniqueID audioPlayerBeginInterruption audioPlayerDecodeErrorDidOccur audioPlayerDidFinishPlaying audioPlayerEndInterruption audioRecorderBeginInterruption audioRecorderDidFinishRecording audioRecorderEncodeErrorDidOccur audioRecorderEndInterruption audioSettings audioTimePitchAlgorithm audioTimeStamp audioTracks audioUnit audiobooksQuery audiovisualMIMETypes audiovisualTypes authenticateHandler authenticateWithCompletionHandler authenticated authenticationMethod authenticationRequired authenticationToken authorizationStatus authorizationStatusForEntityType authorizationStatusForMediaType authorizationStatusForType autoAdjustmentFilters autoAdjustmentFiltersWithOptions autoCompletionViewController autoContentAccessingProxy autoExposureSettingsWithExposureTargetBias autoFocusRangeRestriction autoFocusRangeRestrictionSupported autoFocusSystem autocapitalizationType autocorrectionType autoenablesDefaultLighting automaticTerminationSupportEnabled automaticallyAdjustsMirroring automaticallyAdjustsScrollViewInsets automaticallyAdjustsVideoHDREnabled automaticallyAdjustsVideoMirroring automaticallyAdjustsZRange automaticallyConfiguresApplicationAudioSession automaticallyEnablesLowLightBoostWhenAvailable automaticallyEnablesStillImageStabilizationWhenAvailable automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers automaticallyLoadedAssetKeys automaticallyNotifiesObserversForKey automotive autorepeat autoresizesSubviews autoresizingMask autoreverses autosaveWithCompletionHandler autoupdatingCurrentCalendar autoupdatingCurrentLocale avAsset availability available availableAttitudeReferenceFrames availableCaptureModesForCameraDevice availableChapterLocales availableData availableImageDataCVPixelFormatTypes availableImageDataCodecTypes availableInputs availableLanguages availableLocaleIdentifiers availableMediaCharacteristicsWithMediaSelectionOptions availableMediaTypes availableMediaTypesForSourceType availableMetadataFormats availableMetadataObjectTypes availableModes availableOutputFileTypes availableOutputSettingsPresets availableStringEncodings availableTagSchemesForLanguage availableTrackAssociationTypes availableVideoCVPixelFormatTypes availableVideoCodecTypes averagePowerForChannel averagePowerLevel averageQuantity averageQuantityForSource avoid awakeAfterUsingCoder awakeFromFetch awakeFromInsert awakeFromNib awakeFromSnapshotEvents awakeWithContext axisA axisB axle backBarButtonItem backButtonBackgroundImageForState backButtonBackgroundVerticalPositionAdjustmentForBarMetrics backButtonTitlePositionAdjustmentForBarMetrics backFaceStencil backForwardList backIndicatorImage backIndicatorTransitionMaskImage backItem backList background backgroundColor backgroundEffect backgroundFilters backgroundImage backgroundImageForBarMetrics backgroundImageForBarPosition backgroundImageForState backgroundImageForToolbarPosition backgroundRectForBounds backgroundRefreshStatus backgroundSessionConfiguration backgroundSessionConfigurationWithIdentifier backgroundTimeRemaining backgroundVerticalPositionAdjustmentForBarMetrics backgroundView badge badgeValue bands bandwidth bannerLoaded bannerView bannerViewActionDidFinish bannerViewActionInProgress bannerViewActionShouldBegin bannerViewDidLoadAd bannerViewWillLoadAd barButtonItem barHideOnSwipeGestureRecognizer barHideOnTapGestureRecognizer barPosition barStyle barTintColor base base64EncodedDataWithOptions base64EncodedStringWithOptions base64Encoding baseGeometry baseGeometryBindTransform baseURL baseWritingDirection baseWritingDirectionForPosition baselineAdjustment batchUpdateRequestWithEntityName batteryLevel batteryMonitoringEnabled batteryState beatsPerMinute becomeCurrent becomeCurrentPage becomeCurrentWithPendingUnitCount becomeFirstResponder becomeKeyWindow begin beginActivityWithOptions beginAnimations beginAppearanceTransition beginBackgroundTaskWithExpirationHandler beginBackgroundTaskWithName beginConfiguration beginContentAccess beginCustomizingItems beginEditing beginEntityMapping beginGeneratingDeviceOrientationNotifications beginGeneratingLibraryChangeNotifications beginGeneratingPlaybackNotifications beginIgnoringInteractionEvents beginInterruption beginLoadingChildItemsAtIndexPath beginReceivingRemoteControlEvents beginRefreshing beginRequestWithExtensionContext beginSeekingBackward beginSeekingForward beginTime beginTrackingWithTouch beginUndoGrouping beginUpdates beginningOfDocument behaviorTypes behaviorWithType behaviors bestPaperForPageSize bezierPath bezierPathByReversingPath bezierPathWithArcCenter bezierPathWithCGPath bezierPathWithOvalInRect bezierPathWithRect bezierPathWithRoundedRect biasValues billingAddress bindDrawable biologicalSex biologicalSexWithError birthDirection birthLocation birthRate birthRateVariation birthdayPersonID bitmapRepresentation bits blackColor blackPassEnabled blendMode blendingEnabled blitCommandEncoder blockOperationWithBlock blocked bloodType bloodTypeWithError blue blueColor blueRange blueSpeed body bodyA bodyAlongRayStart bodyAtPoint bodyB bodyInRect bodyWithBodies bodyWithCircleOfRadius bodyWithEdgeChainFromPath bodyWithEdgeFromPoint bodyWithEdgeLoopFromPath bodyWithEdgeLoopFromRect bodyWithPolygonFromPath bodyWithRectangleOfSize bodyWithTexture bodyWithType boldSystemFontOfSize boneIndices boneInverseBindTransforms boneWeights bones bookmarkCommand bookmarkDataWithContentsOfURL bookmarkDataWithOptions bookmarkTime boolForKey boolValue borderColor borderRectForBounds borderStyle borderWidth bottomLayoutGuide bottomLeft bottomRadius bottomRight bounces bouncesZoom boundaryIdentifiers boundaryWithIdentifier boundingMapRect boundingRectForGlyphRange boundingRectWithSize boundingRegion bounds boxWithWidth bridged brightness bringSubviewToFront broadcast brownColor browser browserViewController browserViewControllerDidFinish browserViewControllerWasCancelled bufferAlignment bufferDataSize bufferDataType bufferIndex bufferStructType build builtInPlugInsPath builtInPlugInsURL bundleForClass bundleIdentifier bundlePath bundleURL bundleWithIdentifier bundleWithPath bundleWithURL burstIdentifier burstSelectionTypes buttonA buttonB buttonFontSize buttonNumber buttonTitleAtIndex buttonType buttonWithType buttonX buttonY byValue bypass byteRangeAccessSupported bytesPerComponent bytesPerIndex cString cStringLength cStringUsingEncoding cache cacheName cacheNodeForObjectID cacheNodes cachePolicy cachedImages cachedResponse cachedResponseForRequest cachedSnapshot calculateAccumulatedFrame calculateDirectionsWithCompletionHandler calculateETAWithCompletionHandler calculating calculationMode calendar calendarChooserDidCancel calendarChooserDidFinish calendarChooserSelectionDidChange calendarForEntityType calendarIdentifier calendarItemExternalIdentifier calendarItemIdentifier calendarItemWithIdentifier calendarItemsWithExternalIdentifier calendarWithEventStore calendarWithIdentifier calendars calendarsForEntityType callEventHandler callID callStackReturnAddresses callStackSymbols callState callWithArguments calloutOffset calorieUnit camera cameraCaptureMode cameraDevice cameraFlashMode cameraLookingAtCenterCoordinate cameraOverlayView cameraViewTransform canAddConnection canAddInput canAddInputGroup canAddOutput canAddPasses canAddTrackAssociationWithTrackOfInput canApplyOutputSettings canBeConvertedToEncoding canBePreventedByGestureRecognizer canBecomeFirstResponder canCancelContentTouches canContainAssets canContainCollections canDisplayBannerAds canDrawMapRect canEditVideoAtPath canEvaluatePolicy canFilterByProperty canGoBack canGoForward canHandleAdjustmentData canHandleRequest canInitWithRequest canInitWithTask canInsertItem canMakePayments canMakePaymentsUsingNetworks canOpenURL canPerformAction canPerformEditOperation canPerformMultiplePasses canPerformMultiplePassesOverSourceMediaData canPerformUnwindSegueAction canPerformWithActivityItems canPlayFastForward canPlayFastReverse canPlayReverse canPlaySlowForward canPlaySlowReverse canPreventGestureRecognizer canPreviewItem canPrintData canPrintURL canProvideSampleCursors canRedo canReplaceMapContent canResignFirstResponder canSendAttachments canSendMail canSendSubject canSendText canSendTweet canSetSessionPreset canShowCallout canShowMIMEType canStepBackward canStepForward canUndo cancel cancelAction cancelAllCGImageGeneration cancelAllLocalNotifications cancelAllOperations cancelAllPendingVideoCompositionRequests cancelAllThumbnailImageRequests cancelAuthenticationChallenge cancelBannerViewAction cancelButtonIndex cancelByProducingResumeData cancelConnectPeer cancelConnectToPeer cancelContentEditing cancelContentEditingInputRequest cancelDownloads cancelEditing cancelExport cancelFetchRequest cancelGeocode cancelImageRequest cancelInteractiveTransition cancelInviteToPlayer cancelLoading cancelLocalNotification cancelMigrationWithError cancelPendingInviteToPlayer cancelPendingPrerolls cancelPendingSeeks cancelPerformSelector cancelPerformSelectorsWithTarget cancelPeripheralConnection cancelPreroll cancelPreviousPerformRequestsWithTarget cancelReading cancelRequestWithError cancelTrackingWithEvent cancelVideoZoomRamp cancelWithLocalizableMessageKey cancelWriting cancellable cancellationHandler cancelled cancelsTouchesInView canonicalLanguageIdentifierFromString canonicalLocaleIdentifierFromString canonicalRequestForRequest capHeight capInsets capRadius capSegmentCount capabilities capitalizedLetterCharacterSet capitalizedString capitalizedStringWithLocale capsuleWithCapRadius captureDevicePointOfInterestForPoint captureOutput captureOutputShouldProvideSampleAccurateRecordingStart captureStillImageAsynchronouslyFromConnection captureStillImageBracketAsynchronouslyFromConnection capturesCursor capturesMouseClicks capturingStillImage caretRectForPosition carrierName carrierToken caseInsensitiveCompare caseSensitive castsShadow categories category categoryBitMask categoryOptions categorySampleWithType categoryType categoryTypeForIdentifier cblas cellForItemAtIndexPath cellForRowAtIndexPath center centerCoordinate centerOffset centerRect centimeterOfWaterUnit central centralManager centralManagerDidUpdateState certificateType certificates cflag chainRootNode challengeComposeControllerWithMessage challengeComposeControllerWithPlayers challengeEventHandler chamferMode chamferProfile chamferRadius chamferSegmentCount changeCount changeCountTokenForSaveOperation changeCurrentDirectoryPath changeDetailsForFetchResult changeDetailsForObject changeDetailsFromFetchResult changeFileAttributes changeInLength changePlaybackRateCommand changeRequestForAsset changeRequestForAssetCollection changeRequestForCollectionList changedIndexes changedKeys changedObjects changedValues changedValuesForCurrentEvent channelAssignments channelCount channelLabel channelName channelNumber channels chapterMetadataGroupsBestMatchingPreferredLanguages chapterMetadataGroupsWithTitleLocale char charValue characterAtIndex characterDirectionForLanguage characterIndexForGlyphAtIndex characterIndexForPoint characterIsMember characterOffsetOfPosition characterRangeAtPoint characterRangeByExtendingPosition characterRangeForGlyphRange characterSetWithBitmapRepresentation characterSetWithCharactersInString characterSetWithContentsOfFile characterSetWithRange characteristic characteristicType characteristicTypeForIdentifier characteristics charactersRemaining charactersToBeSkipped charge chassisBody checkPromisedItemIsReachableAndReturnError checkResourceIsReachableAndReturnError checkingTypes childBehaviors childItemsDisplayPlaybackProgressAtIndexPath childNodeWithName childNodes childNodesPassingTest childSecurityAssociationParameters childViewControllerForStatusBarHidden childViewControllerForStatusBarStyle childViewControllers children chooseBestHostPlayerWithCompletionHandler chooseBestHostingPlayerWithCompletionHandler chromaticityValuesForDeviceWhiteBalanceGains circle circleWithCenterCoordinate circleWithMapRect clapack class classFallbacksForKeyedArchiver classForClassName classForCoder classForKeyedArchiver classForKeyedUnarchiver classNameForClass classNamed clearAllForces clearAllMenuItems clearButtonMode clearButtonRectForBounds clearCaches clearColor clearDepth clearKeepAliveTimeout clearStencil clearTextInputContextIdentifier clearsContextBeforeDrawing clearsOnBeginEditing clearsOnInsertion clearsSelectionOnViewWillAppear client clientChangeTokenData clipsToBounds clone close closeFile closePath closeWithCompletionHandler closedCaptionDisplayEnabled closestPositionToPoint cloudItem code collapseSecondaryViewController collapsed collapsesLargestUnit collection collectionListSubtype collectionListType collectionSections collectionView collectionViewContentSize collectionViewLayout collectionWithItems collections colliderNodes collisionBehavior collisionBitMask collisionDelegate collisionImpulse collisionMode color colorAttachments colorBlendFactor colorMaterialEnabled colorSpace colorWithAlphaComponent colorWithCGColor colorWithCIColor colorWithHue colorWithPatternImage colorWithRed colorWithString colorWithWhite colorizeWithColor colorizeWithColorBlendFactor colors columnNumber columnTerminatorsForLocale command commandBuffer commandBufferWithUnretainedReferences commandQueue comment commentURL comments commit commitAnimations commitConfiguration committedValuesForKeys commonFormat commonISOCurrencyCodes commonKey commonMetadata commonPrefixWithString compact comparator compare compareDate compareObject comparePosition compareStartDateWithEvent comparisonPredicateModifier comparisonType compatibleTrackForCompositionTrack compatibleWithSavedPhotosAlbum compilation compilationsQuery completePathIntoString completeRequestReturningItems completeStateRestoration completeTransition completed completedExchanges completedUnitCount completionBlock completionCurve completionDate completionHandler completionSpeed completionVelocity completionWithItemsHandler completionsForPartialWordRange component components componentsFromLocaleIdentifier componentsInTimeZone componentsJoinedByString componentsPerVector componentsSeparatedByCharactersInSet componentsSeparatedByString componentsToDisplayForPath componentsWithString componentsWithURL composable composeViewControllerForServiceType composeViewDelegate composer composerPersistentID composersQuery compositingFilter composition compositionTime compositionTrackSegmentWithTimeRange compositionTrackSegmentWithURL compoundIndexes compoundPredicateType computeCommandEncoder concurrencyType concurrent condition coneWithTopRadius confidence config configuration configurationItems configurationName configurations configureAccessory configureAsServer configurePersistentStoreCoordinatorForURL conflict connect connectPeer connectPeripheral connectToPeer connected connectedAccessories connectedPeers connection connectionDidFinishDownloading connectionDidFinishLoading connectionDidResumeDownloading connectionID connectionPolicy connectionPosition connectionProxyDictionary connectionRules connectionShouldUseCredentialStorage connectionTypesMask connectionWithHost connectionWithInputPort connectionWithInputPorts connectionWithMediaType connectionWithRequest connections const constant constantAttenuation constantAttenuationlinearAttenuationquadraticAttenuation constantColor constantValue constraintWithItem constraints constraintsAffectingLayoutForAxis constraintsWithVisualFormat constructWithArguments contactDelegate contactNormal contactPoint contactPrinter contactTestBetweenBody contactTestBitMask contactTestWithBody contacts container containerFrame containerIdentifier containerURLForSecurityApplicationGroupIdentifier containerView containerViewDidLayoutSubviews containerViewWillLayoutSubviews containerWithIdentifier containsCoordinate containsEnd containsIndex containsIndexes containsIndexesInRange containsMipmaps containsObject containsPass containsPasteboardTypes containsPoint containsStart containsString containsTraitsInCollection containsTweening containsValueForKey contentCompressionResistancePriorityForAxis contentEdgeInsets contentEditingOutput contentFrame contentHorizontalAlignment contentHuggingPriorityForAxis contentIdentifier contentInformationRequest contentInset contentInsets contentItemAtIndexPath contentLimitsEnabled contentMode contentOffset contentOffsetAdjustment contentOffsetForSegmentAtIndex contentOverlayView contentPositionAdjustmentForSegmentType contentRectForBounds contentScaleFactor contentSize contentSizeAdjustment contentSizeForViewInPopover contentStretch contentText contentType contentURL contentVersion contentVerticalAlignment contentView contentViewController contentViewInsets contentWidth contents contentsAreFlipped contentsAtPath contentsCenter contentsEqualAtPath contentsForType contentsGravity contentsOfDirectoryAtPath contentsOfDirectoryAtURL contentsRect contentsScale contentsTransform context contextExpression contextForSegueWithIdentifier contextShouldIgnoreUnmodeledPropertyChanges contextWithCGContext contextWithCGLContext contextWithEAGLContext contextWithJSGlobalContextRef contextWithOptions contextsForSegueWithIdentifier continueSpeaking continueTrackingWithTouch continueWithoutCredentialForAuthenticationChallenge continuityValues continuous controlCharacterSet controlStyle controller controllerDidChangeContent controllerPausedHandler controllerWillChangeContent controllerWithAnimation controllers convertCoordinate convertPoint convertPointFromView convertPointToView convertPosition convertRect convertRegion convertTime convertTransform convexSweepTestWithShape cookieAcceptPolicy cookieWithProperties cookies cookiesForURL cookiesWithResponseHeaderFields coordinate coordinateAccessWithIntents coordinateReadingItemAtURL coordinateSpace coordinateWritingItemAtURL copy copyCGImageAtTime copyFormatDescription copyFromBuffer copyFromTexture copyItemAtPath copyItemAtURL copyNextSampleBuffer copyPath copyPixelBufferForItemTime copyWithZone cornerRadius cornerSegmentCount corners correctionCheckingResultWithRange correlationType correlationTypeForIdentifier correlationWithType count countByEnumeratingWithState countDownDuration countForFetchRequest countForObject countLimit countOfAssetsWithMediaType countOfBytesExpectedToReceive countOfBytesExpectedToSend countOfBytesReceived countOfBytesSent countOfIndexesInRange countOnlyRequest countStyle countUnit country countryCode course cpuCacheMode createCGImage createCGLayerWithSize createDestinationInstancesForSourceInstance createDirectoryAtPath createDirectoryAtURL createFileAtPath createPath createRelationshipsForDestinationInstance createSymbolicLinkAtPath createSymbolicLinkAtURL creationDate creationRequestForAssetCollectionWithTitle creationRequestForAssetFromImage creationRequestForAssetFromImageAtFileURL creationRequestForAssetFromVideoAtFileURL creationRequestForCollectionListWithTitle creatorUserRecordID credential credentialForTrust credentialWithIdentity credentialWithUser credentialsForProtectionSpace cropRect crossFadeWithDuration cubeMapWithContentsOfFile cubeMapWithContentsOfFiles cubeMapWithContentsOfURL cullMode cumulative currencyCode currencyDecimalSeparator currencyGroupingSeparator currencySymbol currentArguments currentAttributedTitle currentBackgroundImage currentCalendar currentCallee currentCalls currentCollation currentContentSizeIdentifier currentContext currentDate currentDevice currentDirectoryPath currentDiskUsage currentEntityMapping currentHandler currentHardwareInputNumberOfChannels currentHardwareOutputNumberOfChannels currentHardwareSampleRate currentImage currentInputMode currentItem currentLanguageCode currentLayout currentLocale currentMaximumTrackImage currentMemoryUsage currentMinimumTrackImage currentMode currentPage currentPageIndicatorTintColor currentParticipant currentPassDescription currentPlaybackRate currentPlaybackTime currentPoint currentPosition currentPreviewItem currentPreviewItemIndex currentProgress currentQueue currentRadioAccessTechnology currentRequest currentRoute currentRunLoop currentThis currentThread currentThumbImage currentTime currentTimeLabelFont currentTitle currentTitleColor currentTitleShadowColor currentUserNotificationSettings currentVersionOfItemAtURL currentVideoFrameRate currentlyReadingIssue cursor customActionWithDuration customFieldWithEvaluationBlock customSelector customVideoCompositor customVideoCompositorClass customView customizableViewControllers cut cyanColor cycling cylinderWithRadius damping dampingFactor darkGrayColor darkTextColor dashCheckingResultWithRange data dataDetectorTypes dataDetectorWithTypes dataForKey dataForPasteboardType dataFromPropertyList dataFromRange dataFromTXTRecordDictionary dataOffset dataRequest dataSource dataSourceID dataSourceName dataSources dataStride dataTaskWithHTTPGetRequest dataTaskWithRequest dataTaskWithURL dataType dataUsingEncoding dataValue dataWithBytes dataWithBytesNoCopy dataWithCapacity dataWithContentsOfFile dataWithContentsOfMappedFile dataWithContentsOfURL dataWithData dataWithJSONObject dataWithLength dataWithPropertyList database date dateByAddingComponents dateByAddingTimeInterval dateByAddingUnit dateBySettingHour dateBySettingUnit dateCheckingResultWithRange dateFormat dateFormatFromTemplate dateFormatTemplate dateFromComponents dateFromString dateOfBirthWithError datePickerMode dateStyle dateTemplate dateValue dateWithEra dateWithTimeInterval dateWithTimeIntervalSince1970 dateWithTimeIntervalSinceNow dateWithTimeIntervalSinceReferenceDate day dayOfTheWeek dayOfWeek dayUnit daylightSavingTime daylightSavingTimeOffset daylightSavingTimeOffsetForDate daysOfTheMonth daysOfTheWeek daysOfTheYear deactivateConstraints deadPeerDetectionRate dealloc debugDescription debugLabel decelerating decelerationRate decimalDigitCharacterSet decimalNumberByAdding decimalNumberByDividingBy decimalNumberByMultiplyingBy decimalNumberByMultiplyingByPowerOf10 decimalNumberByRaisingToPower decimalNumberByRoundingAccordingToBehavior decimalNumberBySubtracting decimalNumberHandlerWithRoundingMode decimalNumberWithDecimal decimalNumberWithMantissa decimalNumberWithString decimalSeparator decimalValue decline declineInviteWithCompletionHandler decodeArrayOfObjCType decodeBoolForKey decodeBytesWithReturnedLength decodeCGAffineTransformForKey decodeCGPointForKey decodeCGRectForKey decodeCGSizeForKey decodeCGVectorForKey decodeCMTimeForKey decodeCMTimeMappingForKey decodeCMTimeRangeForKey decodeDataObject decodeDoubleForKey decodeFloatForKey decodeInt32ForKey decodeInt64ForKey decodeIntForKey decodeIntegerForKey decodeNXObject decodeObject decodeObjectForKey decodeObjectOfClass decodeObjectOfClasses decodePropertyList decodePropertyListForKey decodeRestorableStateWithCoder decodeUIEdgeInsetsForKey decodeUIOffsetForKey decodeValueOfObjCType decodeValuesOfObjCTypes decomposableCharacterSet decomposedStringWithCanonicalMapping decomposedStringWithCompatibilityMapping decreaseSize decrementImageForState default defaultActionForKey defaultBehavior defaultCStringEncoding defaultCalendarForNewEvents defaultCalendarForNewReminders defaultCenter defaultContainer defaultCredentialForProtectionSpace defaultDate defaultDecimalNumberHandler defaultDeviceWithMediaType defaultFormatterBehavior defaultInput defaultInvitationMessage defaultManager defaultMediaLibrary defaultNumberOfPlayers defaultOption defaultParagraphStyle defaultQueue defaultReadingList defaultRecordZone defaultRepresentation defaultSession defaultSessionConfiguration defaultSource defaultStore defaultTabInterval defaultTextAttributes defaultTimeZone defaultValue defaultValueForKey defaultVoiceChatService defaultWritingDirectionForLanguage defaults deferredLocationUpdatesAvailable defersCurrentPageDisplay defineProperty definesPresentationContext definition degreeCelsiusUnit degreeFahrenheitUnit delayTime delaysContentTouches delaysTouchesBegan delaysTouchesEnded delegate delegateQueue delete deleteAssetCollections deleteAssets deleteBackward deleteCacheWithName deleteCharactersInRange deleteCollectionLists deleteCookie deleteDrawable deleteItemsAtIndexPaths deleteObject deleteProperty deleteRecordWithID deleteRecordZoneWithID deleteRecording deleteRowsAtIndexPaths deleteRule deleteSavedGamesWithName deleteSections deleteSubscriptionWithID deleted deletedObjects deliveryMode density denyCallID denyConnectionFromPeer departureDate dependencies depth depthAttachment depthAttachmentPixelFormat depthCompareFunction depthFailureOperation depthPlane depthStencilPassOperation depthWriteEnabled dequeueNotificationsMatching dequeueReusableAnnotationViewWithIdentifier dequeueReusableCellWithIdentifier dequeueReusableCellWithReuseIdentifier dequeueReusableHeaderFooterViewWithIdentifier dequeueReusableSupplementaryViewOfKind descender description descriptionFunction descriptionInStringsFileFormat descriptionWithLocale descriptors deselectAnnotation deselectItemAtIndexPath deselectRowAtIndexPath desiredAccuracy desiredKeys desiredPushTypes destination destinationAlphaBlendFactor destinationContext destinationEndpoint destinationEntity destinationEntityForEntityMapping destinationEntityName destinationEntityVersionHash destinationInstancesForEntityMappingNamed destinationModel destinationOfSymbolicLinkAtPath destinationRGBBlendFactor destinationViewController destructive destructiveButtonIndex detachNewThreadSelector detachNode detail detailTextForGuidedAccessRestrictionWithIdentifier detailTextLabel detectConflictsForObject detectorOfType detectsPhoneNumbers determineAppInstallationAttributionWithCompletionHandler determineCompatibilityOfExportPreset determineCompatibleFileTypesWithCompletionHandler developmentLocalization device deviceAccountIdentifier deviceAccountNumberSuffix deviceCurrentTime deviceInputWithDevice deviceMotion deviceMotionActive deviceMotionAvailable deviceMotionUpdateInterval deviceName deviceWhiteBalanceGains deviceWhiteBalanceGainsForChromaticityValues deviceWhiteBalanceGainsForTemperatureAndTintValues deviceWithUniqueID devices devicesWithMediaType dictationRecognitionFailed dictationRecordingDidEnd dictionary dictionaryForKey dictionaryFromTXTRecordData dictionaryHasDefinitionForTerm dictionaryPayload dictionaryRepresentation dictionaryWithCapacity dictionaryWithContentsOfFile dictionaryWithContentsOfURL dictionaryWithDictionary dictionaryWithObject dictionaryWithObjects dictionaryWithObjectsAndKeys dictionaryWithSharedKeySet dictionaryWithValuesForKeys didAccessValueForKey didAddSubview didAddToPersistentStoreCoordinator didAnimateFirstHalfOfRotationToInterfaceOrientation didApplyConstraints didApplyConstraintsForScene didBeginContact didChange didChangeSize didChangeValueForKey didDeactivate didDismissSearchController didEndContact didEvaluateActions didEvaluateActionsForScene didFinishUpdate didFinishUpdateForScene didMoveToParentViewController didMoveToSuperview didMoveToURL didMoveToView didMoveToWindow didPresentActionSheet didPresentAlertView didPresentSearchController didReceiveLocalNotification didReceiveMemoryWarning didReceiveRemoteNotification didRotateFromInterfaceOrientation didSave didSelectCancel didSelectPost didSimulatePhysics didSimulatePhysicsForScene didTransitionFromLayout didTransitionToState didTurnIntoFault diffieHellmanGroup diffuse diffuseColor dimensions dimsBackgroundDuringPresentation direction directionalLockEnabled directory directoryAttributes directoryContentsAtPath directoryForTemporaryFiles disableActions disableAllBackgroundDeliveryWithCompletion disableAutomaticTermination disableBackgroundDeliveryForType disableEditing disableSharedPhotoStreamsSupport disableSuddenTermination disableUndoRegistration disableUpdates disableUserAttachments disabledBackground disablesAutomaticKeyboardDismissal disallowDeferredLocationUpdates discCount discNumber discardContentIfPossible discardable disconnect disconnectFromAllPeers disconnectNodeInput disconnectNodeOutput disconnectOnSleep disconnectPeerFromAllPeers disconnectTimeout discoverAllContactUserInfosWithCompletionHandler discoverAllContactsCompletionBlock discoverCharacteristics discoverDescriptorsForCharacteristic discoverIncludedServices discoverServices discoverUserInfoWithEmailAddress discoverUserInfoWithUserRecordID discoverUserInfosCompletionBlock discoveredAccessories discoveryInfo discretionary diskCapacity dislikeCommand dismiss dismissAnimated dismissController dismissGrantingAccessToURL dismissHeadingCalibrationDisplay dismissKeyboard dismissMenuAnimated dismissModalViewControllerAnimated dismissMoviePlayerViewControllerAnimated dismissPopoverAnimated dismissPreviewAnimated dismissTextInputController dismissViewControllerAnimated dismissWithClickedButtonIndex dismissalTransitionDidEnd dismissalTransitionWillBegin dispatchThreadgroups display displayIfNeeded displayLayer displayLinkWithTarget displayLocation displayMode displayModeButtonItem displayName displayNameAtPath displayNameForKey displayNameForPeer displayNameWithLocale displayScale displaySizeImage displayedPerson displayedProperties displayingBannerAd displaysSearchBarInNavigationBar distance distanceAttenuationModel distanceAttenuationParameters distanceFilter distanceFromLocation distanceFromString distantFuture distantPast distinguishedNames dividerImageForLeftSegmentState documentContextAfterInput documentContextBeforeInput documentInteractionController documentInteractionControllerDidDismissOpenInMenu documentInteractionControllerDidDismissOptionsMenu documentInteractionControllerDidEndPreview documentInteractionControllerRectForPreview documentInteractionControllerViewControllerForPreview documentInteractionControllerViewForPreview documentInteractionControllerWillBeginPreview documentInteractionControllerWillPresentOpenInMenu documentInteractionControllerWillPresentOptionsMenu documentMenu documentMenuWasCancelled documentPicker documentPickerMode documentPickerWasCancelled documentState documentStorageURL documentText doesRelativeDateFormatting domain dominantLanguage dominantLanguageForScript dominantScript doorsCloseHorizontalWithDuration doorsCloseVerticalWithDuration doorsOpenHorizontalWithDuration doorsOpenVerticalWithDuration doorwayWithDuration doubleForKey doubleSided doubleValue doubleValueForUnit down downloadContentLengths downloadContentVersion downloadOverdue downloadState downloadTaskWithRequest downloadTaskWithResumeData downloadTaskWithURL downloadWithDelegate downloadable downloadingAssets downloads dpad dragField dragState draggable dragging drain draw drawAsPatternInRect drawAtPoint drawBackgroundForGlyphRange drawContentForPageAtIndex drawFooterForPageAtIndex drawGlyphsForGlyphRange drawHeaderForPageAtIndex drawImage drawInContext drawInRect drawIndexedPrimitives drawLayer drawMapRect drawPageAtIndex drawPlaceholderInRect drawPrimitives drawPrintFormatter drawRect drawStrikethroughForGlyphRange drawTextInRect drawUnderlineForGlyphRange drawViewHierarchyInRect drawWithRect drawableColorFormat drawableDepthFormat drawableHeight drawableMultisample drawableProperties drawableSize drawableStencilFormat drawableWidth drawsAsynchronously drawsOutsideLineFragmentForGlyphAtIndex dueDateComponents duplex duration durationWatched dynamic dynamicAnimator dynamicAnimatorDidPause dynamicAnimatorWillResume dynamicBody eaglContext earlierDate edgeAntialiasingMask edgeCreasesElement edgeCreasesSource edgeWidths edges edgesForExtendedLayout editAction editButtonItem editViewDelegate editable edited editedMask editedRange editing editingAccessoryType editingAccessoryView editingRectForBounds editingStringForObjectValue editingStyle effect effectForBlurEffect effectWithStyle elapsedTime elasticity electricField elementArrayType elementStructType elementType emailAddresses emission emissionAngle emissionAngleRange emissionDuration emissionDurationVariation emissionLatitude emissionLongitude emissionRange emissiveColor emitterCell emitterCells emitterDepth emitterMode emitterPosition emitterShape emitterSize emitterZPosition emittingDirection empty emptyImage enable enableAutomaticTermination enableBackgroundDeliveryForType enableEditing enableInputClicksWhenVisible enableNotification enablePostProcessing enableRate enableSetNeedsDisplay enableSuddenTermination enableUndoRegistration enableUpdates enabled enabledRemoteNotificationTypes enablesReturnKeyAutomatically enablesVideoStabilizationWhenAvailable encodeArrayOfObjCType encodeBool encodeBycopyObject encodeByrefObject encodeBytes encodeCGAffineTransform encodeCGPoint encodeCGRect encodeCGSize encodeCGVector encodeCMTime encodeCMTimeMapping encodeCMTimeRange encodeConditionalObject encodeDataObject encodeDouble encodeFloat encodeInt encodeInt32 encodeInt64 encodeInteger encodeNXObject encodeObject encodePropertyList encodeRestorableStateWithCoder encodeRootObject encodeSystemFieldsWithCoder encodeUIEdgeInsets encodeUIOffset encodeValueOfObjCType encodeValuesOfObjCTypes encodeWithCoder encryptionAlgorithm encryptionPreference end endActivity endAppearanceTransition endBackgroundTask endContentAccess endCustomizingAnimated endDate endEditing endEncoding endEntityMapping endGeneratingDeviceOrientationNotifications endGeneratingLibraryChangeNotifications endGeneratingPlaybackNotifications endIgnoringInteractionEvents endInstanceCreationForEntityMapping endInterruption endInterruptionWithFlags endMatchInTurnWithMatchData endOfDocument endPlaybackTime endPoint endProgress endReceivingRemoteControlEvents endRefreshing endRelationshipCreationForEntityMapping endSeeking endSessionAtSourceTime endTrackingWithTouch endTurnWithNextParticipant endTurnWithNextParticipants endUndoGrouping endUpdates endpointAvailable energyFormatterUnitFromUnit enforcedContentItemsCount enforcedContentTreeDepth engine enqueue enqueueNotification enqueueSampleBuffer ensureAttributesAreFixedInRange ensureGlyphsForCharacterRange ensureGlyphsForGlyphRange ensureLayoutForBoundingRect ensureLayoutForCharacterRange ensureLayoutForGlyphRange ensureLayoutForTextContainer entities entitiesByName entitiesForConfiguration entity entityForName entityMappings entityMappingsByName entityMigrationPolicyClassName entityName entityVersionHashesByName entries entriesPassingTest entryWithIdentifier enumerateAssetsAtIndexes enumerateAssetsUsingBlock enumerateAssetsWithOptions enumerateAttribute enumerateAttributesInRange enumerateBodiesAlongRayStart enumerateBodiesAtPoint enumerateBodiesInRect enumerateByteRangesUsingBlock enumerateChildNodesUsingBlock enumerateChildNodesWithName enumerateDatesStartingAfterDate enumerateEnclosingRectsForGlyphRange enumerateEventsMatchingPredicate enumerateGroupsWithTypes enumerateIndexesInRange enumerateIndexesUsingBlock enumerateIndexesWithOptions enumerateKeysAndObjectsUsingBlock enumerateKeysAndObjectsWithOptions enumerateLineFragmentsForGlyphRange enumerateLinesUsingBlock enumerateLinguisticTagsInRange enumerateMatchesInString enumerateMovesWithBlock enumerateObjectsAtIndexes enumerateObjectsUsingBlock enumerateObjectsWithOptions enumerateRangesInRange enumerateRangesUsingBlock enumerateRangesWithOptions enumerateResultsUsingBlock enumerateResultsWithOptions enumerateStatisticsFromDate enumerateSubstringsInRange enumerateTagsInRange enumerateValuesForProperties enumeratorAtPath enumeratorAtURL envMode environment ephemeralSessionConfiguration era eraSymbols error errorComment errorDomain errorLog errorStatusCode errorWithDomain escapedPatternForString escapedTemplateForString estimatedAssetCount estimatedDataRate estimatedItemSize estimatedProgress estimatedResultCount estimatedRowHeight estimatedSectionFooterHeight estimatedSectionHeaderHeight eulerAngles evaluateJavaScript evaluatePolicy evaluateScript evaluateWithObject event eventEditViewController eventEditViewControllerDefaultCalendarForNewEvents eventIdentifier eventStore eventStoreIdentifier eventViewController eventWithEventStore eventWithIdentifier events eventsMatchingPredicate evictUbiquitousItemAtURL evictsObjectsWithDiscardedContent exception exceptionDuringOperation exceptionHandler exceptionWithName exchangeDataMaximumSize exchangeID exchangeMaxInitiatedExchangesPerPlayer exchangeObjectAtIndex exchangeOverlay exchangeOverlayAtIndex exchangeSubviewAtIndex exchanges excludedActivityTypes exclusionPaths exclusive exclusiveTouch executableArchitectures executablePath executableURL executeActionSet executeFetchRequest executeQuery executeRequest executing executionBlocks exerciseAmbiguityInLayout existingObjectWithID exit expectedPlayerCount expectedTravelTime expectsMediaDataInRealTime expiresDate exponentSymbol exportAsynchronouslyWithCompletionHandler exportPresetsCompatibleWithAsset exportSessionWithAsset exportable exposureDuration exposureMode exposurePointOfInterest exposurePointOfInterestSupported exposureTargetBias exposureTargetOffset expression expressionBlock expressionForAggregate expressionForAnyKey expressionForBlock expressionForConstantValue expressionForEvaluatedObject expressionForFetch expressionForFunction expressionForIntersectSet expressionForKeyPath expressionForMinusSet expressionForSubquery expressionForUnionSet expressionForVariable expressionResultType expressionType expressionValueWithObject expressionWithFormat extendStateRestoration extendedGamepad extendedLanguageTag extendedLayoutIncludesOpaqueBars extendedLogData extendedLogDataStringEncoding extensionContext extent externalEntityResolvingPolicy externalPlaybackActive externalPlaybackVideoGravity extraAttributes extraLineFragmentRect extraLineFragmentTextContainer extraLineFragmentUsedRect extrapolateTimeFromAnchor extrusionDepth faceAngle faceID faceIndex fadeAlphaBy fadeAlphaTo fadeDuration fadeInDuration fadeInWithDuration fadeOpacityBy fadeOpacityTo fadeOutDuration fadeOutWithDuration fadeWithColor fadeWithDuration failureResponse falloff falloffBy falloffExponent falloffTo familyName familyNames fastMathEnabled fastestEncoding fault faultingState favorite featuresInImage feedback fetchAllRecordZonesOperation fetchAllRecordZonesWithCompletionHandler fetchAllSubscriptionsOperation fetchAllSubscriptionsWithCompletionHandler fetchAssetCollectionsContainingAsset fetchAssetCollectionsWithALAssetGroupURLs fetchAssetCollectionsWithLocalIdentifiers fetchAssetCollectionsWithType fetchAssetsInAssetCollection fetchAssetsWithALAssetURLs fetchAssetsWithBurstIdentifier fetchAssetsWithLocalIdentifiers fetchAssetsWithMediaType fetchAssetsWithOptions fetchBatchSize fetchCollectionListsContainingCollection fetchCollectionListsWithLocalIdentifiers fetchCollectionListsWithType fetchCollectionsInCollectionList fetchCurrentUserRecordOperation fetchKeyAssetsInAssetCollection fetchLimit fetchMomentListsWithSubtype fetchMomentsInMomentList fetchMomentsWithOptions fetchNotificationChangesCompletionBlock fetchOffset fetchRecordChangesCompletionBlock fetchRecordWithID fetchRecordZoneWithID fetchRecordZonesCompletionBlock fetchRecordsCompletionBlock fetchRemindersMatchingPredicate fetchRequest fetchRequestFromTemplateWithName fetchRequestTemplateForName fetchRequestTemplatesByName fetchRequestWithEntityName fetchResultAfterChanges fetchResultBeforeChanges fetchSavedGamesWithCompletionHandler fetchSubscriptionCompletionBlock fetchSubscriptionWithID fetchTopLevelUserCollectionsWithOptions fetchUserRecordIDWithCompletionHandler fetchedObjects fieldBitMask fileAttributes fileAttributesAtPath fileAttributesToWriteToURL fileCreationDate fileDescriptor fileExistsAtPath fileExtensionHidden fileFormat fileGroupOwnerAccountID fileGroupOwnerAccountName fileHFSCreatorCode fileHFSTypeCode fileHandleForReading fileHandleForReadingAtPath fileHandleForReadingFromURL fileHandleForUpdatingAtPath fileHandleForUpdatingURL fileHandleForWriting fileHandleForWritingAtPath fileHandleForWritingToURL fileHandleWithNullDevice fileHandleWithStandardError fileHandleWithStandardInput fileHandleWithStandardOutput fileIsAppendOnly fileIsImmutable fileManager fileModificationDate fileNameExtensionForType fileOwnerAccountID fileOwnerAccountName filePathURL filePosixPermissions filePresenters fileReferenceURL fileSize fileSystemAttributesAtPath fileSystemFileNumber fileSystemNumber fileSystemRepresentationWithPath fileType fileURL fileURLWithFileSystemRepresentation fileURLWithPath fileURLWithPathComponents fileWrapper fileWrapperFromRange fileWrappers filename files fill fillBackgroundRectArray fillBuffer fillColor fillMode fillPath fillRule fillShader fillTexture fillWithBlendMode filter filterArrayFromSerializedXMP filterNamesInCategories filterNamesInCategory filterParameters filterPredicates filterType filterUsingPredicate filterWithName filteredArrayUsingPredicate filteredOrderedSetUsingPredicate filteredSetUsingPredicate filteringMode filters finalFrameForViewController finalLayoutAttributesForDisappearingDecorationElementOfKind finalLayoutAttributesForDisappearingItemAtIndexPath finalLayoutAttributesForDisappearingSupplementaryElementOfKind finalResult finalize finalizeAnimatedBoundsChange finalizeCollectionViewUpdates finalizeLayoutTransition findMatchForRequest findPlayersForHostedMatchRequest findPlayersForHostedRequest finishCancelledRequest finishContentEditingWithCompletionHandler finishDecoding finishEncoding finishInteractiveTransition finishLoading finishLoadingWithError finishLoadingWithResponse finishMatchmakingForMatch finishTasksAndInvalidate finishTransaction finishWithComposedVideoFrame finishWithError finishWriting finishWritingWithCompletionHandler finished finishedHandlingError finishedSelectedImage finishedUnselectedImage fire fireDate firmwareRevision firstAttribute firstDayOfTheWeek firstIndex firstItem firstLineHeadIndent firstMatchInString firstMaterial firstName firstObject firstObjectCommonWithArray firstOtherButtonIndex firstRectForRange firstUnlaidCharacterIndex firstUnlaidGlyphIndex firstWeekday fixAttributesInRange fixedCoordinateSpace fixesAttributesLazily flashActive flashAvailable flashMode flashScrollIndicators flatness flattenedClone flipHorizontalWithDuration flipVerticalWithDuration floatComponents floatForKey floatMatrix2Value floatMatrix3Value floatMatrix4Value floatValue floatVector2Value floatVector3Value floatVector4Value floor floorsAscended floorsDescended fluidOunceImperialUnit fluidOunceUSUnit flush flushAndRemoveImage flushWithCompletionHandler focalBlurRadius focalDistance focalSize focusMode focusPointOfInterest focusPointOfInterestSupported fog fogColor fogDensityExponent fogEndDistance fogStartDistance followPath font fontAttributes fontColor fontDescriptor fontDescriptorByAddingAttributes fontDescriptorWithFace fontDescriptorWithFamily fontDescriptorWithFontAttributes fontDescriptorWithMatrix fontDescriptorWithName fontDescriptorWithSize fontDescriptorWithSymbolicTraits fontName fontNamesForFamilyName fontSize fontWithDescriptor fontWithName fontWithSize footUnit footerHeight footerReferenceSize footerViewForSection forFoodEnergyUse forMainFrame forMainFrameOnly forPersonHeightUse forPersonMassUse foregroundColor formIntersectionWithCharacterSet formUnionWithCharacterSet format formatDescription formatDescriptions formatIdentifier formatVersion formatWidth formats formattedValue formatterBehavior formattingContext forwardInvocation forwardItem forwardList forwardPlaybackEndTime fractionCompleted fractionOfDistanceThroughGlyphForPoint fragment fragmentArguments fragmentFunction fragmentShader frame frameCapacity frameDuration frameForAlignmentRect frameForDictationResultPlaceholder frameInfo frameInterval frameLength frameOfPresentedViewInContainerView framePosition framebufferOnly framesDisplayed framesPerSecond frequency fresnelExponent friction frictionSlip frictionTorque friendRequestComposeViewControllerDidFinish friends fromValue frontFaceStencil fullResolutionImage fullScreenImage fullSizeImageOrientation fullSizeImageURL fullscreen function functionName functionNames functionType functionWithControlPoints functionWithName gain gameCenterDelegate gameCenterViewControllerDidFinish gamepad gapBetweenPages gathering generalPasteboard generateCGImagesAsynchronouslyForTimes generateIdentityVerificationSignatureWithCompletionHandler generateMipmapsForTexture generatesCalendarDates generatesDecimalNumbers generatesDeviceOrientationNotifications genre genrePersistentID genresQuery geoLocation geocodeAddressDictionary geocodeAddressString geocoding geodesic geometry geometryElementAtIndex geometryElementCount geometryElementWithData geometryFlipped geometryIndex geometrySourceWithData geometrySourceWithNormals geometrySourceWithTextureCoordinates geometrySourceWithVertices geometrySourcesForSemantic geometryWithSources gestureRecognizer gestureRecognizerShouldBegin gestureRecognizers getArgument getArgumentTypeAtIndex getBoundStreamsWithBufferSize getBoundingBoxMin getBoundingSphereCenter getBuffer getBytes getCFRunLoop getCString getCachedResponseForDataTask getCharacters getContinuationStreamsWithCompletionHandler getControlPointAtIndex getCookiesForTask getCoordinates getCredentialsForProtectionSpace getCropRectangleRampForTime getDefaultCredentialForProtectionSpace getDistanceFrom getEra getFileSystemRepresentation getFirstUnlaidCharacterIndex getGlyphsInRange getHour getHue getIndexes getInputStream getKeyframeTimeForIndex getKeyframeValueForIndex getLineDash getLineFragmentInsertionPointsForCharacterAtIndex getLineStart getNonlocalVersionsOfItemAtURL getObjectValue getObjects getOpacityRampForTime getParagraphStart getPromisedItemResourceValue getRed getRelationship getResourceValue getReturnValue getStreamsToHost getStreamsToHostWithName getTasksWithCompletionHandler getTransformRampForTime getUUIDBytes getValue getVolumeRampForTime getWhite gimbalLockEnabled gl glext glkView glkViewController glkViewControllerUpdate globalGain globalObject globalTuning globallyUniqueString glowWidth gltypes glyphAtIndex glyphIndexForCharacterAtIndex glyphIndexForPoint glyphRangeForBoundingRect glyphRangeForBoundingRectWithoutAdditionalLayout glyphRangeForCharacterRange glyphRangeForTextContainer goBack goForward goToBackForwardListItem gobo gramUnit gramUnitWithMetricPrefix grammarCheckingResultWithRange grammarDetails gravity gravityDirection grayColor grayWorldDeviceWhiteBalanceGains green greenColor greenRange greenSpeed gregorianStartDate group groupForURL groupIdentifier groupTableViewBackgroundColor groupedResults groupingAttributes groupingLevel groupingSeparator groupingSize groupingType groupsByEvent gssapi gssapi_apple gssapi_krb5 gssapi_oid gssapi_protos gssapi_spnego guessesForWordRange guidedAccessRestrictionIdentifiers guidedAccessRestrictionWithIdentifier gyroActive gyroAvailable gyroData gyroUpdateInterval halfExtent handleActionWithIdentifier handleBindingOfSymbol handleError handleEvent handleFailureInFunction handleFailureInMethod handleInviteFromGameCenter handleMachMessage handleMatchEnded handlePortMessage handleQueryWithUnboundKey handleTakeValue handleTurnEventForMatch handleUnbindingOfSymbol handleUserActivity hardwareRevision hasAction hasActions hasAlarms hasAmbiguousLayout hasAttendees hasBytesAvailable hasChanges hasFaceAngle hasFaultForRelationshipNamed hasFlash hasIncrementalChanges hasItemConformingToTypeIdentifier hasLearnedWord hasLeftEyePosition hasLocalContents hasMediaCharacteristic hasMediaType hasMemberInPlane hasMouthPosition hasMoves hasNewPixelBufferForItemTime hasNonContiguousLayout hasNotes hasOnlySecureContent hasPassword hasPrefix hasProperty hasProtectedContent hasRecurrenceRules hasRightEyePosition hasRollAngle hasSameAddressAs hasSmile hasSpaceAvailable hasSuffix hasText hasThousandSeparators hasThumbnail hasTorch hasTrackingFrameCount hasTrackingID hasUnsavedChanges hasYawAngle hash hashFunction hashTableWithOptions hashTableWithWeakObjects havingPredicate headIndent headerHeight headerReferenceSize headerViewForSection heading headingAccuracy headingAvailable headingFilter headingOrientation height heightSegmentCount heightTracksTextView helpAnchor hidden hide hidesAccessoryWhenEditing hidesBackButton hidesBarsOnSwipe hidesBarsOnTap hidesBarsWhenKeyboardAppears hidesBarsWhenVerticallyCompact hidesBottomBarWhenPushed hidesForSinglePage hidesNavigationBarDuringPresentation hidesWhenStopped highQualityRendering highResolutionStillImageDimensions highResolutionStillImageOutputEnabled highlighted highlightedAnimationImages highlightedImage highlightedTextColor hitTest hitTestWithSegmentFromPoint home homeDidUpdateName homeManager homeManagerDidUpdateHomes homeManagerDidUpdatePrimaryHome homes horizontalAccuracy horizontalAlignmentMode horizontalSizeClass host hostName hostTime hostTimeForSeconds hostTimeValid hostWithName hosted hour hourUnit hyphenationFactor iAd iPodMusicPlayer icon icons idGLKViewControllerDelegate> idGLKViewDelegate> identifier identifierForKey identifierForNewStoreAtURL identifierForVendor identifiersForBridgedAccessories identifiersOfEntriesWithClass identifyWithCompletionHandler identity identityData identityDataPassword identityReference idleDuration idleDurationVariation idleTimerDisabled idx ignoreSnapshotOnNextApplicationLaunch ignoreTouch ignoreWord ignoredWords ignoresSiblingOrder illegalCharacterSet image imageAsset imageByApplyingFilter imageByApplyingOrientation imageByApplyingTransform imageByClampingToExtent imageByCompositingOverImage imageByCroppingToRect imageCropRect imageEdgeInsets imageForBounds imageForSearchBarIcon imageForSegmentAtIndex imageForState imageInsets imageNamed imageOrientation imagePickerController imagePickerControllerDidCancel imageRectForContentRect imageSequenceAnimationMode imageSequenceColumnCount imageSequenceFrameRate imageSequenceFrameRateVariation imageSequenceInitialFrame imageSequenceInitialFrameVariation imageSequenceRowCount imageTransformForOrientation imageView imageWithAlignmentRectInsets imageWithBitmapData imageWithCGImage imageWithCGLayer imageWithCIImage imageWithCVImageBuffer imageWithCVPixelBuffer imageWithColor imageWithContentsOfFile imageWithContentsOfURL imageWithData imageWithIOSurface imageWithRenderingMode imageWithSize imageWithTexture imageWithTraitCollection images immutable inParentHierarchy inPort inUseByAnotherApplication inchUnit includeAllBurstAssets includeHiddenAssets includedServices includesActualByteCount includesApproximationPhrase includesCount includesPeerToPeer includesPendingChanges includesPropertyValues includesSubentities includesTimeRemainingPhrase includesUnit incompleteAchievementImage increaseLengthBy increaseSize incrementImageForState indentationLevel indentationWidth indeterminate index indexAtPosition indexGreaterThanIndex indexGreaterThanOrEqualToIndex indexInRange indexLessThanIndex indexLessThanOrEqualToIndex indexOfAccessibilityElement indexOfNowPlayingItem indexOfObject indexOfObjectAtIndexes indexOfObjectIdenticalTo indexOfObjectPassingTest indexOfObjectWithOptions indexOfResult indexPassingTest indexPath indexPathAfterUpdate indexPathBeforeUpdate indexPathByAddingIndex indexPathByRemovingLastIndex indexPathForCell indexPathForElementWithModelIdentifier indexPathForItem indexPathForItemAtPoint indexPathForObject indexPathForRow indexPathForRowAtPoint indexPathForSelectedRow indexPathWithIndex indexPathWithIndexes indexPathsForRowsInRect indexPathsForSelectedItems indexPathsForSelectedRows indexPathsForVisibleItems indexPathsForVisibleRows indexPathsToDeleteForDecorationViewOfKind indexPathsToDeleteForSupplementaryViewOfKind indexPathsToInsertForDecorationViewOfKind indexPathsToInsertForSupplementaryViewOfKind indexSet indexSetWithIndex indexSetWithIndexesInRange indexTitle indexWithOptions indexed indexedBySpotlight indexesInRange indexesOfObjectsAtIndexes indexesOfObjectsPassingTest indexesOfObjectsWithOptions indexesPassingTest indexesWithOptions indicatedBitrate indicatorStyle inferredMappingModelForSourceModel infiniteRegion influenceFactor infoDictionary init initByResolvingBookmarkData initCircularRegionWithCenter initDirectoryWithFileWrappers initFileURLWithFileSystemRepresentation initFileURLWithPath initForReading initForReadingWithData initForWriting initForWritingWithMutableData initRecurrenceWithFrequency initRegularFileWithContents initRemoteWithProtocolFamily initRemoteWithTCPPort initStandardFormatWithSampleRate initSymbolicLinkWithDestination initSymbolicLinkWithDestinationURL initToBuffer initToFileAtPath initToMemory initWithAPI initWithAVPlayer initWithAccessibilityContainer initWithAccessory initWithAccountType initWithActivityIndicatorStyle initWithActivityItems initWithActivityType initWithAdType initWithAnnotation initWithArray initWithAsset initWithAssetReaderTrackOutput initWithAssetWriterInput initWithAttributedString initWithAttributedText initWithAudioComponentDescription initWithAudioTimeStamp initWithAudioTracks initWithAuthenticationChallenge initWithBadgeValue initWithBarButtonSystemItem initWithBase64EncodedData initWithBase64EncodedString initWithBase64Encoding initWithBitmapData initWithBool initWithBrowser initWithBytes initWithBytesNoCopy initWithCGAffineTransform initWithCGColor initWithCGImage initWithCGLayer initWithCGPoint initWithCGRect initWithCIColor initWithCIImage initWithCString initWithCStringNoCopy initWithCVImageBuffer initWithCVPixelBuffer initWithCalendarIdentifier initWithCapacity initWithCategory initWithCenter initWithChar initWithCharacteristic initWithCharacters initWithCharactersNoCopy initWithCircle initWithCoder initWithCollectionViewLayout initWithColor initWithCommonFormat initWithConcurrencyType initWithCondition initWithContentEditingInput initWithContentURL initWithContentViewController initWithContentsOfFile initWithContentsOfMappedFile initWithContentsOfURL initWithControlPoints initWithController initWithCoordinate initWithCurrentLayout initWithCursor initWithCustomView initWithData initWithDateFormat initWithDayOfTheWeek initWithDecimal initWithDelegate initWithDevice initWithDictionary initWithDisplayID initWithDisplayName initWithDocumentTypes initWithDomain initWithDominantScript initWithDouble initWithEffect initWithEmailAddresses initWithEntity initWithEntityName initWithExpressionType initWithFetchRequest initWithFileAtPath initWithFileDescriptor initWithFilePresenter initWithFileURL initWithFilterPredicates initWithFireDate initWithFloat initWithFontAttributes initWithFontNamed initWithFormat initWithFormatIdentifier initWithFrame initWithHost initWithHostTime initWithHue initWithIOSurface initWithIdentifier initWithIdentifiers initWithIdentity initWithImage initWithImageNamed initWithIndex initWithIndexSet initWithIndexes initWithIndexesInRange initWithInputPort initWithInputPorts initWithInputs initWithInsertedObjects initWithInt initWithInteger initWithInvite initWithInvocation initWithItem initWithItems initWithKey initWithKeyOptions initWithKeyPath initWithKeyPointerFunctions initWithKeyframeValues initWithLatitude initWithLayer initWithLayout initWithLayoutTag initWithLeaderboardIdentifier initWithLeftExpression initWithLength initWithLocaleIdentifier initWithLong initWithLongLong initWithLowerAngleLimit initWithLowerLimit initWithMachPort initWithManagedObjectModel initWithMantissa initWithMapView initWithMarkupText initWithMatchDomains initWithMatchRequest initWithMediaSubtypesForNativeRepresentation initWithMediaType initWithMediaTypes initWithMemoryCapacity initWithMergeType initWithName initWithNavigationBarClass initWithNibName initWithNotificationCenter initWithNotificationIDsToMarkRead initWithNumberOfBands initWithOAuth2Token initWithOAuthToken initWithObject initWithObjectID initWithObjects initWithObjectsAndKeys initWithOptions initWithOrderedSet initWithOverlay initWithPCMFormat initWithParent initWithPass initWithPasses initWithPath initWithPattern initWithPatternImage initWithPaymentRequest initWithPeer initWithPersistentStoreCoordinator initWithPixelBufferAttributes initWithPlaceholderForCreatedAsset initWithPlaceholderItem initWithPlacemark initWithPlayerIDs initWithPlayerItem initWithPlayers initWithPointerFunctions initWithPolygon initWithPolyline initWithPreferredLanguages initWithPresentedViewController initWithPreviousServerChangeToken initWithProductIdentifiers initWithProgressViewStyle initWithProperties initWithProtectionSpace initWithProtocolFamily initWithProximityUUID initWithProxyHost initWithQuantityType initWithQuery initWithQueue initWithRadius initWithReceiptProperties initWithRecord initWithRecordID initWithRecordIDs initWithRecordName initWithRecordType initWithRecordZoneID initWithRecordZoneIDs initWithRecordZonesToSave initWithRecordsToSave initWithRed initWithReferenceView initWithRequest initWithResponse initWithReuseIdentifier initWithRootViewController initWithRoundingMode initWithSampleBuffer initWithSampleTime initWithSampleType initWithScheme initWithSearchBar initWithSearchResultsController initWithSelectionStyle initWithSerializedRepresentation initWithServiceType initWithSession initWithSessionID initWithSessionWithNoConnection initWithSet initWithSettings initWithShareContext initWithSharegroup initWithShort initWithSize initWithSnapshotData initWithSource initWithSourceModel initWithStream initWithStreamDescription initWithString initWithStyle initWithSubscriptionIDs initWithSubscriptionsToSave initWithSuiteName initWithTCPPort initWithTabBarSystemItem initWithTagSchemes initWithTarget initWithTask initWithTerm initWithText initWithTextAlignment initWithTextInput initWithTextMarkupAttributes initWithTexture initWithTileOverlay initWithTimeInterval initWithTimeIntervalSince1970 initWithTimeIntervalSinceNow initWithTimeIntervalSinceReferenceDate initWithTimeRange initWithTitle initWithTrack initWithTransitionStyle initWithTrust initWithType initWithTypes initWithURL initWithURLTemplate initWithUTF8String initWithUUIDBytes initWithUUIDString initWithUnsignedChar initWithUnsignedInt initWithUnsignedInteger initWithUnsignedLong initWithUnsignedLongLong initWithUnsignedShort initWithUser initWithValue initWithValues initWithVideoFileNamed initWithVideoTracks initWithVideoURL initWithViewportSize initWithVirtualMachine initWithWhite initWithX initWithZoneID initWithZoneName initialFrameForViewController initialLayoutAttributesForAppearingDecorationElementOfKind initialLayoutAttributesForAppearingItemAtIndexPath initialLayoutAttributesForAppearingSupplementaryElementOfKind initialPlaybackTime initialResultsHandler initialURL initiallyInteractive injectionTime inlandWater innerRadius input inputAccessoryView inputAccessoryViewController inputAvailable inputBias inputDataSource inputDataSources inputDelegate inputFormatForBus inputGain inputGainSettable inputGroups inputImageMaximumSize inputIsAvailable inputIsAvailableChanged inputItems inputKeys inputLatency inputMeterLevel inputMeteringEnabled inputMode inputNode inputNumberOfChannels inputOrigin inputParameters inputPorts inputProperty inputScale inputSourceID inputSources inputStream inputStreamWithData inputStreamWithFileAtPath inputStreamWithURL inputView inputViewController inputViewStyle inputs insertAssets insertAttributedString insertChild insertChildCollections insertChildNode insertDebugCaptureBoundary insertDebugSignpost insertDictationResult insertDictationResultPlaceholder insertEmptyTimeRange insertItem insertItemsAtIndexPaths insertMaterial insertNewObjectForEntityForName insertObject insertObjects insertOverlay insertPointer insertRowsAtIndexPaths insertRowsAtIndexes insertSections insertSegmentWithImage insertSegmentWithTitle insertString insertSublayer insertSubview insertText insertTextContainer insertTimeRange insertTimeRanges inserted insertedIndexes insertedObjects installTapOnBus instanceAlphaOffset instanceBlueOffset instanceColor instanceCount instanceDelay instanceGreenOffset instanceRedOffset instanceTransform instantiateInitialViewController instantiateViewControllerWithIdentifier instantiateWithOwner instructions int intValue integerForKey integerValue integrityAlgorithm intensity interactionControllerForDismissal interactionControllerForPresentation interactionControllerWithURL interactivePopGestureRecognizer interfaceOrientation interfaceProperty interfaceTypeMatch interiorPolygons interleaved internationalCurrencySymbol interpolationMode interrupted intersectHashTable intersectOrderedSet intersectSet intersectsHashTable intersectsIndexesInRange intersectsMapRect intersectsNode intersectsOrderedSet intersectsSet interstitialAd interstitialAdActionDidFinish interstitialAdActionShouldBegin interstitialAdDidLoad interstitialAdDidUnload interstitialAdWillLoad interstitialPresentationPolicy interval intervalComponents intrinsicContentSize invalidProductIdentifiers invalidate invalidateAndCancel invalidateAttributesInRange invalidateDataSourceCounts invalidateDecorationElementsOfKind invalidateDisplayForCharacterRange invalidateDisplayForGlyphRange invalidateEverything invalidateFlowLayoutAttributes invalidateFlowLayoutDelegateMetrics invalidateGlyphsForCharacterRange invalidateIntrinsicContentSize invalidateItemsAtIndexPaths invalidateLayout invalidateLayoutForCharacterRange invalidateLayoutWithContext invalidatePath invalidateSupplementaryElementsOfKind invalidateUserActivity invalidatedDecorationIndexPaths invalidatedItemIndexPaths invalidatedSupplementaryIndexPaths invalidationContextClass invalidationContextForBoundsChange invalidationContextForPreferredLayoutAttributes inverseKinematicsConstraintWithChainRootNode inverseRegion inverseRelationship invert invertedSet inviteHandler inviteMessage invitePeer inviteeResponseHandler inviter invocation invocationWithMethodSignature invoke invokeMethod invokeWithTarget is isAccessibilityElement isActive isActivityAvailable isAdvertising isAlphaToCoverageEnabled isAlphaToOneEnabled isAnalog isAnimated isAnimating isAnimationForKeyPaused isAntialiased isAtEnd isAttachedToDevice isAvailableForServiceType isBeingDismissed isBeingPresented isBlendingEnabled isBoolean isBroadcasted isCameraDeviceAvailable isCancelled isCloudItem isCompatibleWithUnit isCompilation isConfiguration isConnected isContainer isContentDiscarded isContentValid isCurrentLocation isCurrentUser isCustomizing isDate isDateInToday isDateInTomorrow isDateInWeekend isDateInYesterday isDaylightSavingTimeForDate isDeletableFileAtPath isDescendantOfView isDetached isDirectionsRequestURL isDistanceAvailable isDynamic isEnabled isEnabledForSegmentAtIndex isEqual isEqualFunction isEqualToArray isEqualToAttributedString isEqualToData isEqualToDate isEqualToDictionary isEqualToHashTable isEqualToIndexSet isEqualToNode isEqualToNumber isEqualToObject isEqualToOrderedSet isEqualToSet isEqualToString isEqualToTimeZone isEqualToValue isEqualWithTypeCoercionToObject isExclusive isExecutableFileAtPath isExposureModeSupported isFileReferenceURL isFinished isFirstResponder isFlashAvailableForCameraDevice isFlashModeSupported isFloorCountingAvailable isFocusModeSupported isForFoodEnergyUse isForPersonHeightUse isForPersonMassUse isFramebufferOnly isFriend isHealthDataAvailable isHidden isHiddenassignreadonlyNS_NONATOMIC_IOSONLY isIgnoringInteractionEvents isInstanceOf isInteractive isKindOfEntity isMainThread isMonitoringAvailableForClass isMovingFromParentViewController isMovingToParentViewController isMultiThreaded isNegative isNetworkAccessAllowed isNew isNodeInsideFrustum isNotifying isNull isNumber isObject isOneway isOperatingSystemAtLeastVersion isPartialStringValid isPassLibraryAvailable isPaused isPaymentPassActivationAvailable isPlayable isPlayableExtendedMIMEType isPosition isPreparedToPlay isPressed isPrimary isPrintingAvailable isProxy isPruned isPublicDatabase isRangingAvailable isRasterizationEnabled isReadableFileAtPath isReadyForDisplay isRegisteredForRemoteNotifications isRelativeAltitudeAvailable isReplayableassignreadonly isResting isRunning isShowingAppNames isSourceTypeAvailable isStepCountingAvailable isString isSubsetOfHashTable isSubsetOfOrderedSet isSubsetOfSet isSupersetOfSet isSupportedAttachmentUTI isTorchModeSupported isUbiquitousItemAtURL isUndefined isValidDateInCalendar isValidForAsset isValidGlyphIndex isValidJSONObject isVertical isVideoStabilizationModeSupported isViewLoaded isVoIPAllowed isWhiteBalanceModeSupported isWritableFileAtPath isoCountryCode issue issueChallengeToPlayers issueDate issueWithName issues issuingPlayer issuingPlayerID italicSystemFontOfSize item itemAtIndex itemAtURL itemChangedAtURL itemPositioning itemSections itemSetWithPasteboardTypes itemSize itemSpacing itemTimeForCVTimeStamp itemTimeForHostTime itemTimeForMachAbsoluteTime itemWidth items itemsInRect javaEnabled javaScriptActionWithScript javaScriptCanOpenWindowsAutomatically javaScriptEnabled jitteringEnabled jobName jointWithBody jointWithBodyA joints jouleUnit jouleUnitWithMetricPrefix jpegStillImageNSDataRepresentation kelvinUnit kernelWithString kernelsWithString key keyCommandWithInput keyCommands keyEnumerator keyForFileWrapper keyForIdentifier keyPath keyPathsAndRelativeValuesForViewerOffset keyPathsForValuesAffectingValueForKey keyPointerFunctions keySpace keySpaceForIdentifier keyTimes keyWindow keyboardAppearance keyboardDismissMode keyboardDisplayRequiresUserAction keyboardType keysOfEntriesPassingTest keysOfEntriesWithOptions keysSortedByValueUsingComparator keysSortedByValueUsingSelector keysSortedByValueWithOptions keyspace kilocalorieUnit kind kinematicBody knownTimeZoneNames label labelColor labelFontSize labelNodeWithFontNamed labelNodeWithText landscapeImagePhone landscapeImagePhoneInsets language languageCode languageMap languagesForScript lastFireDate lastIndex lastModifiedDate lastModifiedUserRecordID lastName lastObject lastPathComponent lastPlayedDate lastRenderTime lastReportedDate lastTurnDate laterDate latitude layer layerClass layerInstructions layerWithSession layerWithSessionWithNoConnection layoutAttributesClass layoutAttributesForCellAtIndexPath layoutAttributesForCellWithIndexPath layoutAttributesForDecorationViewOfKind layoutAttributesForElementsInRect layoutAttributesForItemAtIndexPath layoutAttributesForSupplementaryElementOfKind layoutAttributesForSupplementaryViewOfKind layoutIfNeeded layoutManager layoutManagerDidInvalidateLayout layoutManagers layoutMargins layoutMarginsDidChange layoutOrientation layoutSublayers layoutSublayersOfLayer layoutSubviews layoutTag layoutWithLayout layoutWithLayoutTag layouts leaderboardCategory leaderboardDelegate leaderboardIdentifier leaderboardTimeScope leaderboardViewControllerDidFinish leading leapMonth learnWord left leftBarButtonItem leftBarButtonItems leftCalloutAccessoryView leftCalloutOffset leftCapWidth leftExpression leftEyeClosed leftEyePosition leftItemsSupplementBackButton leftShoulder leftThumbstick leftTrigger leftView leftViewMode leftViewRectForBounds legibleOutput length lengthFormatterUnitFromUnit lengthOfBytesUsingEncoding lengthSegmentCount lenient lensAperture lensPosition letterCharacterSet level levelOfDetailWithGeometry levelsOfDetail levelsOfDetailBias levelsOfUndo libAVFAudio libAudioDSP libBLAS libCGCorePDF libCGFreetype libCGInterfaces libCGVolute libCGXType libCLRendererStubs libCMSBuiltin libCMaps libCVMSPluginSupport libCoreFSCache libCoreVMClient libFontStreams libGFXShared libGLImage libGLProgrammability libGLVMPlugin libJBIG2 libLAPACK libLLVMContainer libLinearAlgebra libPDFRIP libRIP libvDSP libvMisc lifetime lifetimeMinutes lifetimeRange light light0 light0light1light2 lightColor lightGrayColor lightModelAmbientColor lightModelTwoSided lightTextColor lightingBitMask lightingEnabled lightingModelName lightingType likeCommand limit limitDateForMode limits lineBreakMode lineCap lineCapStyle lineDashPattern lineDashPhase lineDirectionForLanguage lineFragmentPadding lineFragmentRectForGlyphAtIndex lineFragmentRectForProposedRect lineFragmentUsedRectForGlyphAtIndex lineHeight lineHeightMultiple lineJoin lineJoinStyle lineLength lineNumber lineRangeForRange lineSpacing lineWidth linearDamping linearGravityField linearGravityFieldWithVector linearVelocityForItem linear_systems linguisticTagsInRange linkCheckingResultWithRange linkItemAtPath linkItemAtURL linkPath linkTextAttributes linkedDevices listenerAngularOrientation listenerPosition listenerVectorOrientation litPerPixel literUnit literUnitWithMetricPrefix load loadAchievementDescriptionsWithCompletionHandler loadAchievementsWithCompletionHandler loadAction loadAndReturnError loadAudioFilesAtURLs loadAudioUnitPresetAtURL loadCategoriesWithCompletionHandler loadData loadDataWithCompletionHandler loadDefaultLeaderboardCategoryIDWithCompletionHandler loadDefaultLeaderboardIdentifierWithCompletionHandler loadFactoryPreset loadFactoryReverbPreset loadFriendPlayersWithCompletionHandler loadFriendsWithCompletionHandler loadFromContents loadFromPreferencesWithCompletionHandler loadHTMLString loadImageWithCompletionHandler loadInstrumentAtURL loadItemForTypeIdentifier loadLeaderboardSetsWithCompletionHandler loadLeaderboardsWithCompletionHandler loadMatchDataWithCompletionHandler loadMatchWithID loadMatchesWithCompletionHandler loadMetadata loadNibNamed loadPhotoForSize loadPlayersForIdentifiers loadPreviewImageWithOptions loadPreviewView loadProductWithParameters loadReceivedChallengesWithCompletionHandler loadRequest loadResourceDataNotifyingClient loadScoresWithCompletionHandler loadSoundBankInstrumentAtURL loadState loadTileAtPath loadValuesAsynchronouslyForKeys loadView loaded loadedTimeRanges loading local localCoordinates localIdentifier localName localNormal localPlayer localPlayerDidCompleteChallenge localPlayerDidReceiveChallenge localPlayerDidSelectChallenge localPlayerScore localTimeZone locale localeIdentifier localeIdentifierFromComponents localeIdentifierFromWindowsLocaleCode localeWithLocaleIdentifier locality localizationDictionary localizations localizedAdditionalDescription localizedCaseInsensitiveCompare localizedCaseInsensitiveContainsString localizedCompare localizedDescription localizedDescriptionForFilterName localizedFailureReason localizedFallbackTitle localizedInfoDictionary localizedLocationNames localizedModel localizedName localizedNameForCategory localizedNameForFilterName localizedNameOfSavingComputer localizedNameOfStringEncoding localizedRecoveryOptions localizedRecoverySuggestion localizedReferenceDocumentationForFilterName localizedScannerWithString localizedShortTitle localizedStandardCompare localizedStringForKey localizedStringForStatusCode localizedStringFromDate localizedStringFromDateComponents localizedStringFromNumber localizedStringWithFormat localizedTitle localizedValueForFieldKey localizesFormat location locationForGlyphAtIndex locationInNode locationInView locationManager locationManagerDidPauseLocationUpdates locationManagerDidResumeLocationUpdates locationManagerShouldDisplayHeadingCalibration locationOfTouch locationServicesEnabled locationWithTitle locations lock lockBeforeDate lockForConfiguration lockWhenCondition lockedObjects locksAmbientWithDiffuse lodMaxClamp lodMinClamp long longCharacterIsMember longEraSymbols longLongForKey longValue longitude lookAtConstraintWithTarget lookupAdConversionDetails loops lossyCString lowLightBoostEnabled lowLightBoostSupported lowPassCutoff lowerAngleLimit lowerDistanceLimit lowerLimit lowercaseLetterCharacterSet lowercaseString lowercaseStringWithLocale lyrics m4v macAddress machPort magFilter magentaColor magneticField magneticHeading magnetometerActive magnetometerAvailable magnetometerData magnetometerUpdateInterval magnification magnificationFilter magnitude mailComposeController mailComposeDelegate main mainBundle mainDocumentURL mainFrame mainMixerNode mainQueue mainRunLoop mainScreen mainThread major majorRadius majorRadiusTolerance makeAndModel makeKeyAndVisible makeKeyWindow makeObjectsPerformSelector makeSampleCursorAtFirstSampleInDecodeOrder makeSampleCursorAtLastSampleInDecodeOrder makeSampleCursorWithPresentationTimeStamp makeTextWritingDirectionLeftToRight makeTextWritingDirectionRightToLeft managedObjectClassName managedObjectContext managedObjectContextDidRegisterObjectsWithIDs managedObjectContextDidUnregisterObjectsWithIDs managedObjectIDForURIRepresentation managedObjectModel managedValueWithValue manager manualExposureSettingsWithExposureDuration manufacturer manufacturerDescription manufacturerName mapItemForCurrentLocation mapItems mapPointForPoint mapRect mapRectForRect mapRectThatFits mapTableWithKeyOptions mapTableWithStrongToStrongObjects mapTableWithStrongToWeakObjects mapTableWithWeakToStrongObjects mapTableWithWeakToWeakObjects mapType mapView mapViewDidFailLoadingMap mapViewDidFinishLoadingMap mapViewDidFinishRenderingMap mapViewDidStopLocatingUser mapViewWillStartLoadingMap mapViewWillStartLocatingUser mapViewWillStartRenderingMap mappingChannel mappingModel mappingModelFromBundles mappingType markAsFinished markConfigurationAsFinal markCurrentPassAsFinished markNotificationsReadCompletionBlock markedTextRange markedTextStyle marksOutputTrackAsEnabled markupText mask maskNode maskView masksToBounds mass massFormatterUnitFromUnit masterGain match matchData matchDataMaximumSize matchDomains matchForInvite matchID matchOutcome matchRequest matchesContentsOfURL matchesInString matchingFontDescriptorsWithMandatoryKeys matchmakerDelegate matchmakerViewController matchmakerViewControllerWasCancelled material materialPropertyWithContents materialWithName materials matrix maxAllowedRotationAngleForJoint maxAnisotropy maxBiometryFailures maxBracketedCaptureStillImageCount maxConcurrentOperationCount maxCount maxDuration maxExposureDuration maxExposureTargetBias maxFrameDuration maxFrameRate maxISO maxLength maxNumberOfRecipients maxPlayers maxPlayersAllowedForMatchOfType maxRange maxRecordedDuration maxRecordedFileSize maxTotalThreadsPerThreadgroup maxWhiteBalanceGain maximum maximumAngularLimit maximumContentHeight maximumContentWidth maximumDate maximumDecimalNumber maximumDistance maximumFractionDigits maximumInputNumberOfChannels maximumIntegerDigits maximumLengthOfBytesUsingEncoding maximumLineHeight maximumLinearLimit maximumNumberOfLines maximumNumberOfPeers maximumNumberOfTouches maximumOutputNumberOfChannels maximumPoints maximumPrimaryColumnWidth maximumQuantity maximumQuantityForSource maximumRangeOfUnit maximumRating maximumRegionMonitoringDistance maximumRelativeValue maximumSignificantDigits maximumSize maximumSuspensionForce maximumSuspensionTravel maximumTrackImageForState maximumTrackTintColor maximumUnitCount maximumUpdateValueLength maximumValue maximumValueImage maximumValueImageRectForBounds maximumVolumeSliderImageForState maximumZ maximumZoomScale mediaPicker mediaPickerDidCancel mediaPlaybackAllowsAirPlay mediaPlaybackRequiresUserAction mediaRequestsWWAN mediaSelectionCriteriaForMediaCharacteristic mediaSelectionGroupForMediaCharacteristic mediaSelectionOptionWithPropertyList mediaSelectionOptionsFromArray mediaSubTypes mediaSubtypes mediaTimeScale mediaType mediaTypes member memberByName members memoryCapacity menuBarVisibility menuFrame menuItems menuVisible merchantCapabilities merchantIdentifier mergeChangesFromContextDidSaveNotification mergePolicy mergeType mergedModelFromBundles message messageComposeDelegate messageComposeViewController messageString metadata metadataForFormat metadataForPersistentStore metadataForPersistentStoreOfType metadataForPersistentStoreWithURL metadataItem metadataItemFilter metadataItemFilterForSharing metadataItemsFromArray metadataObjectTypes metadataObjectsCallbackQueue metadataObjectsDelegate metadataOutput metadataOutputRectOfInterestForRect metadataQuery meterUnit meterUnitWithMetricPrefix meteringEnabled methodReturnLength methodSignature methodSignatureForSelector microphoneMuted migratePersistentStore migrateStoreFromURL migrationManagerClass migrationProgress mileUnit millimeterOfMercuryUnit minCount minExposureDuration minExposureTargetBias minFilter minFrameDuration minFrameRate minFreeDiskSpaceLimit minISO minPlayers minificationFilter minificationFilterBias minificationFiltermagnificationFilter minimum minimumAngularLimit minimumDate minimumDaysInFirstWeek minimumDecimalNumber minimumDistance minimumFontSize minimumFractionDigits minimumIntegerDigits minimumInteritemSpacing minimumLineHeight minimumLineSpacing minimumLinearLimit minimumNumberOfPeers minimumNumberOfTouches minimumPressDuration minimumPrimaryColumnWidth minimumQuantity minimumQuantityForSource minimumRadius minimumRangeOfUnit minimumRating minimumRelativeValue minimumScaleFactor minimumSignificantDigits minimumTrackImageForState minimumTrackTintColor minimumTrackingAdjustment minimumValue minimumValueImage minimumValueImageRectForBounds minimumVolumeSliderImageForState minimumZ minimumZoomScale minor minusHashTable minusOrderedSet minusSet minusSign minute minuteInterval minuteUnit mipFilter mipmapLevelCount mirrored mirroredScreen mirroringSupported miterLimit mobileCountryCode mobileNetworkCode modalInPopover modalPresentationCapturesStatusBarAppearance modalPresentationStyle modalTransitionStyle modalViewController mode model modelByMergingModels modelConfiguration modelID modelIdentifierForElementAtIndexPath modelLayer modelNumber modelTransform modelviewMatrix modelviewMatrixprojectionMatrix modificationDate modifierFlags modifyBadgeCompletionBlock modifyPixelDataWithBlock modifyRecordZonesCompletionBlock modifyRecordsCompletionBlock modifySubscriptionsCompletionBlock module moleUnitWithMetricPrefix moleUnitWithMolarMass momentary monitoredRegions month monthSymbols monthsOfTheYear moreComing moreNavigationController morpher motion motionBegan motionCancelled motionEffects motionEnded motorMaximumForce motorMaximumTorque motorTargetAngularVelocity motorTargetLinearVelocity mountedVolumeURLsIncludingResourceValuesForKeys mouthPosition mov moveAssetsAtIndexes moveBy moveByX moveChildCollectionsAtIndexes moveInWithDirection moveItemAtIndexPath moveItemAtPath moveItemAtURL moveObjectsAtIndexes movePath moveRowAtIndexPath moveSection moveTo moveToPoint moveToX moveToY movieFragmentInterval movieMediaTypes moviePlayer movieSourceType movieTimeScale mp3 mp4 multiThreaded multipleSelectionBackgroundView multipleTouchEnabled multiplier multiply multiplyByInverseOfAttitude multitaskingSupported musicSequence mutableArrayValueForKey mutableArrayValueForKeyPath mutableAudioBufferList mutableBytes mutableCopyWithZone mutableOrderedSetValueForKey mutableOrderedSetValueForKeyPath mutableSetValueForKey mutableSetValueForKeyPath mutableString mutableTextureWithSize mutableTrackCompatibleWithTrack muted myPeerID name nameForInputBus nameForOutputBus nanosecond nativeBounds nativeScale naturalLanguageQuery naturalSize naturalTimeScale navigationBar navigationBarHidden navigationController navigationControllerPreferredInterfaceOrientationForPresentation navigationControllerSupportedInterfaceOrientations navigationDelegate navigationItem navigationOrientation navigationType nearbyConnectionDataForPeer needsDisplay needsDisplayForKey needsDisplayOnBoundsChange needsLayout needsSave needsToBeUpdatedFromPath needsUpdateConstraints negative negativeFormat negativeInfinitySymbol negativePrefix negativeSuffix netService netServiceBrowser netServiceBrowserDidStopSearch netServiceBrowserWillSearch netServiceDidPublish netServiceDidResolveAddress netServiceDidStop netServiceDomain netServiceName netServiceWillPublish netServiceWillResolve networkAccessAllowed networkActivityIndicatorVisible networkName networkPort networkServiceType newBufferWithBytes newBufferWithBytesNoCopy newBufferWithLength newCacheNodeForManagedObject newCommandQueue newCommandQueueWithMaxCommandBufferCount newComputePipelineStateWithFunction newDefaultLibrary newDepthStencilStateWithDescriptor newDrawable newFunctionWithName newLibraryWithData newLibraryWithFile newLibraryWithSource newObjectIDForEntity newPersonViewController newPersonViewDelegate newPixelBuffer newReferenceObjectForManagedObject newRenderPipelineStateWithDescriptor newSamplerStateWithDescriptor newTextureViewWithPixelFormat newTextureWithDescriptor newValueForRelationship newValuesForObjectWithID newVersionNumber newlineCharacterSet newsstandAssetDownload nextAvailableInputBus nextDateAfterDate nextDaylightSavingTimeTransition nextDaylightSavingTimeTransitionAfterDate nextDrawable nextFrameTime nextLayout nextObject nextResponder nextRoadName nextTimedMetadataGroup nextTrackCommand nextWeekendStartDate nibBundle nibName nibWithData nibWithNibName nilSymbol node nodeA nodeAtPoint nodeB nodeTimeForPlayerTime nodeWithFileNamed nodeWithGeometry nodeWithViewportSize nodesAtPoint noiseFieldWithSmoothness nominalFrameRate nonBaseCharacterSet nonretainedObjectValue normal normalMatrix normalTexture normalizedCoordinates normalizedCropRect norms notANumber notANumberSymbol notPredicateWithSubpredicate notShownAttributeForGlyphAtIndex notes notice notificationBatchingInterval notificationCenterVibrancyEffect notificationChangedBlock notificationEnabled notificationFromRemoteNotificationDictionary notificationID notificationIDs notificationInfo notificationType notificationWithName notifyEntryStateOnDisplay notifyOnEntry notifyOnExit notifyWhenInteractionEndsUsingBlock nowPlayingInfo nowPlayingItem null numParticlesToEmit numberFormatter numberFromString numberOfArguments numberOfAssets numberOfButtons numberOfBytesTransferred numberOfCaptureGroups numberOfChannels numberOfChildItemsAtIndexPath numberOfComponents numberOfComponentsInPickerView numberOfDroppedVideoFrames numberOfGlyphs numberOfInputs numberOfItems numberOfItemsInSection numberOfLines numberOfLoops numberOfMatchesInString numberOfMediaRequests numberOfObjects numberOfOutputs numberOfPages numberOfPreviewItemsInPreviewController numberOfRanges numberOfRows numberOfRowsInComponent numberOfRowsInSection numberOfSections numberOfSectionsInCollectionView numberOfSectionsInTableView numberOfSegments numberOfSegmentsDownloaded numberOfServerAddressChanges numberOfStalls numberOfSteps numberOfTapsRequired numberOfTouches numberOfTouchesRequired numberStyle numberValue numberWithBool numberWithChar numberWithDouble numberWithFloat numberWithInt numberWithInteger numberWithLong numberWithLongLong numberWithShort numberWithUnsignedChar numberWithUnsignedInt numberWithUnsignedInteger numberWithUnsignedLong numberWithUnsignedLongLong numberWithUnsignedShort oalMacOSX_OALExtensions oalStaticBufferExtension oauthToken object objectAfterChanges objectAtIndex objectAtIndexPath objectAtIndexedSubscript objectBeforeChanges objectEnumerator objectForInfoDictionaryKey objectForKey objectForKeyedSubscript objectID objectIDForEntity objectIsForcedForKey objectRegisteredForID objectRestorationClass objectSnapshot objectWasDeleted objectWithID objectWithRestorationIdentifierPath objectZone objects objectsAtIndexes objectsForKeys objectsForType objectsPassingTest objectsWithOptions observationInfo observeValueForKeyPath observedBitrate observedBitrateStandardDeviation observedMaxBitrate observedMinBitrate obstruction obtainPermanentIDsForObjects occlusion occurrenceCount ocean offImage offset offsetFromPosition old oldVersionNumber on onDemandEnabled onDemandRules onImage onResp onTintColor one opacity opaque open openInMapsWithLaunchOptions openMapsWithItems openParentApplication openPaymentSetup openURL openWithCompletionHandler operand operatingSystem operatingSystemName operatingSystemVersion operatingSystemVersionString operationCount operationError operationQueue operations optional options orPredicateWithSubpredicates orangeColor ordered orderedSet orderedSetWithArray orderedSetWithCapacity orderedSetWithObject orderedSetWithObjects orderedSetWithOrderedSet orderedSetWithSet ordinalityOfUnit organizationName organizer orientToNode orientToPoint orientation orientationMode orientationSupported originalAsset originalContentView originalRequest originalTransaction originalURL orthographicScale orthography orthographyAtIndex orthographyCheckingResultWithRange orthographyWithDominantScript otherAudioPlaying otherVersionsOfItemAtURL ounceUnit outerRadius output outputDataSource outputDataSources outputDeviceUniqueID outputFileType outputFileURL outputFormat outputFormatForBus outputImage outputImageMaximumSize outputKeys outputLatency outputMediaDataWillChange outputMeterLevel outputMeteringEnabled outputNode outputNumberOfChannels outputObscuredDueToInsufficientExternalProtection outputSequenceWasFlushed outputSettings outputSettingsAssistantWithPreset outputSettingsForConnection outputStream outputStreamToBuffer outputStreamToFileAtPath outputStreamToMemory outputStreamWithURL outputType outputURL outputVolume outputs overlap overlay overlaySKScene overlays overlaysInLevel overrideOutputAudioPort overrideTraitCollection overrideTraitCollectionForChildViewController overscanCompensation ownerName owningPortUID paddingCharacter paddingPosition pageCount pageIndicatorTintColor pageLength pageViewController pageViewControllerPreferredInterfaceOrientationForPresentation pageViewControllerSupportedInterfaceOrientations paginationBreakingMode paginationMode pagingEnabled pan panGestureRecognizer paperRect paperSize paragraphRangeForRange paragraphSpacing paragraphSpacingBefore parallelRenderCommandEncoderWithDescriptor parameterString parameters parent parentContext parentGroup parentNode parentViewController parse parser parserDidEndDocument parserDidStartDocument parserError partialStringValidationEnabled participantID participantQuitInTurnWithOutcome participantQuitOutOfTurnWithOutcome participantRole participantStatus participantType participants particleAction particleAlpha particleAlphaRange particleAlphaSequence particleAlphaSpeed particleAngle particleAngleVariation particleAngularVelocity particleAngularVelocityVariation particleBirthRate particleBlendMode particleBounce particleBounceVariation particleCharge particleChargeVariation particleColor particleColorAlphaRange particleColorAlphaSpeed particleColorBlendFactor particleColorBlendFactorRange particleColorBlendFactorSequence particleColorBlendFactorSpeed particleColorBlueRange particleColorBlueSpeed particleColorGreenRange particleColorGreenSpeed particleColorRedRange particleColorRedSpeed particleColorSequence particleColorVariation particleDiesOnCollision particleFriction particleFrictionVariation particleImage particleLifeSpan particleLifeSpanVariation particleLifetime particleLifetimeRange particleMass particleMassVariation particlePosition particlePositionRange particleRotation particleRotationRange particleRotationSpeed particleScale particleScaleRange particleScaleSequence particleScaleSpeed particleSize particleSizeVariation particleSpeed particleSpeedRange particleSystem particleSystemNamed particleSystems particleTexture particleVelocity particleVelocityVariation particleZPosition particleZPositionRange particleZPositionSpeed pascalUnit pascalUnitWithMetricPrefix passType passTypeIdentifier passURL passWithPassTypeIdentifier passes passesOfType passthroughTrackID passthroughViews password passwordReference paste pasteboardTypes pasteboardTypesForItemSet pasteboardWithName pasteboardWithUniqueName path pathComponents pathContentOfSymbolicLinkAtPath pathExtension pathForAuxiliaryExecutable pathForResource pathWithComponents pathsForResourcesOfType pathsMatchingExtensions pattern pausable pause pauseAnimationForKey pauseButtonColor pauseCommand pauseDownloads pauseOnWillResignActive pauseRecording pauseSpeakingAtBoundary paused pausesIncomingScene pausesLocationUpdatesAutomatically pausesOutgoingScene pausingHandler payment paymentAuthorizationViewController paymentAuthorizationViewControllerDidFinish paymentAuthorizationViewControllerWillAuthorizePayment paymentData paymentInstrumentName paymentNetwork paymentPass paymentQueue paymentQueueRestoreCompletedTransactionsFinished paymentSummaryItems paymentWithProduct paymentWithProductIdentifier peakHoldLevel peakPowerForChannel peerID peerPickerController peerPickerControllerDidCancel peersWithConnectionState penetrationDistance peoplePickerDelegate peoplePickerNavigationController peoplePickerNavigationControllerDidCancel perMillSymbol perPageContentInsets perRecordCompletionBlock perRecordProgressBlock percentComplete percentEncodedFragment percentEncodedHost percentEncodedPassword percentEncodedPath percentEncodedQuery percentEncodedUser percentSymbol percentUnit perform performActivity performActivityWithOptions performAsynchronousFileAccessUsingBlock performBatchUpdates performBlock performBlockAndWait performChanges performChangesAndWait performCustomValidationForEntityMapping performDefaultHandlingForAuthenticationChallenge performExpiringActivityWithReason performFetch performQuery performRequestWithHandler performSegueWithIdentifier performSelector performSelectorInBackground performSelectorOnMainThread performSystemAnimation performWithoutAnimation performsMultiPassEncodingIfSupported peripheral peripheralDataWithMeasuredPower peripheralDidInvalidateServices peripheralDidUpdateName peripheralDidUpdateRSSI peripheralManager peripheralManagerDidStartAdvertising peripheralManagerDidUpdateState peripheralManagerIsReadyToUpdateSubscribers permissions permittedArrowDirections persistedSnapshot persistence persistent persistentDomainForName persistentDomainNames persistentID persistentIDPropertyForGroupingType persistentIdentifier persistentIdentifierForItemAtURL persistentStore persistentStoreCoordinator persistentStoreForURL persistentStoreName persistentStoreOptions persistentStoreTypeForFileType persistentStores personViewController personViewDelegate phase phoneNumber phoneNumberCheckingResultWithRange photoLibraryDidChange physicsBody physicsField physicsShape physicsWorld pickerView pinColor pinchGestureRecognizer pinned pintImperialUnit pintUSUnit pipe pipeRadius pipeSegmentCount pitch pitchEnabled pitchMultiplier pivot pixelAspectRatio pixelBufferPool pixelFormat pixelHeight pixelWidth placeholder placeholderCompletedAchievementImage placeholderForCreatedAsset placeholderForCreatedAssetCollection placeholderForCreatedCollectionList placeholderItem placeholderRectForBounds placeholderURLForURL placemark planeWithWidth play playAtTime playButtonColor playCommand playCount playInputClick playPrerollAdWithCompletionHandler playSoundFileNamed playable playableContentManager playableDuration playableMediaSelectionOptionsFromArray playbackBufferEmpty playbackBufferFull playbackDuration playbackLikelyToKeepUp playbackProgress playbackRate playbackSessionID playbackStartDate playbackStartOffset playbackState playbackType player playerAttributes playerGroup playerID playerIDs playerIndex playerItem playerItemWithAsset playerItemWithURL playerLayerWithPlayer playerScope playerStateUpdateHandler playerTimeForNodeTime playerVoiceChatStateDidChangeHandler playerWithPlayerItem playerWithURL players playersToInvite playing playlistAttributes playlistsQuery plugInsEnabled plusSign podcastPersistentID podcastTitle podcastsQuery pointCount pointForCaptureDevicePointOfInterest pointForCoordinate pointForMapPoint pointInside pointOfView pointSize pointerArrayWithOptions pointerArrayWithPointerFunctions pointerAtIndex pointerFunctions pointerFunctionsWithOptions pointerValue pointers points polygon polygonWithCoordinates polygonWithPoints polyline polylineWithCoordinates polylineWithPoints popConfigurationViewController popController popDebugGroup popNavigationItemAnimated popToRootController popToRootViewControllerAnimated popToViewController popViewControllerAnimated popoverArrowDirection popoverBackgroundViewClass popoverContentSize popoverController popoverControllerDidDismissPopover popoverControllerShouldDismissPopover popoverLayoutMargins popoverPresentationController popoverPresentationControllerDidDismissPopover popoverPresentationControllerShouldDismissPopover popoverVisible port portList portName portType portWithMachPort ports poseAsClass position positionAdjustmentForSearchBarIcon positionForBar positionFromPosition positionWithinRange positionX positionY positiveFormat positiveInfinitySymbol positivePrefix positiveSuffix possibleTagsAtIndex possibleTitles postNotification postNotificationName postUtteranceDelay postalCode posterImage postscriptName poundUnit preGain preUtteranceDelay precomposedStringWithCanonicalMapping precomposedStringWithCompatibilityMapping predicate predicateForCategorySamplesWithOperatorType predicateForCompletedRemindersWithCompletionDateStarting predicateForEnablingPerson predicateForEventsWithStartDate predicateForIncompleteRemindersWithDueDateStarting predicateForObjectWithUUID predicateForObjectsFromSource predicateForObjectsFromSources predicateForObjectsFromWorkout predicateForObjectsWithMetadataKey predicateForObjectsWithNoCorrelation predicateForObjectsWithUUIDs predicateForQuantitySamplesWithOperatorType predicateForRemindersInCalendars predicateForSamplesWithStartDate predicateForSelectionOfPerson predicateForSelectionOfProperty predicateForWorkoutsWithOperatorType predicateForWorkoutsWithWorkoutActivityType predicateFormat predicateFromMetadataQueryString predicateOperatorType predicateWithBlock predicateWithFormat predicateWithLeftExpression predicateWithSubstitutionVariables predicateWithValue preferences preferredContentSize preferredContentSizeCategory preferredContentSizeDidChangeForChildContentContainer preferredDataSource preferredDisplayMode preferredFilename preferredFontDescriptorWithTextStyle preferredFontForTextStyle preferredFrameSize preferredFramesPerSecond preferredHardwareSampleRate preferredIOBufferDuration preferredInput preferredInputNumberOfChannels preferredInterfaceOrientationForPresentation preferredIntervals preferredLanguages preferredLayoutAttributesFittingAttributes preferredLocalizations preferredLocalizationsFromArray preferredMaxLayoutWidth preferredMediaCharacteristics preferredMediaChunkAlignment preferredMediaChunkDuration preferredMode preferredOutputNumberOfChannels preferredPeakBitRate preferredPolarPattern preferredPrimaryColumnWidthFraction preferredRate preferredSampleRate preferredStatusBarStyle preferredStatusBarUpdateAnimation preferredStyle preferredTransform preferredUnitsForQuantityTypes preferredVideoStabilizationMode preferredVolume prefersStatusBarHidden preflightAndReturnError preloadTextureAtlases preloadTextures preloadWithCompletionHandler prepare prepareForAnimatedBoundsChange prepareForCollectionViewUpdates prepareForDeletion prepareForDrawingPages prepareForInterfaceBuilder prepareForPopoverPresentation prepareForPresentationInMode prepareForReadingItemsAtURLs prepareForReuse prepareForSegue prepareForTransitionFromLayout prepareForTransitionToLayout prepareInterstitialAds prepareLayout prepareObject prepareObjects preparePrerollAds prepareToCaptureStillImageBracketFromConnection prepareToDraw prepareToPlay prepareToRecord prepareWithActivityItems prepareWithFrameCount prepareWithInvocationTarget preparedURLRequest preprocessorMacros prerollAtRate present presentAnimated presentAtTime presentControllerWithName presentControllerWithNames presentDrawable presentFromBarButtonItem presentFromRect presentFromViewController presentInView presentLocalNotificationNow presentModalViewController presentMoviePlayerViewControllerAnimated presentOpenInMenuFromBarButtonItem presentOpenInMenuFromRect presentOptionsMenuFromBarButtonItem presentOptionsMenuFromRect presentPopoverFromBarButtonItem presentPopoverFromRect presentPreviewAnimated presentRenderbuffer presentScene presentSearchController presentTextInputControllerWithSuggestions presentViewController presentationAnimationDidFinish presentationController presentationControllerForPresentedViewController presentationCountForPageViewController presentationIndexForPageViewController presentationLatency presentationLayer presentationNode presentationSize presentationStyle presentationTransitionDidEnd presentationTransitionWillBegin presentedItemDidChange presentedItemDidGainVersion presentedItemDidLoseVersion presentedItemDidMoveToURL presentedItemDidResolveConflictVersion presentedItemOperationQueue presentedItemURL presentedSubitemAtURL presentedSubitemDidAppearAtURL presentedSubitemDidChangeAtURL presentedView presentedViewController presentingFullScreenAd presentingViewController presentsWithGesture presentsWithTransaction preservesDepth preservesSuperviewLayoutMargins presetName pressed pressedChangedHandler pressure prevents previewController previewControllerDidDismiss previewControllerWillDismiss previewImageHandler previewItemTitle previewItemURL previousFailureCount previousLocationInNode previousLocationInView previousServerChangeToken previousTrackCommand price priceLocale primary primaryAccountIdentifier primaryAccountNumberSuffix primaryColumnWidth primaryHome primaryLanguage primaryPresentedItemURL primaryViewControllerForCollapsingSplitViewController primaryViewControllerForExpandingSplitViewController primitiveCount primitiveType primitiveValueForKey principalClass printFormatter printFormatters printFormattersForPageAtIndex printInfo printInfoWithDictionary printInteractionController printInteractionControllerDidDismissPrinterOptions printInteractionControllerDidFinishJob printInteractionControllerDidPresentPrinterOptions printInteractionControllerParentViewController printInteractionControllerWillDismissPrinterOptions printInteractionControllerWillPresentPrinterOptions printInteractionControllerWillStartJob printPageRenderer printPaper printRect printToPrinter printableRect printableUTIs printer printerID printerPickerController printerPickerControllerDidDismiss printerPickerControllerDidPresent printerPickerControllerDidSelectPrinter printerPickerControllerParentViewController printerPickerControllerWillDismiss printerPickerControllerWillPresent printerPickerControllerWithInitiallySelectedPrinter printerWithURL printingItem printingItems priority privateCloudDatabase privateFrameworksPath privateFrameworksURL probeURL processEditing processEditingForTextStorage processIdentifier processInfo processName processPendingChanges processPool processingFormat processorCount productIdentifier productViewControllerDidFinish products productsRequest program programIsOpaque progress progressHandler progressImage progressTintColor progressViewStyle progressWithTotalUnitCount project projectPoint projectionTransform promisedItemResourceValuesForKeys prompt propagatesDeletesAtEndOfEvent properties propertiesByName propertiesToFetch propertiesToGroupBy propertiesToUpdate property propertyCache propertyControllers propertyForGlyphAtIndex propertyForKey propertyList propertyListForTextStyleRules propertyListFromData propertyListFromStringsFileFormat propertyListWithData propertyListWithStream proposedCredential protectedDataAvailable protectionSpace protocol protocolClasses protocolFamily protocolSpecificInformation protocolString protocolStrings providePlaceholderAtURL providerIdentifier providesPreciseDurationAndTiming providesPresentationContextTransitionStyle province proximity proximityMonitoringEnabled proximitySensingEnabled proximityState proximityUUID proxyType publicCloudDatabase publicID publish publishWithOptions punctuationCharacterSet purpleColor purpose purposeIdentifier pushConfigurationViewController pushControllerWithName pushDebugGroup pushDirection pushNavigationItem pushRegistry pushTokenForType pushViewController pushWithDirection pyramidWithWidth qualityOfService quantity quantitySampleWithType quantityType quantityTypeForIdentifier quantityWithUnit quarter quarterSymbols quaternion query queryActivityStartingFromDate queryActivityWithCompletionHandler queryCompletionBlock queryItemWithName queryItems queryNotificationReason queryPedometerDataFromDate queryPlayerGroupActivity queryStepCountStartingFrom querying queuePlayerWithItems queuePriority quoteCheckingResultWithRange rAddressMode radialGravityField radialSegmentCount radius raise rampToVideoZoomFactor rampingVideoZoom range rangeAtIndex rangeEnclosingPosition rangeOfCharacterFromSet rangeOfComposedCharacterSequenceAtIndex rangeOfComposedCharacterSequencesForRange rangeOfData rangeOfFirstMatchInString rangeOfMisspelledWordInString rangeOfNominallySpacedGlyphsContainingIndex rangeOfString rangeOfUnit rangeOfWeekendStartDate rangeValue rangeWithConstantValue rangeWithLowerLimit rangeWithNoLimits rangeWithUpperLimit rangeWithValue rangedRegions rank rasterizationEnabled rasterizationScale rate rating ratingCommand rayTestWithSegmentFromPoint reachConstraints reachTo reachToNode reachable reactionForce reactionTorque read readAdditionalContentFromURL readDataOfLength readDataToEndOfFile readFromData readFromFileURL readFromURL readInBackgroundAndNotify readInBackgroundAndNotifyForModes readIntoBuffer readMask readOnly readRSSI readToEndOfFileInBackgroundAndNotify readToEndOfFileInBackgroundAndNotifyForModes readValueForCharacteristic readValueForDescriptor readValueWithCompletionHandler readabilityHandler readable readingIntentWithURL readsFromDepthBuffer ready readyForDisplay readyForMoreMediaData realm reason receiptProperties receivedData receivedRealTimeData receivesCredentialSecurely receivingPlayer receivingPlayerID recipient recipientResponseHandler recipients reciprocalUnit reclaimResources recommendedAudioSettingsForAssetWriterWithOutputFileType recommendedVideoSettingsForAssetWriterWithOutputFileType record recordAtTime recordButtonColor recordChangeTag recordChangedBlock recordFetchedBlock recordFields recordForDuration recordID recordIDs recordIDsToDelete recordName recordPermission recordType recordWithIDWasDeletedBlock recordZoneID recordZoneIDs recordZoneIDsToDelete recordZonesToSave recordedDuration recordedFileSize recording recordingPaused recordsToSave recoveryAttempter rect rectForFooterInSection rectForHeaderInSection rectForMapRect rectForMetadataOutputRectOfInterest rectForPageAtIndex rectForRowAtIndexPath rectForSection rectOfInterest recurrence recurrenceCalendar recurrenceEnd recurrenceEndWithEndDate recurrenceEndWithOccurrenceCount recurrenceRules red redColor redRange redSpeed redirect redo redoActionIsDiscardable redoActionName redoMenuItemTitle redoMenuTitleForUndoActionName redoing referenceAction referenceDistance referenceNode referenceObjectForObjectID referenceRestrictions referenceView reflectionFalloffEnd reflectionFalloffStart reflectionResolutionScaleFactor reflective reflectivity refresh refreshControl refreshCurrentPreviewItem refreshObject refreshSourcesIfNecessary refreshing region regionByDifferenceFromRegion regionByIntersectionWithRegion regionByUnionWithRegion regionMonitoringAvailable regionMonitoringEnabled regionOfInterestForImage regionThatFits regionTriggersOnce registerChangeObserver registerClass registerDefaults registerFilterName registerForLocalNotifications registerForRemoteNotificationTypes registerForRemoteNotifications registerImage registerItemForTypeIdentifier registerListener registerNib registerObjectForStateRestoration registerStoreClass registerUndoWithTarget registerUserNotificationSettings registeredObjects registeredStoreTypes registeredTypeIdentifiers regularExpression regularExpressionCheckingResultWithRanges regularExpressionWithPattern regularFile regularFileContents rejectProtectionSpaceAndContinueWithChallenge relation relationshipKeyPathsForPrefetching relationshipMappings relationshipsByName relationshipsWithDestinationEntity relativeAltitude relativeLocation relativeOffset relativePath relativeString releaseDate relevantDate relinquishFunction relinquishPresentedItemToReader relinquishPresentedItemToWriter reload reloadAllComponents reloadComponent reloadConfigurationItems reloadData reloadFromOrigin reloadInputViews reloadItemsAtIndexPaths reloadRootControllersWithNames reloadRowsAtIndexPaths reloadSectionIndexTitles reloadSections rematchWithCompletionHandler reminderWithEventStore remoteControlReceivedWithEvent remoteIdentifier remoteParticipantVolume remotePlayerDidCompleteChallenge removeAccessory removeAccount removeAction removeActionForKey removeActionSet removeAlarm removeAllActions removeAllActionsWithTarget removeAllAnimations removeAllAnnotations removeAllBehaviors removeAllBoundaries removeAllCachedImages removeAllCachedResourceValues removeAllCachedResponses removeAllChildren removeAllImages removeAllIndexes removeAllItems removeAllJoints removeAllModifiers removeAllObjects removeAllParticleSystems removeAllPoints removeAllSegments removeAllServices removeAllURLs removeAllUserScripts removeAndReturnError removeAnimationForKey removeAnnotation removeAnnotations removeAssets removeAssetsAtIndexes removeAttribute removeBehavior removeBoundaryWithIdentifier removeCachedImageWithName removeCachedResourceValueForKey removeCachedResponseForDataTask removeCachedResponseForRequest removeCachedResponsesSinceDate removeCalendar removeCharactersInRange removeCharactersInString removeChildBehavior removeChildCollections removeChildCollectionsAtIndexes removeChildrenInArray removeConnection removeConstraint removeConstraints removeContact removeCookiesSinceDate removeCredential removeDependency removeDictationResultPlaceholder removeEvent removeFileAtPath removeFilePresenter removeFileWrapper removeFilterPredicate removeFromParent removeFromParentNode removeFromParentViewController removeFromPreferencesWithCompletionHandler removeFromPrintPageRenderer removeFromRunLoop removeFromSuperlayer removeFromSuperview removeGestureRecognizer removeHome removeIndex removeIndexes removeIndexesInRange removeInput removeIssue removeItem removeItemAtPath removeItemAtURL removeJoint removeKeyframeAtIndex removeLastKeyframe removeLastObject removeLayoutManager removeManagedReference removeMaterialAtIndex removeModifiersOfStage removeMotionEffect removeObject removeObjectAtIndex removeObjectForKey removeObjectIdenticalTo removeObjectsAtIndexes removeObjectsForKeys removeObjectsFromIndices removeObjectsInArray removeObjectsInRange removeObserver removeOtherVersionsOfItemAtURL removeOutput removeOverlay removeOverlays removeParticleSystem removePass removePasteboardWithName removePersistentDomainForName removePersistentStore removePointerAtIndex removePort removePropertyForKey removeRecurrenceRule removeReminder removeRoom removeRowsAtIndexes removeScriptMessageHandlerForName removeSegmentAtIndex removeService removeServiceGroup removeSubscriber removeSuiteNamed removeTapOnBus removeTarget removeTextContainerAtIndex removeTimeObserver removeTimeRange removeTrack removeTransactionObserver removeTrigger removeUbiquitousContentAndPersistentStoreAtURL removeUniformNamed removeUser removeVolatileDomainForName removeWithCompletionHandler removeZone removedIndexes removedObjects removedOnCompletion removesDuplicateFrames renamingIdentifier render renderAtTime renderCommandEncoder renderCommandEncoderWithDescriptor renderContext renderContextChanged renderInContext renderMode renderNode renderPassDescriptor renderScale renderSize renderTransform renderbufferStorage renderedContentURL renderer rendererDelegate rendererForOverlay rendererWithContext renderingAlgorithm renderingMode renderingOrder renewCredentialsForAccount renewalDate repeatAction repeatActionForever repeatCalendar repeatCount repeatDuration repeatInterval repeatMode replaceAssetsAtIndexes replaceBytesInRange replaceCharactersInRange replaceChildCollectionsAtIndexes replaceChildNode replaceCurrentItemWithPlayerItem replaceItemAtURL replaceMatchesInString replaceMaterialAtIndex replaceObjectAtIndex replaceObjectsAtIndexes replaceObjectsInRange replaceOccurrencesOfString replacePassWithPass replacePointerAtIndex replaceRange replaceRegion replaceSublayer replacementCheckingResultWithRange replacementObjectForCoder replacementObjectForKeyedArchiver replacementString replacementStringForResult replayable replies replyDate replyWithLocalizableMessageKey reportAchievementWithCompletionHandler reportAchievements reportScoreWithCompletionHandler reportScores representationForUTI representativeItem representedElementCategory representedElementKind representsBurst request requestAVAssetForVideo requestAccessForMediaType requestAccessToAccountsWithType requestAccessToEntityType requestAlwaysAuthorization requestApplicationPermission requestAuthorization requestAuthorizationToShareTypes requestCachePolicy requestContentEditingInputWithOptions requestData requestDidFinish requestExportSessionForVideo requestExpression requestForServiceType requestHeaderFieldsWithCookies requestImageDataForAsset requestImageForAsset requestInterstitialAdPresentation requestIsCacheEquivalent requestMediaDataWhenReadyOnQueue requestMethod requestNotificationOfMediaDataChangeWithAdvanceInterval requestPlayerItemForVideo requestRecordPermission requestStateForRegion requestSupplementaryLexiconWithCompletion requestThumbnailImagesAtTimes requestType requestWhenInUseAuthorization requestWithURL requestedLength requestedTimeToleranceAfter requestedTimeToleranceBefore requestsAlternateRoutes requireGestureRecognizerToFail requiredBillingAddressFields requiredContentSizeIdentifiers requiredPixelBufferAttributesForRenderContext requiredShippingAddressFields requiredSourceTrackIDs requiresConstraintBasedLayout requiresFrameReordering requiresSecureCoding reservedSpaceLength reset resetAchievementsWithCompletionHandler resetBytesInRange resetForReadingTimeRanges resetSimulation resetStandardUserDefaults resetSystemTimeZone resetTransform resetWithCompletionHandler resignCurrent resignFirstResponder resignKeyWindow resistance resizableImageWithCapInsets resizableSnapshotViewFromRect resizeByWidth resizeMode resizeToHeight resizeToWidth resizingMode resolve resolveConflictingSavedGames resolveConflicts resolveDepthPlane resolveLevel resolveSlice resolveTexture resolveWithTimeout resolved resourceDataUsingCache resourceLoader resourceOptions resourcePath resourceSpecifier resourceURL resourceValuesForKeys respondToEachPassDescriptionOnQueue respondToRequest respondWithData respondsToSelector response resting restitution restorationClass restorationIdentifier restorationParent restoreCompletedTransactions restoreCompletedTransactionsWithApplicationUsername restoreUserActivityState result resultAtIndex resultByAdjustingRangesWithOffset resultCount resultType results resultsLimit resume resumeAnimationForKey resumeDownloads resumeOnDidBecomeActive resumeRecording retain retainArguments retainWeakReference retainedReferences retainsRegisteredObjects retrieveConnectedPeripherals retrieveConnectedPeripheralsWithServices retrievePeripherals retrievePeripheralsWithIdentifiers returnKeyType returnsDistinctResults returnsObjectsAsFaults reuseIdentifier revealWithDirection reverbBlend reverbParameters reverseGeocodeLocation reverseGeocoder reverseObjectEnumerator reversePlaybackEndTime reverseTransformedValue reversedAction reversedOrderedSet reversedSortDescriptor reversesTitleShadowWhenHighlighted revertAssetContentToOriginal revertToContentsOfURL rewindButtonColor rgbBlendOperation right rightBarButtonItem rightBarButtonItems rightCalloutAccessoryView rightCalloutOffset rightExpression rightEyeClosed rightEyePosition rightShoulder rightThumbstick rightTrigger rightView rightViewMode rightViewRectForBounds ringRadius ringSegmentCount roll rollAngle rollback rollingFriction rolloffFactor room roomForEntireHome rooms rootNode rootResource rootViewController rotateByAngle rotateByX rotateEnabled rotateToAngle rotateToAxisAngle rotateToX rotatingFooterView rotatingHeaderView rotation rotationMatrix rotationMode rotationRate rotationSpeed roundingBehavior roundingIncrement roundingMode routeButtonImageForState routeButtonRectForBounds routes row rowActionWithStyle rowControllerAtIndex rowHeight rowSizeForComponent rssi run runAction runActionForKey runBlock runLoopModes runMode runUntilDate running sAddressMode sampleAtTime sampleBufferCallbackQueue sampleBufferDelegate sampleCount sampleFieldsAt samplePredicates samplePresentationTimeForTrackTime sampleRate sampleReferenceBaseURL sampleTime sampleTimeValid sampleType save saveAccount saveCalendar saveCurrentTurnWithMatchData saveEvent saveGameData saveMergedMatchData saveObject saveObjects savePolicy savePresentedItemChangesWithCompletionHandler saveRecord saveRecordZone saveReminder saveSnapshot saveSubscription saveToPreferencesWithCompletionHandler saveToURL savingFileType scale scaleBy scaleFactor scaleMode scaleRange scaleSpeed scaleTimeRange scaleTo scaleXBy scaleXTo scaleYTo scalesPageToFit scalingMode scanCharactersFromSet scanDecimal scanDouble scanFloat scanForPeripheralsWithServices scanHexDouble scanHexFloat scanHexInt scanHexLongLong scanInt scanInteger scanLocation scanLongLong scanString scanUnsignedLongLong scanUpToCharactersFromSet scanUpToString scannerWithString scene sceneNamed sceneSourceWithData sceneSourceWithURL sceneTime sceneWithOptions sceneWithSize sceneWithURL scheduleBuffer scheduleFile scheduleInRunLoop scheduleLocalNotification scheduleSegment scheduledLocalNotifications scheduledTimerWithTimeInterval scheme scnScene scope scopeBarBackgroundImage scopeBarButtonBackgroundImageForState scopeBarButtonDividerImageForLeftSegmentState scopeBarButtonTitleTextAttributesForState scopeButtonTitles score scores screen screenBounds screenScale screenSpaceRadius screens scrollDirection scrollEnabled scrollIndicatorInsets scrollMode scrollPoint scrollRangeToVisible scrollRectToVisible scrollToItemAtIndexPath scrollToNearestSelectedRowAtScrollPosition scrollToPoint scrollToRect scrollToRowAtIndex scrollToRowAtIndexPath scrollView scrollViewDidEndDecelerating scrollViewDidEndDragging scrollViewDidEndScrollingAnimation scrollViewDidEndZooming scrollViewDidScroll scrollViewDidScrollToTop scrollViewDidZoom scrollViewShouldScrollToTop scrollViewTexturedBackgroundColor scrollViewWillBeginDecelerating scrollViewWillBeginDragging scrollViewWillBeginZooming scrollViewWillEndDragging scrollsToTop searchBar searchBarBookmarkButtonClicked searchBarCancelButtonClicked searchBarResultsListButtonClicked searchBarSearchButtonClicked searchBarShouldBeginEditing searchBarShouldEndEditing searchBarStyle searchBarTextDidBeginEditing searchBarTextDidEndEditing searchContentsController searchDisplayController searchDisplayControllerDidBeginSearch searchDisplayControllerDidEndSearch searchDisplayControllerWillBeginSearch searchDisplayControllerWillEndSearch searchFieldBackgroundImageForState searchFieldBackgroundPositionAdjustment searchForAllDomains searchForBrowsableDomains searchForRegistrationDomains searchForServicesOfType searchItems searchResultsButtonSelected searchResultsController searchResultsDataSource searchResultsDelegate searchResultsTableView searchResultsTitle searchResultsUpdater searchScopes searchTextPositionAdjustment searching second secondAttribute secondItem secondUnit secondUnitWithMetricPrefix secondaryAudioShouldBeSilencedHint secondaryGroupingSize secondsForHostTime secondsFromGMT secondsFromGMTForDate section sectionFooterHeight sectionForObject sectionForSectionIndexTitle sectionForSectionIndexTitleAtIndex sectionHeaderHeight sectionIndexBackgroundColor sectionIndexColor sectionIndexMinimumDisplayRowCount sectionIndexTitleForSectionName sectionIndexTitles sectionIndexTitlesForTableView sectionIndexTrackingBackgroundColor sectionInset sectionNameKeyPath sectionTitles sections secure secureTextEntry securityIdentity seed seedItems seekBackwardCommand seekForwardCommand seekToDate seekToEndOfFile seekToFileOffset seekToTime seekableTimeRanges seekingWaitsForVideoCompositionRendering segmentCount segmentForTrackTime segmentedControlStyle segments segmentsDownloadedDuration segueForUnwindingToViewController segueWithIdentifier select selectAll selectAnnotation selectChallengeablePlayerIDs selectChallengeablePlayers selectItemAtIndexPath selectMediaOption selectMediaOptionAutomaticallyInMediaSelectionGroup selectRow selectRowAtIndexPath selectable selected selectedAnnotations selectedBackgroundView selectedCalendars selectedDataSource selectedImage selectedImageTintColor selectedIndex selectedItem selectedMediaOptionInMediaSelectionGroup selectedPolarPattern selectedPrinter selectedRange selectedRowInComponent selectedScopeButtonIndex selectedSegmentIndex selectedTextColor selectedTextRange selectedViewController selectionAffinity selectionDidChange selectionGranularity selectionIndicatorImage selectionRectsForRange selectionStyle selectionWillChange selector selfContained semantic semanticForSymbol sendAction sendActionsForControlEvents sendAsynchronousRequest sendBeforeDate sendController sendData sendDataToAllPeers sendDataToAllPlayers sendDate sendEvent sendExchangeToParticipants sendMIDIEvent sendMIDISysExEvent sendPitchBend sendPressure sendPressureForKey sendProgramChange sendReminderToParticipants sendResourceAtURL sendSubviewToBack sendSynchronousRequest sender sentenceRangeForRange separateSecondaryViewControllerForSplitViewController separatorColor separatorEffect separatorInset separatorStyle sequence serialNumber serializedRepresentation serializedXMPFromFilters serverAddress serverCertificateCommonName serverCertificateIssuerCommonName serverTrust service serviceGroups serviceType services servicesWithTypes session sessionDescription sessionID sessionMode sessionOnly sessionPreset sessionSendsLaunchEvents sessionWithConfiguration set setAbbreviationDictionary setAccessibilityHint setAccessibilityImageRegions setAccessibilityLabel setAccessibilityTraits setAccessibilityValue setActionIsDiscardable setActionName setActions setActive setAffineTransform setAlpha setAngle setAnimationBeginsFromCurrentState setAnimationCurve setAnimationDelay setAnimationDelegate setAnimationDidStopSelector setAnimationDuration setAnimationRepeatAutoreverses setAnimationRepeatCount setAnimationStartDate setAnimationTimingFunction setAnimationTransition setAnimationWillStartSelector setAnimationsEnabled setArgument setArray setAssetsFilter setAttachmentSize setAttribute setAttributedString setAttributedText setAttributedTitle setAttributes setAuthorization setBackButtonBackgroundImage setBackButtonBackgroundVerticalPositionAdjustment setBackButtonTitlePositionAdjustment setBackgroundColor setBackgroundImage setBackgroundImageData setBackgroundImageNamed setBackgroundVerticalPositionAdjustment setBaseWritingDirection setBccRecipients setBlendColorRed setBool setBoundingBoxMin setBuffer setBufferOffset setBuffers setByAddingObject setByAddingObjectsFromArray setByAddingObjectsFromSet setBytes setCalendar setCamera setCategory setCcRecipients setCenterCoordinate setClass setClassName setCollectionViewLayout setColor setCompletionBlock setComputePipelineState setContentCompressionResistancePriority setContentHuggingPriority setContentOffset setContentPositionAdjustment setContentViewController setCookie setCookies setCoordinate setCornerRadius setCredential setCropRectangle setCropRectangleRampFromStartCropRectangle setCullMode setCurrentContext setData setDataReceiveHandler setDate setDecrementImage setDefaultBehavior setDefaultCredential setDefaultFormatterBehavior setDefaultLeaderboard setDefaultLeaderboardCategoryID setDefaultLeaderboardIdentifier setDefaultTimeZone setDefaults setDelegate setDelegateQueue setDepthBias setDepthStencilState setDesiredConnectionLatency setDestination setDictionary setDisableActions setDividerImage setDouble setDragState setDrawsOutsideLineFragment setEditing setEnabled setEntities setExposureModeCustomWithDuration setExposureTargetBias setExtraLineFragmentRect setFetchRequestTemplate setFill setFinishedSelectedImage setFloat setFocusModeLockedWithLensPosition setFragmentBuffer setFragmentBufferOffset setFragmentBuffers setFragmentBytes setFragmentSamplerState setFragmentSamplerStates setFragmentTexture setFragmentTextures setFrontFacingWinding setFullscreen setGlyphs setHTTPShouldHandleCookies setHasContent setHeight setHidden setHidesBackButton setHighlighted setHighlightedItemForProperty setHostedPlayer setHostedPlayerReady setIgnoredWords setImage setImageData setImageNamed setIncrementImage setInitialText setInputDataSource setInputGain setInteger setIsAccessibilityElement setItems setKeepAliveTimeout setKeyframeTime setKeyframeValue setKeys setLeftBarButtonItem setLeftBarButtonItems setLineDash setLineFragmentRect setLocalizableMessageWithKey setLocalizedDateFormatFromTemplate setLocation setLongLong setMagnification setMarkedText setMaxAllowedRotationAngle setMaximumTrackImage setMaximumVolumeSliderImage setMediaSelectionCriteria setMenuVisible setMessage setMessageBody setMetadata setMetadataObjectsDelegate setMinimumBackgroundFetchInterval setMinimumTrackImage setMinimumVolumeSliderImage setMode setMute setNavigationBarHidden setNeedsDisplay setNeedsDisplayInMapRect setNeedsDisplayInRect setNeedsLayout setNeedsStatusBarAppearanceUpdate setNeedsUpdateConstraints setNewsstandIconImage setNilValueForKey setNotShownAttribute setNotifyValue setNumberOfRows setNumberOfSteps setObject setObjectZone setOn setOpacity setOpacityRampFromStartOpacity setOrthography setOutputAudioUnit setOutputDataSource setOutputSettings setOverrideTraitCollection setPersistentDomain setPlayer setPopoverContentSize setPositionAdjustment setPositions setPreferredDataSource setPreferredHardwareSampleRate setPreferredIOBufferDuration setPreferredInput setPreferredInputNumberOfChannels setPreferredOutputNumberOfChannels setPreferredPolarPattern setPreferredSampleRate setPrimitiveValue setProgress setProjectionTransform setProperty setProtocolSpecificInformation setPurgeableState setQueueWithItemCollection setQueueWithQuery setRate setRegion setRenderPipelineState setRepresentation setRequiresSecureCoding setResourceData setResourceValue setResourceValues setResponseSerializer setReturnValue setRightBarButtonItem setRightBarButtonItems setRouteButtonImage setRowTypes setSampleBufferDelegate setSamplerState setSamplerStates setScale setScissorRect setScopeBarButtonBackgroundImage setScopeBarButtonDividerImage setScopeBarButtonTitleTextAttributes setSearchFieldBackgroundImage setSelected setSemantic setSessionWithNoConnection setSet setShadowImage setSharedURLCache setShowsCancelButton setSource setStatusBarHidden setStatusBarOrientation setStatusBarStyle setSteeringAngle setStencilReferenceValue setString setStroke setSubject setTXTRecordData setTargetOffsetFromCenter setTargetRect setTemporaryResourceValue setText setTextColor setTextContainer setTexture setTextures setThreadPriority setThreadgroupMemoryLength setThumbImage setTimeZone setTimeoutInterval setTintColor setTitle setTitleColor setTitlePositionAdjustment setTitleShadowColor setTitleTextAttributes setTitleVerticalPositionAdjustment setToRecipients setToolbarHidden setToolbarItems setTorchModeOnWithLevel setTransform setTransformRampFromStartTransform setTranslatesAutoresizingMaskIntoConstraints setTranslatesReferenceBoundsIntoBoundaryWithInsets setTranslation setTransportControlsPlaybackMode setTriangleFillMode setURL setUbiquitous setUp setUserInfoObject setUserTrackingMode setValidationPredicates setValue setValueTransformer setValuesForKeysWithDictionary setVersion setVertexBuffer setVertexBufferOffset setVertexBuffers setVertexBytes setVertexSamplerState setVertexSamplerStates setVertexTexture setVertexTextures setVideoAtPath setViewControllers setViewport setVisibilityResultMode setVisibleMapRect setVolatileDomain setVolume setVolumeRampFromStartVolume setVolumeThumbImage setWeek setWeight setWhiteBalanceModeLockedWithDeviceWhiteBalanceGains setWidth setWithArray setWithCapacity setWithObject setWithObjects setWithSet setZoomScale settings settingsForTypes shader shaderModifiers shaderWithFileNamed shaderWithSource shadowBias shadowBlurRadius shadowCastBitMask shadowColor shadowImage shadowImageForToolbarPosition shadowMapSize shadowMode shadowOffset shadowOpacity shadowPath shadowRadius shadowSampleCount shadowedBitMask shapeNodeWithCircleOfRadius shapeNodeWithEllipseInRect shapeNodeWithEllipseOfSize shapeNodeWithPath shapeNodeWithPoints shapeNodeWithRect shapeNodeWithRectOfSize shapeNodeWithSplinePoints shapeWithGeometry shapeWithNode shapeWithPath shapeWithShapes sharedAccelerometer sharedAccessoryManager sharedApplication sharedClient sharedCommandCenter sharedContainerIdentifier sharedContentManager sharedCredentialStorage sharedFrameworksPath sharedFrameworksURL sharedHTTPCookieStorage sharedInstance sharedKeySetForKeys sharedLibrary sharedManager sharedMatchmaker sharedMenuController sharedPhotoLibrary sharedPrintController sharedSecretReference sharedSession sharedSupportPath sharedSupportURL sharedTurnBasedEventHandler sharedURLCache sharegroup shiftIndexesStartingAtIndex shininess shippingAddress shippingMethod shippingMethods shippingType short shortMonthSymbols shortQuarterSymbols shortStandaloneMonthSymbols shortStandaloneQuarterSymbols shortStandaloneWeekdaySymbols shortValue shortWeekdaySymbols shouldArchiveValueForKey shouldAutomaticallyForwardAppearanceMethods shouldAutomaticallyForwardRotationMethods shouldAutoplay shouldAutorotate shouldAutorotateToInterfaceOrientation shouldBadge shouldBeArchived shouldBeRequiredToFailByGestureRecognizer shouldCenterFilter shouldChangeTextInRange shouldCullNonVisibleNodes shouldEnableEffects shouldEnableLimits shouldGroupAccessibilityChildren shouldIndentWhileEditing shouldInvalidateLayoutForBoundsChange shouldInvalidateLayoutForPreferredLayoutAttributes shouldOptimizeForNetworkUse shouldPerformSegueWithIdentifier shouldPresentInFullscreen shouldPresentInterstitialAd shouldProcessNamespaces shouldRasterize shouldRefreshRefetchedObjects shouldRemovePresentersView shouldReportNamespacePrefixes shouldRequireFailureOfGestureRecognizer shouldResolveExternalEntities shouldSendContentAvailable shouldSetDefaultLeaderboard shouldShowBannerForLocallyCompletedChallenge shouldShowBannerForLocallyReceivedChallenge shouldShowBannerForRemotelyCompletedChallenge shouldShowCancelConfirmation shouldShowLinkedPeople show showAnnotations showBannerWithTitle showBluetoothAccessoryPickerWithNameFilter showCGGlyphs showDetailViewController showExistingMatches showFromBarButtonItem showFromRect showFromTabBar showFromToolbar showInView showViewController showingAppNames showingDeleteConfirmation showsBookmarkButton showsBuildings showsCameraControls showsCancelButton showsCloudItems showsCompass showsCompletionBanner showsControlCharacters showsDeviceMovementDisplay showsDoneButton showsDrawCount showsFPS showsFields showsHorizontalScrollIndicator showsInvisibleCharacters showsNodeCount showsNumberOfCopies showsPageRange showsPaperSelectionForLoadedPapers showsPhysics showsPlaybackControls showsPointsOfInterest showsQuadCount showsReorderControl showsRouteButton showsScale showsScopeBar showsSearchResultsButton showsSelectionIndicator showsStatistics showsTouchWhenHighlighted showsUserLocation showsVerticalScrollIndicator showsVolumeSlider showsZoomControls shuffleMode siemenUnit siemenUnitWithMetricPrefix signal signatureWithObjCTypes signedURLRequest significantLocationChangeMonitoringAvailable simulatesAskToBuyInSandbox size sizeForChildContentContainer sizeForNumberOfPages sizeFromBannerContentSizeIdentifier sizeFunction sizeThatFits sizeToFit sizeWithAttributes sizeWithFont skeleton skinner skinnerWithBaseGeometry skipBackwardCommand skipCount skipDescendants skipDescendents skipForwardCommand skipToBeginning skipToNextItem skipToPreviousItem sleepForTimeInterval sleepUntilDate slice smallSystemFontSize smallestEncoding smoothAutoFocusEnabled smoothAutoFocusSupported smoothness snapshot snapshotData snapshotViewAfterScreenUpdates socket socketType songsQuery sortDescriptorWithKey sortDescriptors sortRange sortUsingComparator sortUsingDescriptors sortUsingFunction sortUsingSelector sortWithOptions sortedArrayFromArray sortedArrayHint sortedArrayUsingComparator sortedArrayUsingDescriptors sortedArrayUsingFunction sortedArrayUsingSelector sortedArrayWithOptions sortedCookiesUsingDescriptors sortingMode soundName source sourceAlphaBlendFactor sourceContext sourceEndpoint sourceEntityForEntityMapping sourceEntityName sourceEntityVersionHash sourceExpression sourceFrame sourceFrameByTrackID sourceIdentifier sourceInstancesForEntityMappingNamed sourceModel sourceObject sourcePixelBufferAttributes sourceRGBBlendFactor sourceRect sourceTimeRanges sourceTrackID sourceTrackIDs sourceType sourceURL sourceVideoAverageFrameDuration sourceVideoMinFrameDuration sourceView sourceViewController sourceWithIdentifier sources speakUtterance speaking specular specularColor speechString speechSynthesizer speechUtteranceWithString speechVoices speed speedBy speedFactor speedInKilometersPerHour speedTo spellCheckingResultWithRange spellCheckingType sphereWithRadius spin spinRange spineLocation splat splitViewController splitViewControllerPreferredInterfaceOrientationForPresentation splitViewControllerSupportedInterfaceOrientations spotCutoff spotDirection spotExponent spotInnerAngle spotOuterAngle spreadingAngle springField spriteNodeWithColor spriteNodeWithImageNamed spriteNodeWithTexture ssid stackSize stalenessInterval standaloneMonthSymbols standaloneQuarterSymbols standaloneWeekdaySymbols standard standardUserDefaults standardizedURL start startAccelerometerUpdates startAccelerometerUpdatesToQueue startAccessingSecurityScopedResource startActivityUpdatesToQueue startAdvertising startAdvertisingPeer startAndReturnError startAnimating startAnimatingWithImagesInRange startBrowsingForNearbyPlayersWithHandler startBrowsingForNearbyPlayersWithReachableHandler startBrowsingForPeers startCachingImagesForAssets startContentEditingWithInput startDate startDateComponents startDeviceMotionUpdates startDeviceMotionUpdatesToQueue startDeviceMotionUpdatesUsingReferenceFrame startDownloadingUbiquitousItemAtURL startDownloads startGyroUpdates startGyroUpdatesToQueue startInteractiveTransition startInteractiveTransitionToCollectionViewLayout startLoading startMagnetometerUpdates startMagnetometerUpdatesToQueue startMonitoring startMonitoringForRegion startMonitoringSignificantLocationChanges startMonitoringVisits startNote startOfDayForDate startPage startPedometerUpdatesFromDate startPoint startProgress startProvidingItemAtURL startQuery startRangingBeaconsInRegion startReading startRecordingToOutputFileURL startRelativeAltitudeUpdatesToQueue startRunning startSearchingForNewAccessories startSearchingForUnconfiguredAccessoriesMatchingPredicate startSessionAtSourceTime startStepCountingUpdatesToQueue startStreamWithName startUpdatingHeading startUpdatingLocation startVPNTunnelAndReturnError startVideoCapture startVideoCompositionRequest startVoiceChatWithParticipantID startWirelessControllerDiscoveryWithCompletionHandler startWithCompletionHandler startWithQueue startWriting started startupTime state staticBody stationary statistics statisticsForDate statisticsUpdateHandler status statusBarFrame statusBarHidden statusBarOrientation statusBarOrientationAnimationDuration statusBarStyle statusBarVisibility statusCode statusForApplicationPermission statusOfValueForKey steeringAxis stencilAttachment stencilAttachmentPixelFormat stencilCompareFunction stencilFailureOperation stepByCount stepFunction stepRate stepValue steps stereoPan stillImageStabilizationActive stillImageStabilizationSupported stoneUnit stop stopAccelerometerUpdates stopAccessingSecurityScopedResource stopActivityUpdates stopAdvertising stopAdvertisingPeer stopAnimating stopBrowsingForNearbyPlayers stopBrowsingForPeers stopCachingImagesForAllAssets stopCachingImagesForAssets stopCommand stopDeviceMotionUpdates stopGyroUpdates stopLoading stopMagnetometerUpdates stopMonitoring stopMonitoringForRegion stopMonitoringSignificantLocationChanges stopMonitoringVisits stopNote stopPedometerUpdates stopProvidingItemAtURL stopQuery stopRangingBeaconsInRegion stopRecording stopRelativeAltitudeUpdates stopRequestingMediaData stopRunning stopScan stopSearchingForNewAccessories stopSearchingForUnconfiguredAccessories stopSpeakingAtBoundary stopStepCountingUpdates stopUpdatingHeading stopUpdatingLocation stopVPNTunnel stopVideoCapture stopVoiceChatWithParticipantID stopWirelessControllerDiscovery stopped storagePolicy storeAction storeCachedResponse storeCookies storedInExternalRecord storedValueForKey storyboard storyboardWithName stream streamError streamStatus streamingContentKeyRequestDataForApp strength strengthBy strengthTo stretchFactor stretchableImageWithLeftCapWidth stride strikethroughGlyphRange string stringArrayForKey stringByAbbreviatingWithTildeInPath stringByAddingPercentEncodingWithAllowedCharacters stringByAddingPercentEscapesUsingEncoding stringByAppendingFormat stringByAppendingPathComponent stringByAppendingPathExtension stringByAppendingString stringByDeletingLastPathComponent stringByDeletingPathExtension stringByEvaluatingJavaScriptFromString stringByExpandingTildeInPath stringByFoldingWithOptions stringByPaddingToLength stringByRemovingPercentEncoding stringByReplacingCharactersInRange stringByReplacingMatchesInString stringByReplacingOccurrencesOfString stringByReplacingPercentEscapesUsingEncoding stringByResolvingSymlinksInPath stringByStandardizingPath stringByTrimmingCharactersInSet stringEditedInRange stringEncodingForData stringForKey stringForObjectValue stringFromByteCount stringFromDate stringFromDateComponents stringFromDistance stringFromJoules stringFromKilograms stringFromMeters stringFromNumber stringFromTimeInterval stringFromValue stringRepresentation stringValue stringWithCString stringWithCapacity stringWithCharacters stringWithContentsOfFile stringWithContentsOfURL stringWithFileSystemRepresentation stringWithFormat stringWithString stringWithUTF8String strings stringsByAppendingPaths stroke strokeColor strokeEnd strokePath strokeShader strokeStart strokeTexture strokeWithBlendMode strongObjectsPointerArray strongToStrongObjectsMapTable strongToWeakObjectsMapTable structType structuredLocation style subAdministrativeArea subLocality subThoroughfare subarrayWithRange subdataWithRange subdivisionLevel subentities subentitiesByName subgroups subject subjectAreaChangeMonitoringEnabled sublayerTransform sublayers subpathsAtPath subpathsOfDirectoryAtPath subpredicates subscribed subscribedCentrals subscriber subscriberCellularProvider subscriberCellularProviderDidUpdateNotifier subscriptionID subscriptionIDs subscriptionIDsToDelete subscriptionOptions subscriptionType subscriptionsToSave substringFromIndex substringToIndex substringWithRange subtitle subtype subviews suggestedFilename sumQuantity sumQuantityForSource summaryItemWithLabel superentity superlayer superview supportedEventAvailabilities supportedFileTypes supportedInterfaceOrientations supportedInterfaceOrientationsForWindow supportedJobTypes supportedNetworks supportedPlaybackRates supportedPolarPatterns supportsAVCaptureSessionPreset supportsColor supportsContinuationStreams supportsDuplex supportsFeatureSet supportsRandomAccess supportsSecureCoding supportsURL supportsVideoFieldMode supportsVideoMaxFrameDuration supportsVideoMinFrameDuration supportsVideoMirroring supportsVideoOrientation supportsVideoStabilization suppressesIncrementalRendering suppressesPlayerRendering suspend suspended suspensionCompression suspensionDamping suspensionRestLength suspensionStiffness switchBitrate symbolCharacterSet symbolicLink symbolicLinkDestination symbolicLinkDestinationURL symbolicTraits synchronize synchronizeFile synchronizedLayerWithPlayerItem synchronous systemFontOfSize systemFontSize systemID systemLayoutFittingSizeDidChangeForChildContentContainer systemLayoutSizeFittingSize systemLocale systemMusicPlayer systemName systemSpawnedOnCollision systemSpawnedOnDying systemSpawnedOnLiving systemTimeZone systemUptime systemVersion tAddressMode tabBar tabBarController tabBarControllerPreferredInterfaceOrientationForPresentation tabBarControllerSupportedInterfaceOrientations tabBarItem tabStops table tableFooterView tableHeaderView tableView tag tagAtIndex tagSchemes tagsInRange tailIndent takePicture takeStoredValue takeValue takeValuesFromDictionary tapCount tapHandler target targetContentOffsetForProposedContentOffset targetDisplayModeForActionInSplitViewController targetForAction targetFrame targetNode targetOffsetFromCenterForItem targetPosition targetTransform targetValue targetViewControllerForAction targets task taskDescription taskIdentifier tearDown technique techniqueBySequencingTechniques techniqueWithDictionary temperatureAndTintValuesForDeviceWhiteBalanceGains temporaryDirectoryURLForNewVersionOfItemAtURL temporaryID tensionValues testExample testPerformanceExample text textAlignment textAttributesForNegativeInfinity textAttributesForNegativeValues textAttributesForNil textAttributesForNotANumber textAttributesForPositiveInfinity textAttributesForPositiveValues textAttributesForZero textColor textContainer textContainerChangedGeometry textContainerForGlyphAtIndex textContainerInset textContainers textDidChange textDocumentProxy textEncodingName textField textFieldAtIndex textFieldDidBeginEditing textFieldDidEndEditing textFieldShouldBeginEditing textFieldShouldClear textFieldShouldEndEditing textFieldShouldReturn textFields textForGuidedAccessRestrictionWithIdentifier textInRange textInputContextIdentifier textInputMode textInputView textLabel textMarkupAttributes textRangeFromPosition textRectForBounds textSelector textStorage textStyleRuleWithTextMarkupAttributes textStyleRules textStyleRulesFromPropertyList textStylingAtPosition textStylingResolution textView textViewDidBeginEditing textViewDidChange textViewDidChangeSelection textViewDidEndEditing textViewShouldBeginEditing textViewShouldEndEditing textWillChange textWithString texture texture2DDescriptorWithPixelFormat texture2d0 texture2d0texture2d1 textureByApplyingCIFilter textureByGeneratingNormalMap textureByGeneratingNormalMapWithSmoothness textureCoordinatesWithMappingChannel textureCubeDescriptorWithPixelFormat textureCubeMap textureDataType textureFromNode textureNamed textureNames textureNoiseWithSmoothness textureOrder textureOrigin textureRect textureType textureValue textureVectorNoiseWithSmoothness textureWithCGImage textureWithContentsOfData textureWithContentsOfFile textureWithContentsOfURL textureWithData textureWithImage textureWithImageNamed textureWithRect the thoroughfare thousandSeparator threadDictionary threadExecutionWidth threadPriority threadgroupMemoryAlignment threadgroupMemoryDataSize thumbImageForState thumbRectForBounds thumbTintColor thumbnail thumbnailImageAtTime tileSize time timeInterval timeIntervalSince1970 timeIntervalSinceDate timeIntervalSinceNow timeIntervalSinceReferenceDate timeMapping timeOffset timeRange timeRemaining timeScope timeSinceFirstResume timeSinceLastDraw timeSinceLastResume timeSinceLastUpdate timeStep timeStyle timeWithAudioTimeStamp timeWithHostTime timeWithSampleTime timeZone timeZoneDataVersion timeZoneForSecondsFromGMT timeZoneWithAbbreviation timeZoneWithName timedMetadata timeoutDate timeoutInterval timeoutIntervalForRequest timeoutIntervalForResource timerWithTimeInterval timestamp timingFunction timingFunctions timingMode tintAdjustmentMode tintColor tintColorDidChange title titleColorForState titleEdgeInsets titleForSegmentAtIndex titleForState titleLabel titlePositionAdjustment titlePositionAdjustmentForBarMetrics titlePropertyForGroupingType titleRectForContentRect titleShadowColorForState titleShadowOffset titleTextAttributes titleTextAttributesForState titleVerticalPositionAdjustmentForBarMetrics titleView toArray toBool toDate toDictionary toDouble toInt32 toMany toNumber toObject toObjectOfClass toPoint toRange toRect toSize toString toUInt32 toValue toggleBoldface toggleItalics togglePlayPauseCommand toggleUnderline token tokenizer tolerance toolbar toolbarHidden toolbarItems toolbarsVisibility topCapHeight topItem topLayoutGuide topLeft topRadius topRight topViewController torchActive torchAvailable torchLevel torchMode torusWithRingRadius totalBounds totalCostLimit totalDistance totalEnergyBurned totalUnitCount touchInside touchesBegan touchesCancelled touchesEnded touchesForGestureRecognizer touchesForView touchesForWindow touchesMoved touchesShouldBegin touchesShouldCancelInContentView track trackGroups trackID trackIDs trackImage trackRectForBounds trackTintColor trackWithTrackID tracking trackingFrameCount trackingID tracks tracksWithMediaCharacteristic tracksWithMediaType traitCollection traitCollectionDidChange traitCollectionWithDisplayScale traitCollectionWithHorizontalSizeClass traitCollectionWithTraitsFromCollections traitCollectionWithUserInterfaceIdiom traitCollectionWithVerticalSizeClass transaction transactionDate transactionIdentifier transactionReceipt transactionState transactions transferDuration transform transform3D transformConstraintInWorldSpace transformedMetadataObjectForMetadataObject transformedValue transformedValueClass transient transientAssetCollectionWithAssetFetchResult transientAssetCollectionWithAssets transientCollectionListWithCollections transientCollectionListWithCollectionsFetchResult transitInformationCheckingResultWithRange transitionCoordinator transitionDuration transitionFromView transitionFromViewController transitionProgress transitionStyle transitionWasCancelled transitionWithCIFilter transitionWithView transitioningDelegate translatesAutoresizingMaskIntoConstraints translatesReferenceBoundsIntoBoundary translationInView translucent transparency transparencyMode transparent transportControlsPlaybackMode transportControlsSpeed transportControlsSupported transportType trashItemAtURL triggers trueHeading truncateFileAtOffset truncatedGlyphRangeInLineFragmentForGlyphAtIndex truncationMode tryLock tryLockWhenCondition ttl tubeWithInnerRadius turbulenceFieldWithSmoothness turnBasedMatchmakerDelegate turnBasedMatchmakerViewController turnBasedMatchmakerViewControllerWasCancelled turnIcon twoDigitStartDate type types typingAttributes ubiquityIdentityToken uint8_t unableToSetNilForKey unachievedDescription uname unarchiveObjectWithData unarchiveObjectWithFile unarchiver unarchiverDidFinish unarchiverWillFinish unblockAccessory unconfiguredAccessories underPageBackgroundColor underage underlineGlyphRange underlyingQueue undo undoActionIsDiscardable undoActionName undoManager undoMenuItemTitle undoMenuTitleForUndoActionName undoNestedGroup undoRegistrationEnabled undoing unhide uniformNamed uniformType uniformTypeIdentifier uniformWithName uniforms unionHashTable unionOrderedSet unionSet uniqueID unitDividedByUnit unitFromEnergyFormatterUnit unitFromLengthFormatterUnit unitFromMassFormatterUnit unitFromString unitMultipliedByUnit unitRaisedToPower unitString unitStringFromJoules unitStringFromKilograms unitStringFromMeters unitStringFromValue unitStyle units unitsStyle unknown unknownPersonViewController unknownPersonViewDelegate unlearnWord unload unlock unlockForConfiguration unlockWithCondition unmarkText unprojectPoint unpublish unregisterAllListeners unregisterChangeObserver unregisterClass unregisterForLocalNotifications unregisterForRemoteNotifications unregisterImageWithTraitCollection unregisterListener unresolvedConflictVersionsOfItemAtURL unscheduleFromRunLoop unsignedIntegerValue unusedTrackID up update updateAction updateAssociatedServiceType updateAuthorizationData updateCacheNode updateChangeCount updateChangeCountWithToken updateCollisionPairs updateConstraints updateConstraintsIfNeeded updateCurrentPageDisplay updateFireDate updateFromPath updateInteractiveTransition updateInterval updateItemUsingCurrentState updateMeters updateName updatePrimaryHome updateRecurrence updateSearchResultsForSearchController updateTargetValue updateTimeZone updateUserActivity updateUserActivityState updateValue updateViewConstraints updateWithValues updated updatedObjects updating uploadTaskWithRequest uploadTaskWithStreamedRequest upperAngleLimit upperDistanceLimit upperLimit uppercaseLetterCharacterSet uppercaseString uppercaseStringWithLocale url useApplicationAudioSession useConstantColor useCredential useDNSServers useExtendedAuthentication useLayoutToLayoutNavigationTransitions useStoredAccessor usedRectForTextContainer user userAcceleration userActivity userActivityWasContinued userActivityWillSave userContentController userData userFullName userGrouping userInfo userInput userInteractionEnabled userInteractionNoLongerPermittedForError userInterfaceIdiom userInterfaceLayoutDirection userLocation userLocationVisible userRecordID userRecordIDs userScripts userTrackingMode username users usesAirPlayVideoWhileAirPlayScreenIsActive usesApplicationAudioSession usesBackgroundSession usesEllipsoidalExtent usesEvenOddFillRule usesExternalPlaybackWhileExternalScreenIsActive usesFontLeading usesGroupingSeparator usesMipmaps usesOrthographicProjection usesPreciseCollisionDetection usesSceneTimeBase usesSignificantDigits usesStoreSpecificMigrationManager usesStrongWriteBarrier usesWeakReadAndWriteBarriers vBasicOps vBigNum vDSP vDSP_translate vForce vImage vImage_CVUtilities vImage_Types vImage_Utilities valid validDate validTypes validateContent validateForDelete validateForInsert validateForUpdate validateTrackSegments validateValue validationPredicates validationWarnings value valueAtIndex valueChangedHandler valueExpression valueForAnimatedKey valueForAttribute valueForComponent valueForHTTPHeaderField valueForKey valueForKeyPath valueForPasteboardType valueForProperty valueForPropertyDescription valueForUndefinedKey valueFunction valueListAttributes valueLists valueOfAttribute valuePending valuePointerFunctions valueTransformerForName valueTransformerName valueTransformerNames valueWithBool valueWithBytes valueWithCATransform3D valueWithCGAffineTransform valueWithCGPoint valueWithCGRect valueWithCGSize valueWithCGVector valueWithCMTime valueWithCMTimeMapping valueWithCMTimeRange valueWithDouble valueWithInt32 valueWithJSValueRef valueWithMKCoordinate valueWithMKCoordinateSpan valueWithNewArrayInContext valueWithNewErrorFromMessage valueWithNewObjectInContext valueWithNewRegularExpressionFromPattern valueWithNonretainedObject valueWithNullInContext valueWithObject valueWithPoint valueWithPointer valueWithRange valueWithRect valueWithSCNMatrix4 valueWithSCNVector3 valueWithSCNVector4 valueWithSize valueWithUIEdgeInsets valueWithUIOffset valueWithUInt32 valueWithUndefinedInContext values valuesForAttributes valuesForKeys valuesForPasteboardType variable vecLib vecLibTypes vector vectorCount vectorOps vectorWithCGAffineTransform vectorWithCGPoint vectorWithCGRect vectorWithString vectorWithValues vectorWithX vehicleWithChassisBody velocity velocityFactor velocityFieldWithTexture velocityFieldWithVector velocityInView velocityRange vendorName version versionForClassName versionHash versionHashModifier versionIdentifiers versionOfItemAtURL vertexArguments vertexAttributes vertexDescriptor vertexFunction vertexShader verticalAccuracy verticalAlignmentMode verticalSizeClass veryShortMonthSymbols veryShortStandaloneMonthSymbols veryShortStandaloneWeekdaySymbols veryShortWeekdaySymbols vfp videoAtPathIsCompatibleWithSavedPhotosAlbum videoBinned videoBounds videoComposition videoCompositionCoreAnimationToolWithAdditionalLayer videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayers videoCompositionInstruction videoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack videoCompositionWithPropertiesOfAsset videoEditorController videoEditorControllerDidCancel videoFieldMode videoFieldOfView videoGravity videoHDREnabled videoHDRSupported videoMaxFrameDuration videoMaxScaleAndCropFactor videoMaxZoomFactor videoMaximumDuration videoMinFrameDuration videoMirrored videoNodeWithAVPlayer videoNodeWithVideoFileNamed videoNodeWithVideoURL videoOrientation videoPath videoPreviewLayer videoQuality videoRect videoScaleAndCropFactor videoSettings videoStabilizationEnabled videoStabilizationSupported videoSupportedFrameRateRanges videoTracks videoZoomFactor videoZoomFactorUpscaleThreshold view viewControllerForKey viewControllerForUnwindSegueAction viewControllerWithRestorationIdentifierPath viewControllers viewDidAppear viewDidDisappear viewDidLayoutSubviews viewDidLoad viewDidUnload viewFlipsideBackgroundColor viewForAnnotation viewForBaselineLayout viewForKey viewForOverlay viewForRow viewForZoomingInScrollView viewPrintFormatter viewState viewWillAppear viewWillDisappear viewWillLayoutSubviews viewWillTransitionToSize viewWillUnload viewWithTag viewportSize virtualMachine visibilityResultBuffer visible visibleCells visibleMapRect visibleRect visibleViewController voice voiceChatService voiceChatWithName voiceWithLanguage void volatileDomainForName volatileDomainNames volume volumeSliderRectForBounds volumeThumbImageForState volumeThumbRectForBounds volumeWarningSliderImage vortexField wait waitForDataInBackgroundAndNotify waitForDataInBackgroundAndNotifyForModes waitForDuration waitUntilAllOperationsAreFinished waitUntilCompleted waitUntilDate waitUntilFinished waitUntilScheduled walking wantsDefaultContentAppearance wantsFullScreenLayout wantsIncrementalChangeDetails wantsSoftwareDimming warmupDuration weakObjectsHashTable weakObjectsPointerArray weakToStrongObjectsMapTable weakToWeakObjectsMapTable webServiceURL webView webViewDidFinishLoad webViewDidStartLoad webpageURL week weekNumber weekOfMonth weekOfYear weekday weekdayOrdinal weekdaySymbols weeksOfTheYear weightForTargetAtIndex wetDryMix wheelWithNode wheels whiteBalanceMode whiteColor whitespaceAndNewlineCharacterSet whitespaceCharacterSet widgetController widgetMarginInsetsForProposedMarginInsets widgetPerformUpdateWithCompletionHandler width widthForSegmentAtIndex widthSegmentCount widthTracksTextView willAccessValueForKey willActivate willAnimateFirstHalfOfRotationToInterfaceOrientation willAnimateRotationToInterfaceOrientation willAnimateSecondHalfOfRotationFromInterfaceOrientation willChange willChangeValueForKey willDismissSearchController willMoveFromView willMoveToAnimator willMoveToParentViewController willMoveToSuperview willMoveToWindow willPresentActionSheet willPresentAlertView willPresentSearchController willRemoveCacheNodes willRemoveFromPersistentStoreCoordinator willRemoveSubview willRotateToInterfaceOrientation willSave willTransitionFromLayout willTransitionToState willTransitionToTraitCollection willTurnIntoFault window windowLevel windows windowsLocaleCodeFromLocaleIdentifier wirelessRouteActive wirelessRoutesAvailable workoutActivityType workoutEventWithType workoutEvents workoutType workoutWithActivityType worldCoordinates worldNormal worldSpaceDistance worldTransform wrapS wrapT wrapped wraps write writeAdditionalContent writeBookmarkData writeContents writeData writeFromBuffer writeImageDataToSavedPhotosAlbum writeImageToSavedPhotosAlbum writeJSONObject writeMask writeModifiedImageDataToSavedPhotosAlbum writeModifiedVideoAtPathToSavedPhotosAlbum writePlaceholderAtURL writePropertyList writeToFile writeToURL writeValue writeVideoAtPathToSavedPhotosAlbum writeabilityHandler writesToDepthBuffer writingDirection writingIntentWithURL x xAcceleration xAxis xFov xHeight xScale xSize xSizeySizezSize xcschememanagement y yAcceleration yAxis yFov yScale yaw yawAngle year yearForWeekOfYear yellowColor z zAcceleration zFar zIndex zNear zPosition zRotation zero zeroFormattingBehavior zeroPadsFractionDigits zeroSymbol zoneID zoneName zones zoomBouncing zoomEnabled zoomScale zoomToRect zooming ================================================ FILE: shakefun/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 kongcup Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: shakefun/README.md ================================================ # shakefun 在ios设备中,采集hao123上的搞笑图片或gif,然后通过摇动设备来更换显示的内容。又好玩,又锻炼身体!呵呵 本工程主要使用AFNetworking来访问网络,下载资源;使用SVProgressHUD来显示进度和用户提示。 本工程主要目的在于学习~ ================================================ FILE: shakefun/shakefun/AFNetworking/AFHTTPRequestOperation.h ================================================ // AFHTTPRequestOperation.h // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import "AFURLConnectionOperation.h" NS_ASSUME_NONNULL_BEGIN /** `AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request. */ @interface AFHTTPRequestOperation : AFURLConnectionOperation ///------------------------------------------------ /// @name Getting HTTP URL Connection Information ///------------------------------------------------ /** The last HTTP response received by the operation's connection. */ @property (readonly, nonatomic, strong, nullable) NSHTTPURLResponse *response; /** Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an AFHTTPResponse serializer, which uses the raw data as its response object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed. @warning `responseSerializer` must not be `nil`. Setting a response serializer will clear out any cached value */ @property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; /** An object constructed by the `responseSerializer` from the response and response data. Returns `nil` unless the operation `isFinished`, has a `response`, and has `responseData` with non-zero content length. If an error occurs during serialization, `nil` will be returned, and the `error` property will be populated with the serialization error. */ @property (readonly, nonatomic, strong, nullable) id responseObject; ///----------------------------------------------------------- /// @name Setting Completion Block Success / Failure Callbacks ///----------------------------------------------------------- /** Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed. This method should be overridden in subclasses in order to specify the response object passed into the success block. @param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request. @param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occurred during the request. */ - (void)setCompletionBlockWithSuccess:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; @end NS_ASSUME_NONNULL_END ================================================ FILE: shakefun/shakefun/AFNetworking/AFHTTPRequestOperation.m ================================================ // AFHTTPRequestOperation.m // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFHTTPRequestOperation.h" static dispatch_queue_t http_request_operation_processing_queue() { static dispatch_queue_t af_http_request_operation_processing_queue; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_http_request_operation_processing_queue = dispatch_queue_create("com.alamofire.networking.http-request.processing", DISPATCH_QUEUE_CONCURRENT); }); return af_http_request_operation_processing_queue; } static dispatch_group_t http_request_operation_completion_group() { static dispatch_group_t af_http_request_operation_completion_group; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_http_request_operation_completion_group = dispatch_group_create(); }); return af_http_request_operation_completion_group; } #pragma mark - @interface AFURLConnectionOperation () @property (readwrite, nonatomic, strong) NSURLRequest *request; @property (readwrite, nonatomic, strong) NSURLResponse *response; @end @interface AFHTTPRequestOperation () @property (readwrite, nonatomic, strong) NSHTTPURLResponse *response; @property (readwrite, nonatomic, strong) id responseObject; @property (readwrite, nonatomic, strong) NSError *responseSerializationError; @property (readwrite, nonatomic, strong) NSRecursiveLock *lock; @end @implementation AFHTTPRequestOperation @dynamic response; @dynamic lock; - (instancetype)initWithRequest:(NSURLRequest *)urlRequest { self = [super initWithRequest:urlRequest]; if (!self) { return nil; } self.responseSerializer = [AFHTTPResponseSerializer serializer]; return self; } - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { NSParameterAssert(responseSerializer); [self.lock lock]; _responseSerializer = responseSerializer; self.responseObject = nil; self.responseSerializationError = nil; [self.lock unlock]; } - (id)responseObject { [self.lock lock]; if (!_responseObject && [self isFinished] && !self.error) { NSError *error = nil; self.responseObject = [self.responseSerializer responseObjectForResponse:self.response data:self.responseData error:&error]; if (error) { self.responseSerializationError = error; } } [self.lock unlock]; return _responseObject; } - (NSError *)error { if (_responseSerializationError) { return _responseSerializationError; } else { return [super error]; } } #pragma mark - AFHTTPRequestOperation - (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { // completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-retain-cycles" #pragma clang diagnostic ignored "-Wgnu" self.completionBlock = ^{ if (self.completionGroup) { dispatch_group_enter(self.completionGroup); } dispatch_async(http_request_operation_processing_queue(), ^{ if (self.error) { if (failure) { dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { id responseObject = self.responseObject; if (self.error) { if (failure) { dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(self, self.error); }); } } else { if (success) { dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ success(self, responseObject); }); } } } if (self.completionGroup) { dispatch_group_leave(self.completionGroup); } }); }; #pragma clang diagnostic pop } #pragma mark - AFURLRequestOperation - (void)pause { [super pause]; u_int64_t offset = 0; if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) { offset = [(NSNumber *)[self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey] unsignedLongLongValue]; } else { offset = [(NSData *)[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length]; } NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy]; if ([self.response respondsToSelector:@selector(allHeaderFields)] && [[self.response allHeaderFields] valueForKey:@"ETag"]) { [mutableURLRequest setValue:[[self.response allHeaderFields] valueForKey:@"ETag"] forHTTPHeaderField:@"If-Range"]; } [mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"]; self.request = mutableURLRequest; } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFHTTPRequestOperation *operation = [super copyWithZone:zone]; operation.responseSerializer = [self.responseSerializer copyWithZone:zone]; operation.completionQueue = self.completionQueue; operation.completionGroup = self.completionGroup; return operation; } @end ================================================ FILE: shakefun/shakefun/AFNetworking/AFHTTPRequestOperationManager.h ================================================ // AFHTTPRequestOperationManager.h // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #import #if __IPHONE_OS_VERSION_MIN_REQUIRED #import #else #import #endif #import "AFHTTPRequestOperation.h" #import "AFURLResponseSerialization.h" #import "AFURLRequestSerialization.h" #import "AFSecurityPolicy.h" #import "AFNetworkReachabilityManager.h" #ifndef NS_DESIGNATED_INITIALIZER #if __has_attribute(objc_designated_initializer) #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) #else #define NS_DESIGNATED_INITIALIZER #endif #endif NS_ASSUME_NONNULL_BEGIN /** `AFHTTPRequestOperationManager` encapsulates the common patterns of communicating with a web application over HTTP, including request creation, response serialization, network reachability monitoring, and security, as well as request operation management. ## Subclassing Notes Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass `AFHTTPSessionManager`, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application. For developers targeting iOS 6 or Mac OS X 10.8 or earlier, `AFHTTPRequestOperationManager` may be used to similar effect. ## Methods to Override To change the behavior of all request operation construction for an `AFHTTPRequestOperationManager` subclass, override `HTTPRequestOperationWithRequest:success:failure`. ## Serialization Requests created by an HTTP client will contain default headers and encode parameters according to the `requestSerializer` property, which is an object conforming to ``. Responses received from the server are automatically validated and serialized by the `responseSerializers` property, which is an object conforming to `` ## URL Construction Using Relative Paths For HTTP convenience methods, the request serializer constructs URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`, when provided. If `baseURL` is `nil`, `path` needs to resolve to a valid `NSURL` object using `NSURL +URLWithString:`. Below are a few examples of how `baseURL` and relative paths interact: NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ Also important to note is that a trailing slash will be added to any `baseURL` without one. This would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash. ## Network Reachability Monitoring Network reachability status and change monitoring is available through the `reachabilityManager` property. Applications may choose to monitor network reachability conditions in order to prevent or suspend any outbound requests. See `AFNetworkReachabilityManager` for more details. ## NSSecureCoding & NSCopying Caveats `AFHTTPRequestOperationManager` conforms to the `NSSecureCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. There are a few minor caveats to keep in mind, however: - Archives and copies of HTTP clients will be initialized with an empty operation queue. - NSSecureCoding cannot serialize / deserialize block properties, so an archive of an HTTP client will not include any reachability callback block that may be set. */ @interface AFHTTPRequestOperationManager : NSObject /** The URL used to monitor reachability, and construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods. */ @property (readonly, nonatomic, strong, nullable) NSURL *baseURL; /** Requests created with `requestWithMethod:URLString:parameters:` & `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:` are constructed with a set of default headers using a parameter serialization specified by this property. By default, this is set to an instance of `AFHTTPRequestSerializer`, which serializes query string parameters for `GET`, `HEAD`, and `DELETE` requests, or otherwise URL-form-encodes HTTP message bodies. @warning `requestSerializer` must not be `nil`. */ @property (nonatomic, strong) AFHTTPRequestSerializer * requestSerializer; /** Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to a JSON serializer, which serializes data from responses with a `application/json` MIME type, and falls back to the raw data object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed. @warning `responseSerializer` must not be `nil`. */ @property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; /** The operation queue on which request operations are scheduled and run. */ @property (nonatomic, strong) NSOperationQueue *operationQueue; ///------------------------------- /// @name Managing URL Credentials ///------------------------------- /** Whether request operations should consult the credential storage for authenticating the connection. `YES` by default. @see AFURLConnectionOperation -shouldUseCredentialStorage */ @property (nonatomic, assign) BOOL shouldUseCredentialStorage; /** The credential used by request operations for authentication challenges. @see AFURLConnectionOperation -credential */ @property (nonatomic, strong, nullable) NSURLCredential *credential; ///------------------------------- /// @name Managing Security Policy ///------------------------------- /** The security policy used by created request operations to evaluate server trust for secure connections. `AFHTTPRequestOperationManager` uses the `defaultPolicy` unless otherwise specified. */ @property (nonatomic, strong) AFSecurityPolicy *securityPolicy; ///------------------------------------ /// @name Managing Network Reachability ///------------------------------------ /** The network reachability manager. `AFHTTPRequestOperationManager` uses the `sharedManager` by default. */ @property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager; ///------------------------------- /// @name Managing Callback Queues ///------------------------------- /** The dispatch queue for the `completionBlock` of request operations. If `NULL` (default), the main queue is used. */ #if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong, nullable) dispatch_queue_t completionQueue; #else @property (nonatomic, assign, nullable) dispatch_queue_t completionQueue; #endif /** The dispatch group for the `completionBlock` of request operations. If `NULL` (default), a private dispatch group is used. */ #if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong, nullable) dispatch_group_t completionGroup; #else @property (nonatomic, assign, nullable) dispatch_group_t completionGroup; #endif ///--------------------------------------------- /// @name Creating and Initializing HTTP Clients ///--------------------------------------------- /** Creates and returns an `AFHTTPRequestOperationManager` object. */ + (instancetype)manager; /** Initializes an `AFHTTPRequestOperationManager` object with the specified base URL. This is the designated initializer. @param url The base URL for the HTTP client. @return The newly-initialized HTTP client */ - (instancetype)initWithBaseURL:(nullable NSURL *)url NS_DESIGNATED_INITIALIZER; ///--------------------------------------- /// @name Managing HTTP Request Operations ///--------------------------------------- /** Creates an `AFHTTPRequestOperation`, and sets the response serializers to that of the HTTP client. @param request The request object to be loaded asynchronously during execution of the operation. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the object created from the response data of request. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. */ - (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; ///--------------------------- /// @name Making HTTP Requests ///--------------------------- /** Creates and runs an `AFHTTPRequestOperation` with a `GET` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. @see -HTTPRequestOperationWithRequest:success:failure: */ - (nullable AFHTTPRequestOperation *)GET:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; /** Creates and runs an `AFHTTPRequestOperation` with a `HEAD` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes a single arguments: the request operation. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. @see -HTTPRequestOperationWithRequest:success:failure: */ - (nullable AFHTTPRequestOperation *)HEAD:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(AFHTTPRequestOperation *operation))success failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; /** Creates and runs an `AFHTTPRequestOperation` with a `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. @see -HTTPRequestOperationWithRequest:success:failure: */ - (nullable AFHTTPRequestOperation *)POST:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; /** Creates and runs an `AFHTTPRequestOperation` with a multipart `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. @see -HTTPRequestOperationWithRequest:success:failure: */ - (nullable AFHTTPRequestOperation *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id formData))block success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; /** Creates and runs an `AFHTTPRequestOperation` with a `PUT` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. @see -HTTPRequestOperationWithRequest:success:failure: */ - (nullable AFHTTPRequestOperation *)PUT:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; /** Creates and runs an `AFHTTPRequestOperation` with a `PATCH` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. @see -HTTPRequestOperationWithRequest:success:failure: */ - (nullable AFHTTPRequestOperation *)PATCH:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; /** Creates and runs an `AFHTTPRequestOperation` with a `DELETE` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. @see -HTTPRequestOperationWithRequest:success:failure: */ - (nullable AFHTTPRequestOperation *)DELETE:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; @end NS_ASSUME_NONNULL_END ================================================ FILE: shakefun/shakefun/AFNetworking/AFHTTPRequestOperationManager.m ================================================ // AFHTTPRequestOperationManager.m // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import "AFHTTPRequestOperationManager.h" #import "AFHTTPRequestOperation.h" #import #import #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #import #endif @interface AFHTTPRequestOperationManager () @property (readwrite, nonatomic, strong) NSURL *baseURL; @end @implementation AFHTTPRequestOperationManager + (instancetype)manager { return [[self alloc] initWithBaseURL:nil]; } - (instancetype)init { return [self initWithBaseURL:nil]; } - (instancetype)initWithBaseURL:(NSURL *)url { self = [super init]; if (!self) { return nil; } // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) { url = [url URLByAppendingPathComponent:@""]; } self.baseURL = url; self.requestSerializer = [AFHTTPRequestSerializer serializer]; self.responseSerializer = [AFJSONResponseSerializer serializer]; self.securityPolicy = [AFSecurityPolicy defaultPolicy]; self.reachabilityManager = [AFNetworkReachabilityManager sharedManager]; self.operationQueue = [[NSOperationQueue alloc] init]; self.shouldUseCredentialStorage = YES; return self; } #pragma mark - #ifdef _SYSTEMCONFIGURATION_H #endif - (void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer { NSParameterAssert(requestSerializer); _requestSerializer = requestSerializer; } - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { NSParameterAssert(responseSerializer); _responseSerializer = responseSerializer; } #pragma mark - - (AFHTTPRequestOperation *)HTTPRequestOperationWithHTTPMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError]; if (serializationError) { if (failure) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(nil, serializationError); }); #pragma clang diagnostic pop } return nil; } return [self HTTPRequestOperationWithRequest:request success:success failure:failure]; } - (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; operation.responseSerializer = self.responseSerializer; operation.shouldUseCredentialStorage = self.shouldUseCredentialStorage; operation.credential = self.credential; operation.securityPolicy = self.securityPolicy; [operation setCompletionBlockWithSuccess:success failure:failure]; operation.completionQueue = self.completionQueue; operation.completionGroup = self.completionGroup; return operation; } #pragma mark - - (AFHTTPRequestOperation *)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; } - (AFHTTPRequestOperation *)HEAD:(NSString *)URLString parameters:(id)parameters success:(void (^)(AFHTTPRequestOperation *operation))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters success:^(AFHTTPRequestOperation *requestOperation, __unused id responseObject) { if (success) { success(requestOperation); } } failure:failure]; [self.operationQueue addOperation:operation]; return operation; } - (AFHTTPRequestOperation *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"POST" URLString:URLString parameters:parameters success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; } - (AFHTTPRequestOperation *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id formData))block success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError]; if (serializationError) { if (failure) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(nil, serializationError); }); #pragma clang diagnostic pop } return nil; } AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; } - (AFHTTPRequestOperation *)PUT:(NSString *)URLString parameters:(id)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; } - (AFHTTPRequestOperation *)PATCH:(NSString *)URLString parameters:(id)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; } - (AFHTTPRequestOperation *)DELETE:(NSString *)URLString parameters:(id)parameters success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; } #pragma mark - NSObject - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.operationQueue]; } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSURL *baseURL = [decoder decodeObjectForKey:NSStringFromSelector(@selector(baseURL))]; self = [self initWithBaseURL:baseURL]; if (!self) { return nil; } self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))]; self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))]; [coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))]; [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFHTTPRequestOperationManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL]; HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone]; HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone]; return HTTPClient; } @end ================================================ FILE: shakefun/shakefun/AFNetworking/AFHTTPSessionManager.h ================================================ // AFHTTPSessionManager.h // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #import #if __IPHONE_OS_VERSION_MIN_REQUIRED #import #else #import #endif #import "AFURLSessionManager.h" #ifndef NS_DESIGNATED_INITIALIZER #if __has_attribute(objc_designated_initializer) #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) #else #define NS_DESIGNATED_INITIALIZER #endif #endif /** `AFHTTPSessionManager` is a subclass of `AFURLSessionManager` with convenience methods for making HTTP requests. When a `baseURL` is provided, requests made with the `GET` / `POST` / et al. convenience methods can be made with relative paths. ## Subclassing Notes Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass `AFHTTPSessionManager`, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application. For developers targeting iOS 6 or Mac OS X 10.8 or earlier, `AFHTTPRequestOperationManager` may be used to similar effect. ## Methods to Override To change the behavior of all data task operation construction, which is also used in the `GET` / `POST` / et al. convenience methods, override `dataTaskWithRequest:completionHandler:`. ## Serialization Requests created by an HTTP client will contain default headers and encode parameters according to the `requestSerializer` property, which is an object conforming to ``. Responses received from the server are automatically validated and serialized by the `responseSerializers` property, which is an object conforming to `` ## URL Construction Using Relative Paths For HTTP convenience methods, the request serializer constructs URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`, when provided. If `baseURL` is `nil`, `path` needs to resolve to a valid `NSURL` object using `NSURL +URLWithString:`. Below are a few examples of how `baseURL` and relative paths interact: NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ Also important to note is that a trailing slash will be added to any `baseURL` without one. This would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash. @warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance. */ #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) NS_ASSUME_NONNULL_BEGIN @interface AFHTTPSessionManager : AFURLSessionManager /** The URL used to construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods. */ @property (readonly, nonatomic, strong, nullable) NSURL *baseURL; /** Requests created with `requestWithMethod:URLString:parameters:` & `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:` are constructed with a set of default headers using a parameter serialization specified by this property. By default, this is set to an instance of `AFHTTPRequestSerializer`, which serializes query string parameters for `GET`, `HEAD`, and `DELETE` requests, or otherwise URL-form-encodes HTTP message bodies. @warning `requestSerializer` must not be `nil`. */ @property (nonatomic, strong) AFHTTPRequestSerializer * requestSerializer; /** Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `AFJSONResponseSerializer`. @warning `responseSerializer` must not be `nil`. */ @property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; ///--------------------- /// @name Initialization ///--------------------- /** Creates and returns an `AFHTTPSessionManager` object. */ + (instancetype)manager; /** Initializes an `AFHTTPSessionManager` object with the specified base URL. @param url The base URL for the HTTP client. @return The newly-initialized HTTP client */ - (instancetype)initWithBaseURL:(nullable NSURL *)url; /** Initializes an `AFHTTPSessionManager` object with the specified base URL. This is the designated initializer. @param url The base URL for the HTTP client. @param configuration The configuration used to create the managed session. @return The newly-initialized HTTP client */ - (instancetype)initWithBaseURL:(nullable NSURL *)url sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; ///--------------------------- /// @name Making HTTP Requests ///--------------------------- /** Creates and runs an `NSURLSessionDataTask` with a `GET` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `HEAD` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes a single arguments: the data task. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)HEAD:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task))success failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id formData))block success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `PUT` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `PATCH` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `DELETE` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(nullable void (^)(NSURLSessionDataTask *task, NSError *error))failure; @end NS_ASSUME_NONNULL_END #endif ================================================ FILE: shakefun/shakefun/AFNetworking/AFHTTPSessionManager.m ================================================ // AFHTTPSessionManager.m // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFHTTPSessionManager.h" #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) #import "AFURLRequestSerialization.h" #import "AFURLResponseSerialization.h" #import #import #ifdef _SYSTEMCONFIGURATION_H #import #import #import #import #import #endif #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #import #endif @interface AFHTTPSessionManager () @property (readwrite, nonatomic, strong) NSURL *baseURL; @end @implementation AFHTTPSessionManager @dynamic responseSerializer; + (instancetype)manager { return [[[self class] alloc] initWithBaseURL:nil]; } - (instancetype)init { return [self initWithBaseURL:nil]; } - (instancetype)initWithBaseURL:(NSURL *)url { return [self initWithBaseURL:url sessionConfiguration:nil]; } - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration { return [self initWithBaseURL:nil sessionConfiguration:configuration]; } - (instancetype)initWithBaseURL:(NSURL *)url sessionConfiguration:(NSURLSessionConfiguration *)configuration { self = [super initWithSessionConfiguration:configuration]; if (!self) { return nil; } // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) { url = [url URLByAppendingPathComponent:@""]; } self.baseURL = url; self.requestSerializer = [AFHTTPRequestSerializer serializer]; self.responseSerializer = [AFJSONResponseSerializer serializer]; return self; } #pragma mark - #ifdef _SYSTEMCONFIGURATION_H #endif - (void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer { NSParameterAssert(requestSerializer); _requestSerializer = requestSerializer; } - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { NSParameterAssert(responseSerializer); [super setResponseSerializer:responseSerializer]; } #pragma mark - - (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)HEAD:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters success:^(NSURLSessionDataTask *task, __unused id responseObject) { if (success) { success(task); } } failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id formData))block success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError]; if (serializationError) { if (failure) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(nil, serializationError); }); #pragma clang diagnostic pop } return nil; } __block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:nil completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { if (error) { if (failure) { failure(task, error); } } else { if (success) { success(task, responseObject); } } }]; [task resume]; return task; } - (NSURLSessionDataTask *)PUT:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)PATCH:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure { NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError]; if (serializationError) { if (failure) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(nil, serializationError); }); #pragma clang diagnostic pop } return nil; } __block NSURLSessionDataTask *dataTask = nil; dataTask = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { if (error) { if (failure) { failure(dataTask, error); } } else { if (success) { success(dataTask, responseObject); } } }]; return dataTask; } #pragma mark - NSObject - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.session, self.operationQueue]; } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSURL *baseURL = [decoder decodeObjectOfClass:[NSURL class] forKey:NSStringFromSelector(@selector(baseURL))]; NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"]; if (!configuration) { NSString *configurationIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:@"identifier"]; if (configurationIdentifier) { #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1100) configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:configurationIdentifier]; #else configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:configurationIdentifier]; #endif } } self = [self initWithBaseURL:baseURL sessionConfiguration:configuration]; if (!self) { return nil; } self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))]; self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))]; if ([self.session.configuration conformsToProtocol:@protocol(NSCoding)]) { [coder encodeObject:self.session.configuration forKey:@"sessionConfiguration"]; } else { [coder encodeObject:self.session.configuration.identifier forKey:@"identifier"]; } [coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))]; [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFHTTPSessionManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL sessionConfiguration:self.session.configuration]; HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone]; HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone]; return HTTPClient; } @end #endif ================================================ FILE: shakefun/shakefun/AFNetworking/AFNetworkReachabilityManager.h ================================================ // AFNetworkReachabilityManager.h // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #ifndef NS_DESIGNATED_INITIALIZER #if __has_attribute(objc_designated_initializer) #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) #else #define NS_DESIGNATED_INITIALIZER #endif #endif typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) { AFNetworkReachabilityStatusUnknown = -1, AFNetworkReachabilityStatusNotReachable = 0, AFNetworkReachabilityStatusReachableViaWWAN = 1, AFNetworkReachabilityStatusReachableViaWiFi = 2, }; NS_ASSUME_NONNULL_BEGIN /** `AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces. Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability. See Apple's Reachability Sample Code (https://developer.apple.com/library/ios/samplecode/reachability/) @warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined. */ @interface AFNetworkReachabilityManager : NSObject /** The current network reachability status. */ @property (readonly, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; /** Whether or not the network is currently reachable. */ @property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable; /** Whether or not the network is currently reachable via WWAN. */ @property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN; /** Whether or not the network is currently reachable via WiFi. */ @property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi; ///--------------------- /// @name Initialization ///--------------------- /** Returns the shared network reachability manager. */ + (instancetype)sharedManager; /** Creates and returns a network reachability manager for the specified domain. @param domain The domain used to evaluate network reachability. @return An initialized network reachability manager, actively monitoring the specified domain. */ + (instancetype)managerForDomain:(NSString *)domain; /** Creates and returns a network reachability manager for the socket address. @param address The socket address (`sockaddr_in`) used to evaluate network reachability. @return An initialized network reachability manager, actively monitoring the specified socket address. */ + (instancetype)managerForAddress:(const void *)address; /** Initializes an instance of a network reachability manager from the specified reachability object. @param reachability The reachability object to monitor. @return An initialized network reachability manager, actively monitoring the specified reachability. */ - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER; ///-------------------------------------------------- /// @name Starting & Stopping Reachability Monitoring ///-------------------------------------------------- /** Starts monitoring for changes in network reachability status. */ - (void)startMonitoring; /** Stops monitoring for changes in network reachability status. */ - (void)stopMonitoring; ///------------------------------------------------- /// @name Getting Localized Reachability Description ///------------------------------------------------- /** Returns a localized string representation of the current network reachability status. */ - (NSString *)localizedNetworkReachabilityStatusString; ///--------------------------------------------------- /// @name Setting Network Reachability Change Callback ///--------------------------------------------------- /** Sets a callback to be executed when the network availability of the `baseURL` host changes. @param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`. */ - (void)setReachabilityStatusChangeBlock:(nullable void (^)(AFNetworkReachabilityStatus status))block; @end ///---------------- /// @name Constants ///---------------- /** ## Network Reachability The following constants are provided by `AFNetworkReachabilityManager` as possible network reachability statuses. enum { AFNetworkReachabilityStatusUnknown, AFNetworkReachabilityStatusNotReachable, AFNetworkReachabilityStatusReachableViaWWAN, AFNetworkReachabilityStatusReachableViaWiFi, } `AFNetworkReachabilityStatusUnknown` The `baseURL` host reachability is not known. `AFNetworkReachabilityStatusNotReachable` The `baseURL` host cannot be reached. `AFNetworkReachabilityStatusReachableViaWWAN` The `baseURL` host can be reached via a cellular connection, such as EDGE or GPRS. `AFNetworkReachabilityStatusReachableViaWiFi` The `baseURL` host can be reached via a Wi-Fi connection. ### Keys for Notification UserInfo Dictionary Strings that are used as keys in a `userInfo` dictionary in a network reachability status change notification. `AFNetworkingReachabilityNotificationStatusItem` A key in the userInfo dictionary in a `AFNetworkingReachabilityDidChangeNotification` notification. The corresponding value is an `NSNumber` object representing the `AFNetworkReachabilityStatus` value for the current reachability status. */ ///-------------------- /// @name Notifications ///-------------------- /** Posted when network reachability changes. This notification assigns no notification object. The `userInfo` dictionary contains an `NSNumber` object under the `AFNetworkingReachabilityNotificationStatusItem` key, representing the `AFNetworkReachabilityStatus` value for the current network reachability. @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (`Prefix.pch`). */ extern NSString * const AFNetworkingReachabilityDidChangeNotification; extern NSString * const AFNetworkingReachabilityNotificationStatusItem; ///-------------------- /// @name Functions ///-------------------- /** Returns a localized string representation of an `AFNetworkReachabilityStatus` value. */ extern NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status); NS_ASSUME_NONNULL_END ================================================ FILE: shakefun/shakefun/AFNetworking/AFNetworkReachabilityManager.m ================================================ // AFNetworkReachabilityManager.m // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFNetworkReachabilityManager.h" #import #import #import #import #import NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change"; NSString * const AFNetworkingReachabilityNotificationStatusItem = @"AFNetworkingReachabilityNotificationStatusItem"; typedef void (^AFNetworkReachabilityStatusBlock)(AFNetworkReachabilityStatus status); typedef NS_ENUM(NSUInteger, AFNetworkReachabilityAssociation) { AFNetworkReachabilityForAddress = 1, AFNetworkReachabilityForAddressPair = 2, AFNetworkReachabilityForName = 3, }; NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusNotReachable: return NSLocalizedStringFromTable(@"Not Reachable", @"AFNetworking", nil); case AFNetworkReachabilityStatusReachableViaWWAN: return NSLocalizedStringFromTable(@"Reachable via WWAN", @"AFNetworking", nil); case AFNetworkReachabilityStatusReachableViaWiFi: return NSLocalizedStringFromTable(@"Reachable via WiFi", @"AFNetworking", nil); case AFNetworkReachabilityStatusUnknown: default: return NSLocalizedStringFromTable(@"Unknown", @"AFNetworking", nil); } } static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) { BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0); BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0); BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)); BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0); BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction)); AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown; if (isNetworkReachable == NO) { status = AFNetworkReachabilityStatusNotReachable; } #if TARGET_OS_IPHONE else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) { status = AFNetworkReachabilityStatusReachableViaWWAN; } #endif else { status = AFNetworkReachabilityStatusReachableViaWiFi; } return status; } static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); AFNetworkReachabilityStatusBlock block = (__bridge AFNetworkReachabilityStatusBlock)info; if (block) { block(status); } dispatch_async(dispatch_get_main_queue(), ^{ NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; NSDictionary *userInfo = @{ AFNetworkingReachabilityNotificationStatusItem: @(status) }; [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:userInfo]; }); } static const void * AFNetworkReachabilityRetainCallback(const void *info) { return Block_copy(info); } static void AFNetworkReachabilityReleaseCallback(const void *info) { if (info) { Block_release(info); } } @interface AFNetworkReachabilityManager () @property (readwrite, nonatomic, strong) id networkReachability; @property (readwrite, nonatomic, assign) AFNetworkReachabilityAssociation networkReachabilityAssociation; @property (readwrite, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; @property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock; @end @implementation AFNetworkReachabilityManager + (instancetype)sharedManager { static AFNetworkReachabilityManager *_sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ struct sockaddr_in address; bzero(&address, sizeof(address)); address.sin_len = sizeof(address); address.sin_family = AF_INET; _sharedManager = [self managerForAddress:&address]; }); return _sharedManager; } + (instancetype)managerForDomain:(NSString *)domain { SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]); AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability]; manager.networkReachabilityAssociation = AFNetworkReachabilityForName; return manager; } + (instancetype)managerForAddress:(const void *)address { SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address); AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability]; manager.networkReachabilityAssociation = AFNetworkReachabilityForAddress; return manager; } - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability { self = [super init]; if (!self) { return nil; } self.networkReachability = CFBridgingRelease(reachability); self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown; return self; } - (instancetype)init NS_UNAVAILABLE { return nil; } - (void)dealloc { [self stopMonitoring]; } #pragma mark - - (BOOL)isReachable { return [self isReachableViaWWAN] || [self isReachableViaWiFi]; } - (BOOL)isReachableViaWWAN { return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWWAN; } - (BOOL)isReachableViaWiFi { return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWiFi; } #pragma mark - - (void)startMonitoring { [self stopMonitoring]; if (!self.networkReachability) { return; } __weak __typeof(self)weakSelf = self; AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) { __strong __typeof(weakSelf)strongSelf = weakSelf; strongSelf.networkReachabilityStatus = status; if (strongSelf.networkReachabilityStatusBlock) { strongSelf.networkReachabilityStatusBlock(status); } }; id networkReachability = self.networkReachability; SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL}; SCNetworkReachabilitySetCallback((__bridge SCNetworkReachabilityRef)networkReachability, AFNetworkReachabilityCallback, &context); SCNetworkReachabilityScheduleWithRunLoop((__bridge SCNetworkReachabilityRef)networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); switch (self.networkReachabilityAssociation) { case AFNetworkReachabilityForName: break; case AFNetworkReachabilityForAddress: case AFNetworkReachabilityForAddressPair: default: { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{ SCNetworkReachabilityFlags flags; SCNetworkReachabilityGetFlags((__bridge SCNetworkReachabilityRef)networkReachability, &flags); AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); dispatch_async(dispatch_get_main_queue(), ^{ callback(status); NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }]; }); }); } break; } } - (void)stopMonitoring { if (!self.networkReachability) { return; } SCNetworkReachabilityUnscheduleFromRunLoop((__bridge SCNetworkReachabilityRef)self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); } #pragma mark - - (NSString *)localizedNetworkReachabilityStatusString { return AFStringFromNetworkReachabilityStatus(self.networkReachabilityStatus); } #pragma mark - - (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block { self.networkReachabilityStatusBlock = block; } #pragma mark - NSKeyValueObserving + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { if ([key isEqualToString:@"reachable"] || [key isEqualToString:@"reachableViaWWAN"] || [key isEqualToString:@"reachableViaWiFi"]) { return [NSSet setWithObject:@"networkReachabilityStatus"]; } return [super keyPathsForValuesAffectingValueForKey:key]; } @end ================================================ FILE: shakefun/shakefun/AFNetworking/AFNetworking.h ================================================ // AFNetworking.h // // Copyright (c) 2013 AFNetworking (http://afnetworking.com/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #ifndef _AFNETWORKING_ #define _AFNETWORKING_ #import "AFURLRequestSerialization.h" #import "AFURLResponseSerialization.h" #import "AFSecurityPolicy.h" #import "AFNetworkReachabilityManager.h" #import "AFURLConnectionOperation.h" #import "AFHTTPRequestOperation.h" #import "AFHTTPRequestOperationManager.h" #if ( ( defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || \ ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 ) ) #import "AFURLSessionManager.h" #import "AFHTTPSessionManager.h" #endif #endif /* _AFNETWORKING_ */ ================================================ FILE: shakefun/shakefun/AFNetworking/AFSecurityPolicy.h ================================================ // AFSecurityPolicy.h // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import typedef NS_ENUM(NSUInteger, AFSSLPinningMode) { AFSSLPinningModeNone, AFSSLPinningModePublicKey, AFSSLPinningModeCertificate, }; /** `AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. */ NS_ASSUME_NONNULL_BEGIN @interface AFSecurityPolicy : NSObject /** The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`. */ @property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode; /** The certificates used to evaluate server trust according to the SSL pinning mode. By default, this property is set to any (`.cer`) certificates included in the app bundle. Note that if you create an array with duplicate certificates, the duplicate certificates will be removed. Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches. */ @property (nonatomic, strong, nullable) NSArray *pinnedCertificates; /** Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`. */ @property (nonatomic, assign) BOOL allowInvalidCertificates; /** Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`. */ @property (nonatomic, assign) BOOL validatesDomainName; ///----------------------------------------- /// @name Getting Specific Security Policies ///----------------------------------------- /** Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys. @return The default security policy. */ + (instancetype)defaultPolicy; ///--------------------- /// @name Initialization ///--------------------- /** Creates and returns a security policy with the specified pinning mode. @param pinningMode The SSL pinning mode. @return A new security policy. */ + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode; ///------------------------------ /// @name Evaluating Server Trust ///------------------------------ /** Whether or not the specified server trust should be accepted, based on the security policy. This method should be used when responding to an authentication challenge from a server. @param serverTrust The X.509 certificate trust of the server. @return Whether or not to trust the server. @warning This method has been deprecated in favor of `-evaluateServerTrust:forDomain:`. */ - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust DEPRECATED_ATTRIBUTE; /** Whether or not the specified server trust should be accepted, based on the security policy. This method should be used when responding to an authentication challenge from a server. @param serverTrust The X.509 certificate trust of the server. @param domain The domain of serverTrust. If `nil`, the domain will not be validated. @return Whether or not to trust the server. */ - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(nullable NSString *)domain; @end NS_ASSUME_NONNULL_END ///---------------- /// @name Constants ///---------------- /** ## SSL Pinning Modes The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes. enum { AFSSLPinningModeNone, AFSSLPinningModePublicKey, AFSSLPinningModeCertificate, } `AFSSLPinningModeNone` Do not used pinned certificates to validate servers. `AFSSLPinningModePublicKey` Validate host certificates against public keys of pinned certificates. `AFSSLPinningModeCertificate` Validate host certificates against pinned certificates. */ ================================================ FILE: shakefun/shakefun/AFNetworking/AFSecurityPolicy.m ================================================ // AFSecurityPolicy.m // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFSecurityPolicy.h" #import #if !defined(__IPHONE_OS_VERSION_MIN_REQUIRED) static NSData * AFSecKeyGetData(SecKeyRef key) { CFDataRef data = NULL; __Require_noErr_Quiet(SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data), _out); return (__bridge_transfer NSData *)data; _out: if (data) { CFRelease(data); } return nil; } #endif static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) { #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) return [(__bridge id)key1 isEqual:(__bridge id)key2]; #else return [AFSecKeyGetData(key1) isEqual:AFSecKeyGetData(key2)]; #endif } static id AFPublicKeyForCertificate(NSData *certificate) { id allowedPublicKey = nil; SecCertificateRef allowedCertificate; SecCertificateRef allowedCertificates[1]; CFArrayRef tempCertificates = nil; SecPolicyRef policy = nil; SecTrustRef allowedTrust = nil; SecTrustResultType result; allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate); __Require_Quiet(allowedCertificate != NULL, _out); allowedCertificates[0] = allowedCertificate; tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL); policy = SecPolicyCreateBasicX509(); __Require_noErr_Quiet(SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust), _out); __Require_noErr_Quiet(SecTrustEvaluate(allowedTrust, &result), _out); allowedPublicKey = (__bridge_transfer id)SecTrustCopyPublicKey(allowedTrust); _out: if (allowedTrust) { CFRelease(allowedTrust); } if (policy) { CFRelease(policy); } if (tempCertificates) { CFRelease(tempCertificates); } if (allowedCertificate) { CFRelease(allowedCertificate); } return allowedPublicKey; } static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) { BOOL isValid = NO; SecTrustResultType result; __Require_noErr_Quiet(SecTrustEvaluate(serverTrust, &result), _out); isValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); _out: return isValid; } static NSArray * AFCertificateTrustChainForServerTrust(SecTrustRef serverTrust) { CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; for (CFIndex i = 0; i < certificateCount; i++) { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); [trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)]; } return [NSArray arrayWithArray:trustChain]; } static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { SecPolicyRef policy = SecPolicyCreateBasicX509(); CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; for (CFIndex i = 0; i < certificateCount; i++) { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); SecCertificateRef someCertificates[] = {certificate}; CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL); SecTrustRef trust; __Require_noErr_Quiet(SecTrustCreateWithCertificates(certificates, policy, &trust), _out); SecTrustResultType result; __Require_noErr_Quiet(SecTrustEvaluate(trust, &result), _out); [trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)]; _out: if (trust) { CFRelease(trust); } if (certificates) { CFRelease(certificates); } continue; } CFRelease(policy); return [NSArray arrayWithArray:trustChain]; } #pragma mark - @interface AFSecurityPolicy() @property (readwrite, nonatomic, assign) AFSSLPinningMode SSLPinningMode; @property (readwrite, nonatomic, strong) NSArray *pinnedPublicKeys; @end @implementation AFSecurityPolicy + (NSArray *)defaultPinnedCertificates { static NSArray *_defaultPinnedCertificates = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."]; NSMutableArray *certificates = [NSMutableArray arrayWithCapacity:[paths count]]; for (NSString *path in paths) { NSData *certificateData = [NSData dataWithContentsOfFile:path]; [certificates addObject:certificateData]; } _defaultPinnedCertificates = [[NSArray alloc] initWithArray:certificates]; }); return _defaultPinnedCertificates; } + (instancetype)defaultPolicy { AFSecurityPolicy *securityPolicy = [[self alloc] init]; securityPolicy.SSLPinningMode = AFSSLPinningModeNone; return securityPolicy; } + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode { AFSecurityPolicy *securityPolicy = [[self alloc] init]; securityPolicy.SSLPinningMode = pinningMode; [securityPolicy setPinnedCertificates:[self defaultPinnedCertificates]]; return securityPolicy; } - (id)init { self = [super init]; if (!self) { return nil; } self.validatesDomainName = YES; return self; } - (void)setPinnedCertificates:(NSArray *)pinnedCertificates { _pinnedCertificates = [[NSOrderedSet orderedSetWithArray:pinnedCertificates] array]; if (self.pinnedCertificates) { NSMutableArray *mutablePinnedPublicKeys = [NSMutableArray arrayWithCapacity:[self.pinnedCertificates count]]; for (NSData *certificate in self.pinnedCertificates) { id publicKey = AFPublicKeyForCertificate(certificate); if (!publicKey) { continue; } [mutablePinnedPublicKeys addObject:publicKey]; } self.pinnedPublicKeys = [NSArray arrayWithArray:mutablePinnedPublicKeys]; } else { self.pinnedPublicKeys = nil; } } #pragma mark - - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust { return [self evaluateServerTrust:serverTrust forDomain:nil]; } - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain { if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AFSSLPinningModeNone || [self.pinnedCertificates count] == 0)) { // https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html // According to the docs, you should only trust your provided certs for evaluation. // Pinned certificates are added to the trust. Without pinned certificates, // there is nothing to evaluate against. // // From Apple Docs: // "Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors). // Instead, add your own (self-signed) CA certificate to the list of trusted anchors." NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning."); return NO; } NSMutableArray *policies = [NSMutableArray array]; if (self.validatesDomainName) { [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)]; } else { [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()]; } SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); if (self.SSLPinningMode == AFSSLPinningModeNone) { if (self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust)){ return YES; } else { return NO; } } else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { return NO; } NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust); switch (self.SSLPinningMode) { case AFSSLPinningModeNone: default: return NO; case AFSSLPinningModeCertificate: { NSMutableArray *pinnedCertificates = [NSMutableArray array]; for (NSData *certificateData in self.pinnedCertificates) { [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)]; } SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates); if (!AFServerTrustIsValid(serverTrust)) { return NO; } NSUInteger trustedCertificateCount = 0; for (NSData *trustChainCertificate in serverCertificates) { if ([self.pinnedCertificates containsObject:trustChainCertificate]) { trustedCertificateCount++; } } return trustedCertificateCount > 0; } case AFSSLPinningModePublicKey: { NSUInteger trustedPublicKeyCount = 0; NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust); for (id trustChainPublicKey in publicKeys) { for (id pinnedPublicKey in self.pinnedPublicKeys) { if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) { trustedPublicKeyCount += 1; } } } return trustedPublicKeyCount > 0; } } return NO; } #pragma mark - NSKeyValueObserving + (NSSet *)keyPathsForValuesAffectingPinnedPublicKeys { return [NSSet setWithObject:@"pinnedCertificates"]; } @end ================================================ FILE: shakefun/shakefun/AFNetworking/AFURLConnectionOperation.h ================================================ // AFURLConnectionOperation.h // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #import "AFURLRequestSerialization.h" #import "AFURLResponseSerialization.h" #import "AFSecurityPolicy.h" #ifndef NS_DESIGNATED_INITIALIZER #if __has_attribute(objc_designated_initializer) #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) #else #define NS_DESIGNATED_INITIALIZER #endif #endif /** `AFURLConnectionOperation` is a subclass of `NSOperation` that implements `NSURLConnection` delegate methods. ## Subclassing Notes This is the base class of all network request operations. You may wish to create your own subclass in order to implement additional `NSURLConnection` delegate methods (see "`NSURLConnection` Delegate Methods" below), or to provide additional properties and/or class constructors. If you are creating a subclass that communicates over the HTTP or HTTPS protocols, you may want to consider subclassing `AFHTTPRequestOperation` instead, as it supports specifying acceptable content types or status codes. ## NSURLConnection Delegate Methods `AFURLConnectionOperation` implements the following `NSURLConnection` delegate methods: - `connection:didReceiveResponse:` - `connection:didReceiveData:` - `connectionDidFinishLoading:` - `connection:didFailWithError:` - `connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:` - `connection:willCacheResponse:` - `connectionShouldUseCredentialStorage:` - `connection:needNewBodyStream:` - `connection:willSendRequestForAuthenticationChallenge:` If any of these methods are overridden in a subclass, they _must_ call the `super` implementation first. ## Callbacks and Completion Blocks The built-in `completionBlock` provided by `NSOperation` allows for custom behavior to be executed after the request finishes. It is a common pattern for class constructors in subclasses to take callback block parameters, and execute them conditionally in the body of its `completionBlock`. Make sure to handle cancelled operations appropriately when setting a `completionBlock` (i.e. returning early before parsing response data). See the implementation of any of the `AFHTTPRequestOperation` subclasses for an example of this. Subclasses are strongly discouraged from overriding `setCompletionBlock:`, as `AFURLConnectionOperation`'s implementation includes a workaround to mitigate retain cycles, and what Apple rather ominously refers to as ["The Deallocation Problem"](http://developer.apple.com/library/ios/#technotes/tn2109/). ## SSL Pinning Relying on the CA trust model to validate SSL certificates exposes your app to security vulnerabilities, such as man-in-the-middle attacks. For applications that connect to known servers, SSL certificate pinning provides an increased level of security, by checking server certificate validity against those specified in the app bundle. SSL with certificate pinning is strongly recommended for any application that transmits sensitive information to an external webservice. Connections will be validated on all matching certificates with a `.cer` extension in the bundle root. ## NSCoding & NSCopying Conformance `AFURLConnectionOperation` conforms to the `NSCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. However, because of the intrinsic limitations of capturing the exact state of an operation at a particular moment, there are some important caveats to keep in mind: ### NSCoding Caveats - Encoded operations do not include any block or stream properties. Be sure to set `completionBlock`, `outputStream`, and any callback blocks as necessary when using `-initWithCoder:` or `NSKeyedUnarchiver`. - Operations are paused on `encodeWithCoder:`. If the operation was encoded while paused or still executing, its archived state will return `YES` for `isReady`. Otherwise, the state of an operation when encoding will remain unchanged. ### NSCopying Caveats - `-copy` and `-copyWithZone:` return a new operation with the `NSURLRequest` of the original. So rather than an exact copy of the operation at that particular instant, the copying mechanism returns a completely new instance, which can be useful for retrying operations. - A copy of an operation will not include the `outputStream` of the original. - Operation copies do not include `completionBlock`, as it often strongly captures a reference to `self`, which would otherwise have the unintuitive side-effect of pointing to the _original_ operation when copied. */ NS_ASSUME_NONNULL_BEGIN @interface AFURLConnectionOperation : NSOperation ///------------------------------- /// @name Accessing Run Loop Modes ///------------------------------- /** The run loop modes in which the operation will run on the network thread. By default, this is a single-member set containing `NSRunLoopCommonModes`. */ @property (nonatomic, strong) NSSet *runLoopModes; ///----------------------------------------- /// @name Getting URL Connection Information ///----------------------------------------- /** The request used by the operation's connection. */ @property (readonly, nonatomic, strong) NSURLRequest *request; /** The last response received by the operation's connection. */ @property (readonly, nonatomic, strong, nullable) NSURLResponse *response; /** The error, if any, that occurred in the lifecycle of the request. */ @property (readonly, nonatomic, strong, nullable) NSError *error; ///---------------------------- /// @name Getting Response Data ///---------------------------- /** The data received during the request. */ @property (readonly, nonatomic, strong, nullable) NSData *responseData; /** The string representation of the response data. */ @property (readonly, nonatomic, copy, nullable) NSString *responseString; /** The string encoding of the response. If the response does not specify a valid string encoding, `responseStringEncoding` will return `NSUTF8StringEncoding`. */ @property (readonly, nonatomic, assign) NSStringEncoding responseStringEncoding; ///------------------------------- /// @name Managing URL Credentials ///------------------------------- /** Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default. This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`. */ @property (nonatomic, assign) BOOL shouldUseCredentialStorage; /** The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`. This will be overridden by any shared credentials that exist for the username or password of the request URL, if present. */ @property (nonatomic, strong, nullable) NSURLCredential *credential; ///------------------------------- /// @name Managing Security Policy ///------------------------------- /** The security policy used to evaluate server trust for secure connections. */ @property (nonatomic, strong) AFSecurityPolicy *securityPolicy; ///------------------------ /// @name Accessing Streams ///------------------------ /** The input stream used to read data to be sent during the request. This property acts as a proxy to the `HTTPBodyStream` property of `request`. */ @property (nonatomic, strong) NSInputStream *inputStream; /** The output stream that is used to write data received until the request is finished. By default, data is accumulated into a buffer that is stored into `responseData` upon completion of the request, with the intermediary `outputStream` property set to `nil`. When `outputStream` is set, the data will not be accumulated into an internal buffer, and as a result, the `responseData` property of the completed request will be `nil`. The output stream will be scheduled in the network thread runloop upon being set. */ @property (nonatomic, strong, nullable) NSOutputStream *outputStream; ///--------------------------------- /// @name Managing Callback Queues ///--------------------------------- /** The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. */ #if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong, nullable) dispatch_queue_t completionQueue; #else @property (nonatomic, assign, nullable) dispatch_queue_t completionQueue; #endif /** The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. */ #if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong, nullable) dispatch_group_t completionGroup; #else @property (nonatomic, assign, nullable) dispatch_group_t completionGroup; #endif ///--------------------------------------------- /// @name Managing Request Operation Information ///--------------------------------------------- /** The user info dictionary for the receiver. */ @property (nonatomic, strong) NSDictionary *userInfo; // FIXME: It doesn't seem that this userInfo is used anywhere in the implementation. ///------------------------------------------------------ /// @name Initializing an AFURLConnectionOperation Object ///------------------------------------------------------ /** Initializes and returns a newly allocated operation object with a url connection configured with the specified url request. This is the designated initializer. @param urlRequest The request object to be used by the operation connection. */ - (instancetype)initWithRequest:(NSURLRequest *)urlRequest NS_DESIGNATED_INITIALIZER; ///---------------------------------- /// @name Pausing / Resuming Requests ///---------------------------------- /** Pauses the execution of the request operation. A paused operation returns `NO` for `-isReady`, `-isExecuting`, and `-isFinished`. As such, it will remain in an `NSOperationQueue` until it is either cancelled or resumed. Pausing a finished, cancelled, or paused operation has no effect. */ - (void)pause; /** Whether the request operation is currently paused. @return `YES` if the operation is currently paused, otherwise `NO`. */ - (BOOL)isPaused; /** Resumes the execution of the paused request operation. Pause/Resume behavior varies depending on the underlying implementation for the operation class. In its base implementation, resuming a paused requests restarts the original request. However, since HTTP defines a specification for how to request a specific content range, `AFHTTPRequestOperation` will resume downloading the request from where it left off, instead of restarting the original request. */ - (void)resume; ///---------------------------------------------- /// @name Configuring Backgrounding Task Behavior ///---------------------------------------------- /** Specifies that the operation should continue execution after the app has entered the background, and the expiration handler for that background task. @param handler A handler to be called shortly before the application’s remaining background time reaches 0. The handler is wrapped in a block that cancels the operation, and cleans up and marks the end of execution, unlike the `handler` parameter in `UIApplication -beginBackgroundTaskWithExpirationHandler:`, which expects this to be done in the handler itself. The handler is called synchronously on the main thread, thus blocking the application’s suspension momentarily while the application is notified. */ #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) - (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(nullable void (^)(void))handler NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions."); #endif ///--------------------------------- /// @name Setting Progress Callbacks ///--------------------------------- /** Sets a callback to be called when an undetermined number of bytes have been uploaded to the server. @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes three arguments: the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread. */ - (void)setUploadProgressBlock:(nullable void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block; /** Sets a callback to be called when an undetermined number of bytes have been downloaded from the server. @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread. */ - (void)setDownloadProgressBlock:(nullable void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block; ///------------------------------------------------- /// @name Setting NSURLConnection Delegate Callbacks ///------------------------------------------------- /** Sets a block to be executed when the connection will authenticate a challenge in order to download its request, as handled by the `NSURLConnectionDelegate` method `connection:willSendRequestForAuthenticationChallenge:`. @param block A block object to be executed when the connection will authenticate a challenge in order to download its request. The block has no return type and takes two arguments: the URL connection object, and the challenge that must be authenticated. This block must invoke one of the challenge-responder methods (NSURLAuthenticationChallengeSender protocol). If `allowsInvalidSSLCertificate` is set to YES, `connection:willSendRequestForAuthenticationChallenge:` will attempt to have the challenge sender use credentials with invalid SSL certificates. */ - (void)setWillSendRequestForAuthenticationChallengeBlock:(nullable void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block; /** Sets a block to be executed when the server redirects the request from one URL to another URL, or when the request URL changed by the `NSURLProtocol` subclass handling the request in order to standardize its format, as handled by the `NSURLConnectionDataDelegate` method `connection:willSendRequest:redirectResponse:`. @param block A block object to be executed when the request URL was changed. The block returns an `NSURLRequest` object, the URL request to redirect, and takes three arguments: the URL connection object, the the proposed redirected request, and the URL response that caused the redirect. */ - (void)setRedirectResponseBlock:(nullable NSURLRequest * (^)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse))block; /** Sets a block to be executed to modify the response a connection will cache, if any, as handled by the `NSURLConnectionDelegate` method `connection:willCacheResponse:`. @param block A block object to be executed to determine what response a connection will cache, if any. The block returns an `NSCachedURLResponse` object, the cached response to store in memory or `nil` to prevent the response from being cached, and takes two arguments: the URL connection object, and the cached response provided for the request. */ - (void)setCacheResponseBlock:(nullable NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block; /// /** */ + (NSArray *)batchOfRequestOperations:(nullable NSArray *)operations progressBlock:(nullable void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock completionBlock:(nullable void (^)(NSArray *operations))completionBlock; @end ///-------------------- /// @name Notifications ///-------------------- /** Posted when an operation begins executing. */ extern NSString * const AFNetworkingOperationDidStartNotification; /** Posted when an operation finishes. */ extern NSString * const AFNetworkingOperationDidFinishNotification; NS_ASSUME_NONNULL_END ================================================ FILE: shakefun/shakefun/AFNetworking/AFURLConnectionOperation.m ================================================ // AFURLConnectionOperation.m // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFURLConnectionOperation.h" #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #import #endif #if !__has_feature(objc_arc) #error AFNetworking must be built with ARC. // You can turn on ARC for only AFNetworking files by adding -fobjc-arc to the build phase for each of its files. #endif typedef NS_ENUM(NSInteger, AFOperationState) { AFOperationPausedState = -1, AFOperationReadyState = 1, AFOperationExecutingState = 2, AFOperationFinishedState = 3, }; static dispatch_group_t url_request_operation_completion_group() { static dispatch_group_t af_url_request_operation_completion_group; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_url_request_operation_completion_group = dispatch_group_create(); }); return af_url_request_operation_completion_group; } static dispatch_queue_t url_request_operation_completion_queue() { static dispatch_queue_t af_url_request_operation_completion_queue; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_url_request_operation_completion_queue = dispatch_queue_create("com.alamofire.networking.operation.queue", DISPATCH_QUEUE_CONCURRENT ); }); return af_url_request_operation_completion_queue; } static NSString * const kAFNetworkingLockName = @"com.alamofire.networking.operation.lock"; NSString * const AFNetworkingOperationDidStartNotification = @"com.alamofire.networking.operation.start"; NSString * const AFNetworkingOperationDidFinishNotification = @"com.alamofire.networking.operation.finish"; typedef void (^AFURLConnectionOperationProgressBlock)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected); typedef void (^AFURLConnectionOperationAuthenticationChallengeBlock)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge); typedef NSCachedURLResponse * (^AFURLConnectionOperationCacheResponseBlock)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse); typedef NSURLRequest * (^AFURLConnectionOperationRedirectResponseBlock)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse); typedef void (^AFURLConnectionOperationBackgroundTaskCleanupBlock)(); static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { switch (state) { case AFOperationReadyState: return @"isReady"; case AFOperationExecutingState: return @"isExecuting"; case AFOperationFinishedState: return @"isFinished"; case AFOperationPausedState: return @"isPaused"; default: { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunreachable-code" return @"state"; #pragma clang diagnostic pop } } } static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperationState toState, BOOL isCancelled) { switch (fromState) { case AFOperationReadyState: switch (toState) { case AFOperationPausedState: case AFOperationExecutingState: return YES; case AFOperationFinishedState: return isCancelled; default: return NO; } case AFOperationExecutingState: switch (toState) { case AFOperationPausedState: case AFOperationFinishedState: return YES; default: return NO; } case AFOperationFinishedState: return NO; case AFOperationPausedState: return toState == AFOperationReadyState; default: { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunreachable-code" switch (toState) { case AFOperationPausedState: case AFOperationReadyState: case AFOperationExecutingState: case AFOperationFinishedState: return YES; default: return NO; } } #pragma clang diagnostic pop } } @interface AFURLConnectionOperation () @property (readwrite, nonatomic, assign) AFOperationState state; @property (readwrite, nonatomic, strong) NSRecursiveLock *lock; @property (readwrite, nonatomic, strong) NSURLConnection *connection; @property (readwrite, nonatomic, strong) NSURLRequest *request; @property (readwrite, nonatomic, strong) NSURLResponse *response; @property (readwrite, nonatomic, strong) NSError *error; @property (readwrite, nonatomic, strong) NSData *responseData; @property (readwrite, nonatomic, copy) NSString *responseString; @property (readwrite, nonatomic, assign) NSStringEncoding responseStringEncoding; @property (readwrite, nonatomic, assign) long long totalBytesRead; @property (readwrite, nonatomic, copy) AFURLConnectionOperationBackgroundTaskCleanupBlock backgroundTaskCleanup; @property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock uploadProgress; @property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock downloadProgress; @property (readwrite, nonatomic, copy) AFURLConnectionOperationAuthenticationChallengeBlock authenticationChallenge; @property (readwrite, nonatomic, copy) AFURLConnectionOperationCacheResponseBlock cacheResponse; @property (readwrite, nonatomic, copy) AFURLConnectionOperationRedirectResponseBlock redirectResponse; - (void)operationDidStart; - (void)finish; - (void)cancelConnection; @end @implementation AFURLConnectionOperation @synthesize outputStream = _outputStream; + (void)networkRequestThreadEntryPoint:(id)__unused object { @autoreleasepool { [[NSThread currentThread] setName:@"AFNetworking"]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; [runLoop run]; } } + (NSThread *)networkRequestThread { static NSThread *_networkRequestThread = nil; static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ _networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil]; [_networkRequestThread start]; }); return _networkRequestThread; } - (instancetype)initWithRequest:(NSURLRequest *)urlRequest { NSParameterAssert(urlRequest); self = [super init]; if (!self) { return nil; } _state = AFOperationReadyState; self.lock = [[NSRecursiveLock alloc] init]; self.lock.name = kAFNetworkingLockName; self.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes]; self.request = urlRequest; self.shouldUseCredentialStorage = YES; self.securityPolicy = [AFSecurityPolicy defaultPolicy]; return self; } - (instancetype)init NS_UNAVAILABLE { return nil; } - (void)dealloc { if (_outputStream) { [_outputStream close]; _outputStream = nil; } if (_backgroundTaskCleanup) { _backgroundTaskCleanup(); } } #pragma mark - - (void)setResponseData:(NSData *)responseData { [self.lock lock]; if (!responseData) { _responseData = nil; } else { _responseData = [NSData dataWithBytes:responseData.bytes length:responseData.length]; } [self.lock unlock]; } - (NSString *)responseString { [self.lock lock]; if (!_responseString && self.response && self.responseData) { self.responseString = [[NSString alloc] initWithData:self.responseData encoding:self.responseStringEncoding]; } [self.lock unlock]; return _responseString; } - (NSStringEncoding)responseStringEncoding { [self.lock lock]; if (!_responseStringEncoding && self.response) { NSStringEncoding stringEncoding = NSUTF8StringEncoding; if (self.response.textEncodingName) { CFStringEncoding IANAEncoding = CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)self.response.textEncodingName); if (IANAEncoding != kCFStringEncodingInvalidId) { stringEncoding = CFStringConvertEncodingToNSStringEncoding(IANAEncoding); } } self.responseStringEncoding = stringEncoding; } [self.lock unlock]; return _responseStringEncoding; } - (NSInputStream *)inputStream { return self.request.HTTPBodyStream; } - (void)setInputStream:(NSInputStream *)inputStream { NSMutableURLRequest *mutableRequest = [self.request mutableCopy]; mutableRequest.HTTPBodyStream = inputStream; self.request = mutableRequest; } - (NSOutputStream *)outputStream { if (!_outputStream) { self.outputStream = [NSOutputStream outputStreamToMemory]; } return _outputStream; } - (void)setOutputStream:(NSOutputStream *)outputStream { [self.lock lock]; if (outputStream != _outputStream) { if (_outputStream) { [_outputStream close]; } _outputStream = outputStream; } [self.lock unlock]; } #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) - (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(void (^)(void))handler { [self.lock lock]; if (!self.backgroundTaskCleanup) { UIApplication *application = [UIApplication sharedApplication]; UIBackgroundTaskIdentifier __block backgroundTaskIdentifier = UIBackgroundTaskInvalid; __weak __typeof(self)weakSelf = self; self.backgroundTaskCleanup = ^(){ if (backgroundTaskIdentifier != UIBackgroundTaskInvalid) { [[UIApplication sharedApplication] endBackgroundTask:backgroundTaskIdentifier]; backgroundTaskIdentifier = UIBackgroundTaskInvalid; } }; backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{ __strong __typeof(weakSelf)strongSelf = weakSelf; if (handler) { handler(); } if (strongSelf) { [strongSelf cancel]; strongSelf.backgroundTaskCleanup(); } }]; } [self.lock unlock]; } #endif #pragma mark - - (void)setState:(AFOperationState)state { if (!AFStateTransitionIsValid(self.state, state, [self isCancelled])) { return; } [self.lock lock]; NSString *oldStateKey = AFKeyPathFromOperationState(self.state); NSString *newStateKey = AFKeyPathFromOperationState(state); [self willChangeValueForKey:newStateKey]; [self willChangeValueForKey:oldStateKey]; _state = state; [self didChangeValueForKey:oldStateKey]; [self didChangeValueForKey:newStateKey]; [self.lock unlock]; } - (void)pause { if ([self isPaused] || [self isFinished] || [self isCancelled]) { return; } [self.lock lock]; if ([self isExecuting]) { [self performSelector:@selector(operationDidPause) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; dispatch_async(dispatch_get_main_queue(), ^{ NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter postNotificationName:AFNetworkingOperationDidFinishNotification object:self]; }); } self.state = AFOperationPausedState; [self.lock unlock]; } - (void)operationDidPause { [self.lock lock]; [self.connection cancel]; [self.lock unlock]; } - (BOOL)isPaused { return self.state == AFOperationPausedState; } - (void)resume { if (![self isPaused]) { return; } [self.lock lock]; self.state = AFOperationReadyState; [self start]; [self.lock unlock]; } #pragma mark - - (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block { self.uploadProgress = block; } - (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block { self.downloadProgress = block; } - (void)setWillSendRequestForAuthenticationChallengeBlock:(void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block { self.authenticationChallenge = block; } - (void)setCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block { self.cacheResponse = block; } - (void)setRedirectResponseBlock:(NSURLRequest * (^)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse))block { self.redirectResponse = block; } #pragma mark - NSOperation - (void)setCompletionBlock:(void (^)(void))block { [self.lock lock]; if (!block) { [super setCompletionBlock:nil]; } else { __weak __typeof(self)weakSelf = self; [super setCompletionBlock:^ { __strong __typeof(weakSelf)strongSelf = weakSelf; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" dispatch_group_t group = strongSelf.completionGroup ?: url_request_operation_completion_group(); dispatch_queue_t queue = strongSelf.completionQueue ?: dispatch_get_main_queue(); #pragma clang diagnostic pop dispatch_group_async(group, queue, ^{ block(); }); dispatch_group_notify(group, url_request_operation_completion_queue(), ^{ [strongSelf setCompletionBlock:nil]; }); }]; } [self.lock unlock]; } - (BOOL)isReady { return self.state == AFOperationReadyState && [super isReady]; } - (BOOL)isExecuting { return self.state == AFOperationExecutingState; } - (BOOL)isFinished { return self.state == AFOperationFinishedState; } - (BOOL)isConcurrent { return YES; } - (void)start { [self.lock lock]; if ([self isCancelled]) { [self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; } else if ([self isReady]) { self.state = AFOperationExecutingState; [self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; } [self.lock unlock]; } - (void)operationDidStart { [self.lock lock]; if (![self isCancelled]) { self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; for (NSString *runLoopMode in self.runLoopModes) { [self.connection scheduleInRunLoop:runLoop forMode:runLoopMode]; [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode]; } [self.outputStream open]; [self.connection start]; } [self.lock unlock]; dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidStartNotification object:self]; }); } - (void)finish { [self.lock lock]; self.state = AFOperationFinishedState; [self.lock unlock]; dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidFinishNotification object:self]; }); } - (void)cancel { [self.lock lock]; if (![self isFinished] && ![self isCancelled]) { [super cancel]; if ([self isExecuting]) { [self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; } } [self.lock unlock]; } - (void)cancelConnection { NSDictionary *userInfo = nil; if ([self.request URL]) { userInfo = @{NSURLErrorFailingURLErrorKey : [self.request URL]}; } NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo]; if (![self isFinished]) { if (self.connection) { [self.connection cancel]; [self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:error]; } else { // Accommodate race condition where `self.connection` has not yet been set before cancellation self.error = error; [self finish]; } } } #pragma mark - + (NSArray *)batchOfRequestOperations:(NSArray *)operations progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock completionBlock:(void (^)(NSArray *operations))completionBlock { if (!operations || [operations count] == 0) { return @[[NSBlockOperation blockOperationWithBlock:^{ dispatch_async(dispatch_get_main_queue(), ^{ if (completionBlock) { completionBlock(@[]); } }); }]]; } __block dispatch_group_t group = dispatch_group_create(); NSBlockOperation *batchedOperation = [NSBlockOperation blockOperationWithBlock:^{ dispatch_group_notify(group, dispatch_get_main_queue(), ^{ if (completionBlock) { completionBlock(operations); } }); }]; for (AFURLConnectionOperation *operation in operations) { operation.completionGroup = group; void (^originalCompletionBlock)(void) = [operation.completionBlock copy]; __weak __typeof(operation)weakOperation = operation; operation.completionBlock = ^{ __strong __typeof(weakOperation)strongOperation = weakOperation; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" dispatch_queue_t queue = strongOperation.completionQueue ?: dispatch_get_main_queue(); #pragma clang diagnostic pop dispatch_group_async(group, queue, ^{ if (originalCompletionBlock) { originalCompletionBlock(); } NSUInteger numberOfFinishedOperations = [[operations indexesOfObjectsPassingTest:^BOOL(id op, NSUInteger __unused idx, BOOL __unused *stop) { return [op isFinished]; }] count]; if (progressBlock) { progressBlock(numberOfFinishedOperations, [operations count]); } dispatch_group_leave(group); }); }; dispatch_group_enter(group); [batchedOperation addDependency:operation]; } return [operations arrayByAddingObject:batchedOperation]; } #pragma mark - NSObject - (NSString *)description { [self.lock lock]; NSString *description = [NSString stringWithFormat:@"<%@: %p, state: %@, cancelled: %@ request: %@, response: %@>", NSStringFromClass([self class]), self, AFKeyPathFromOperationState(self.state), ([self isCancelled] ? @"YES" : @"NO"), self.request, self.response]; [self.lock unlock]; return description; } #pragma mark - NSURLConnectionDelegate - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { if (self.authenticationChallenge) { self.authenticationChallenge(connection, challenge); return; } if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; } else { [[challenge sender] cancelAuthenticationChallenge:challenge]; } } else { if ([challenge previousFailureCount] == 0) { if (self.credential) { [[challenge sender] useCredential:self.credential forAuthenticationChallenge:challenge]; } else { [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; } } else { [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; } } } - (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection __unused *)connection { return self.shouldUseCredentialStorage; } - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse { if (self.redirectResponse) { return self.redirectResponse(connection, request, redirectResponse); } else { return request; } } - (void)connection:(NSURLConnection __unused *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { dispatch_async(dispatch_get_main_queue(), ^{ if (self.uploadProgress) { self.uploadProgress((NSUInteger)bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); } }); } - (void)connection:(NSURLConnection __unused *)connection didReceiveResponse:(NSURLResponse *)response { self.response = response; } - (void)connection:(NSURLConnection __unused *)connection didReceiveData:(NSData *)data { NSUInteger length = [data length]; while (YES) { NSInteger totalNumberOfBytesWritten = 0; if ([self.outputStream hasSpaceAvailable]) { const uint8_t *dataBuffer = (uint8_t *)[data bytes]; NSInteger numberOfBytesWritten = 0; while (totalNumberOfBytesWritten < (NSInteger)length) { numberOfBytesWritten = [self.outputStream write:&dataBuffer[(NSUInteger)totalNumberOfBytesWritten] maxLength:(length - (NSUInteger)totalNumberOfBytesWritten)]; if (numberOfBytesWritten == -1) { break; } totalNumberOfBytesWritten += numberOfBytesWritten; } break; } if (self.outputStream.streamError) { [self.connection cancel]; [self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:self.outputStream.streamError]; return; } } dispatch_async(dispatch_get_main_queue(), ^{ self.totalBytesRead += (long long)length; if (self.downloadProgress) { self.downloadProgress(length, self.totalBytesRead, self.response.expectedContentLength); } }); } - (void)connectionDidFinishLoading:(NSURLConnection __unused *)connection { self.responseData = [self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; [self.outputStream close]; if (self.responseData) { self.outputStream = nil; } self.connection = nil; [self finish]; } - (void)connection:(NSURLConnection __unused *)connection didFailWithError:(NSError *)error { self.error = error; [self.outputStream close]; if (self.responseData) { self.outputStream = nil; } self.connection = nil; [self finish]; } - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { if (self.cacheResponse) { return self.cacheResponse(connection, cachedResponse); } else { if ([self isCancelled]) { return nil; } return cachedResponse; } } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSURLRequest *request = [decoder decodeObjectOfClass:[NSURLRequest class] forKey:NSStringFromSelector(@selector(request))]; self = [self initWithRequest:request]; if (!self) { return nil; } self.state = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(state))] integerValue]; self.response = [decoder decodeObjectOfClass:[NSHTTPURLResponse class] forKey:NSStringFromSelector(@selector(response))]; self.error = [decoder decodeObjectOfClass:[NSError class] forKey:NSStringFromSelector(@selector(error))]; self.responseData = [decoder decodeObjectOfClass:[NSData class] forKey:NSStringFromSelector(@selector(responseData))]; self.totalBytesRead = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(totalBytesRead))] longLongValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [self pause]; [coder encodeObject:self.request forKey:NSStringFromSelector(@selector(request))]; switch (self.state) { case AFOperationExecutingState: case AFOperationPausedState: [coder encodeInteger:AFOperationReadyState forKey:NSStringFromSelector(@selector(state))]; break; default: [coder encodeInteger:self.state forKey:NSStringFromSelector(@selector(state))]; break; } [coder encodeObject:self.response forKey:NSStringFromSelector(@selector(response))]; [coder encodeObject:self.error forKey:NSStringFromSelector(@selector(error))]; [coder encodeObject:self.responseData forKey:NSStringFromSelector(@selector(responseData))]; [coder encodeInt64:self.totalBytesRead forKey:NSStringFromSelector(@selector(totalBytesRead))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFURLConnectionOperation *operation = [(AFURLConnectionOperation *)[[self class] allocWithZone:zone] initWithRequest:self.request]; operation.uploadProgress = self.uploadProgress; operation.downloadProgress = self.downloadProgress; operation.authenticationChallenge = self.authenticationChallenge; operation.cacheResponse = self.cacheResponse; operation.redirectResponse = self.redirectResponse; operation.completionQueue = self.completionQueue; operation.completionGroup = self.completionGroup; return operation; } @end ================================================ FILE: shakefun/shakefun/AFNetworking/AFURLRequestSerialization.h ================================================ // AFURLRequestSerialization.h // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #import #endif NS_ASSUME_NONNULL_BEGIN /** The `AFURLRequestSerialization` protocol is adopted by an object that encodes parameters for a specified HTTP requests. Request serializers may encode parameters as query strings, HTTP bodies, setting the appropriate HTTP header fields as necessary. For example, a JSON request serializer may set the HTTP body of the request to a JSON representation, and set the `Content-Type` HTTP header field value to `application/json`. */ @protocol AFURLRequestSerialization /** Returns a request with the specified parameters encoded into a copy of the original request. @param request The original request. @param parameters The parameters to be encoded. @param error The error that occurred while attempting to encode the request parameters. @return A serialized request. */ - (nullable NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(nullable id)parameters error:(NSError * __nullable __autoreleasing *)error; @end #pragma mark - /** */ typedef NS_ENUM(NSUInteger, AFHTTPRequestQueryStringSerializationStyle) { AFHTTPRequestQueryStringDefaultStyle = 0, }; @protocol AFMultipartFormData; /** `AFHTTPRequestSerializer` conforms to the `AFURLRequestSerialization` & `AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. Any request or response serializer dealing with HTTP is encouraged to subclass `AFHTTPRequestSerializer` in order to ensure consistent default behavior. */ @interface AFHTTPRequestSerializer : NSObject /** The string encoding used to serialize parameters. `NSUTF8StringEncoding` by default. */ @property (nonatomic, assign) NSStringEncoding stringEncoding; /** Whether created requests can use the device’s cellular radio (if present). `YES` by default. @see NSMutableURLRequest -setAllowsCellularAccess: */ @property (nonatomic, assign) BOOL allowsCellularAccess; /** The cache policy of created requests. `NSURLRequestUseProtocolCachePolicy` by default. @see NSMutableURLRequest -setCachePolicy: */ @property (nonatomic, assign) NSURLRequestCachePolicy cachePolicy; /** Whether created requests should use the default cookie handling. `YES` by default. @see NSMutableURLRequest -setHTTPShouldHandleCookies: */ @property (nonatomic, assign) BOOL HTTPShouldHandleCookies; /** Whether created requests can continue transmitting data before receiving a response from an earlier transmission. `NO` by default @see NSMutableURLRequest -setHTTPShouldUsePipelining: */ @property (nonatomic, assign) BOOL HTTPShouldUsePipelining; /** The network service type for created requests. `NSURLNetworkServiceTypeDefault` by default. @see NSMutableURLRequest -setNetworkServiceType: */ @property (nonatomic, assign) NSURLRequestNetworkServiceType networkServiceType; /** The timeout interval, in seconds, for created requests. The default timeout interval is 60 seconds. @see NSMutableURLRequest -setTimeoutInterval: */ @property (nonatomic, assign) NSTimeInterval timeoutInterval; ///--------------------------------------- /// @name Configuring HTTP Request Headers ///--------------------------------------- /** Default HTTP header field values to be applied to serialized requests. By default, these include the following: - `Accept-Language` with the contents of `NSLocale +preferredLanguages` - `User-Agent` with the contents of various bundle identifiers and OS designations @discussion To add or remove default request headers, use `setValue:forHTTPHeaderField:`. */ @property (readonly, nonatomic, strong) NSDictionary *HTTPRequestHeaders; /** Creates and returns a serializer with default configuration. */ + (instancetype)serializer; /** Sets the value for the HTTP headers set in request objects made by the HTTP client. If `nil`, removes the existing value for that header. @param field The HTTP header to set a default value for @param value The value set as default for the specified header, or `nil` */ - (void)setValue:(nullable NSString *)value forHTTPHeaderField:(NSString *)field; /** Returns the value for the HTTP headers set in the request serializer. @param field The HTTP header to retrieve the default value for @return The value set as default for the specified header, or `nil` */ - (nullable NSString *)valueForHTTPHeaderField:(NSString *)field; /** Sets the "Authorization" HTTP header set in request objects made by the HTTP client to a basic authentication value with Base64-encoded username and password. This overwrites any existing value for this header. @param username The HTTP basic auth username @param password The HTTP basic auth password */ - (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username password:(NSString *)password; /** @deprecated This method has been deprecated. Use -setValue:forHTTPHeaderField: instead. */ - (void)setAuthorizationHeaderFieldWithToken:(NSString *)token DEPRECATED_ATTRIBUTE; /** Clears any existing value for the "Authorization" HTTP header. */ - (void)clearAuthorizationHeader; ///------------------------------------------------------- /// @name Configuring Query String Parameter Serialization ///------------------------------------------------------- /** HTTP methods for which serialized requests will encode parameters as a query string. `GET`, `HEAD`, and `DELETE` by default. */ @property (nonatomic, strong) NSSet *HTTPMethodsEncodingParametersInURI; /** Set the method of query string serialization according to one of the pre-defined styles. @param style The serialization style. @see AFHTTPRequestQueryStringSerializationStyle */ - (void)setQueryStringSerializationWithStyle:(AFHTTPRequestQueryStringSerializationStyle)style; /** Set the a custom method of query string serialization according to the specified block. @param block A block that defines a process of encoding parameters into a query string. This block returns the query string and takes three arguments: the request, the parameters to encode, and the error that occurred when attempting to encode parameters for the given request. */ - (void)setQueryStringSerializationWithBlock:(nullable NSString * (^)(NSURLRequest *request, id parameters, NSError * __autoreleasing *error))block; ///------------------------------- /// @name Creating Request Objects ///------------------------------- /** @deprecated This method has been deprecated. Use -requestWithMethod:URLString:parameters:error: instead. */ - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters DEPRECATED_ATTRIBUTE; /** Creates an `NSMutableURLRequest` object with the specified HTTP method and URL string. If the HTTP method is `GET`, `HEAD`, or `DELETE`, the parameters will be used to construct a url-encoded query string that is appended to the request's URL. Otherwise, the parameters will be encoded according to the value of the `parameterEncoding` property, and set as the request body. @param method The HTTP method for the request, such as `GET`, `POST`, `PUT`, or `DELETE`. This parameter must not be `nil`. @param URLString The URL string used to create the request URL. @param parameters The parameters to be either set as a query string for `GET` requests, or the request HTTP body. @param error The error that occurred while constructing the request. @return An `NSMutableURLRequest` object. */ - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(nullable id)parameters error:(NSError * __nullable __autoreleasing *)error; /** @deprecated This method has been deprecated. Use -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error: instead. */ - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(NSDictionary *)parameters constructingBodyWithBlock:(void (^)(id formData))block DEPRECATED_ATTRIBUTE; /** Creates an `NSMutableURLRequest` object with the specified HTTP method and URLString, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2 Multipart form requests are automatically streamed, reading files directly from disk along with in-memory data in a single HTTP body. The resulting `NSMutableURLRequest` object has an `HTTPBodyStream` property, so refrain from setting `HTTPBodyStream` or `HTTPBody` on this request object, as it will clear out the multipart form body stream. @param method The HTTP method for the request. This parameter must not be `GET` or `HEAD`, or `nil`. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded and set in the request HTTP body. @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. @param error The error that occurred while constructing the request. @return An `NSMutableURLRequest` object */ - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(nullable NSDictionary *)parameters constructingBodyWithBlock:(nullable void (^)(id formData))block error:(NSError * __nullable __autoreleasing *)error; /** Creates an `NSMutableURLRequest` by removing the `HTTPBodyStream` from a request, and asynchronously writing its contents into the specified file, invoking the completion handler when finished. @param request The multipart form request. The `HTTPBodyStream` property of `request` must not be `nil`. @param fileURL The file URL to write multipart form contents to. @param handler A handler block to execute. @discussion There is a bug in `NSURLSessionTask` that causes requests to not send a `Content-Length` header when streaming contents from an HTTP body, which is notably problematic when interacting with the Amazon S3 webservice. As a workaround, this method takes a request constructed with `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error:`, or any other request with an `HTTPBodyStream`, writes the contents to the specified file and returns a copy of the original request with the `HTTPBodyStream` property set to `nil`. From here, the file can either be passed to `AFURLSessionManager -uploadTaskWithRequest:fromFile:progress:completionHandler:`, or have its contents read into an `NSData` that's assigned to the `HTTPBody` property of the request. @see https://github.com/AFNetworking/AFNetworking/issues/1398 */ - (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request writingStreamContentsToFile:(NSURL *)fileURL completionHandler:(nullable void (^)(NSError *error))handler; @end #pragma mark - /** The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `AFHTTPRequestSerializer -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:`. */ @protocol AFMultipartFormData /** Appends the HTTP header `Content-Disposition: file; filename=#{generated filename}; name=#{name}"` and `Content-Type: #{generated mimeType}`, followed by the encoded file data and the multipart form boundary. The filename and MIME type for this data in the form will be automatically generated, using the last path component of the `fileURL` and system associated MIME type for the `fileURL` extension, respectively. @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. @param name The name to be associated with the specified data. This parameter must not be `nil`. @param error If an error occurs, upon return contains an `NSError` object that describes the problem. @return `YES` if the file data was successfully appended, otherwise `NO`. */ - (BOOL)appendPartWithFileURL:(NSURL *)fileURL name:(NSString *)name error:(NSError * __nullable __autoreleasing *)error; /** Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. @param name The name to be associated with the specified data. This parameter must not be `nil`. @param fileName The file name to be used in the `Content-Disposition` header. This parameter must not be `nil`. @param mimeType The declared MIME type of the file data. This parameter must not be `nil`. @param error If an error occurs, upon return contains an `NSError` object that describes the problem. @return `YES` if the file data was successfully appended otherwise `NO`. */ - (BOOL)appendPartWithFileURL:(NSURL *)fileURL name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType error:(NSError * __nullable __autoreleasing *)error; /** Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the data from the input stream and the multipart form boundary. @param inputStream The input stream to be appended to the form data @param name The name to be associated with the specified input stream. This parameter must not be `nil`. @param fileName The filename to be associated with the specified input stream. This parameter must not be `nil`. @param length The length of the specified input stream in bytes. @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. */ - (void)appendPartWithInputStream:(nullable NSInputStream *)inputStream name:(NSString *)name fileName:(NSString *)fileName length:(int64_t)length mimeType:(NSString *)mimeType; /** Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. @param data The data to be encoded and appended to the form data. @param name The name to be associated with the specified data. This parameter must not be `nil`. @param fileName The filename to be associated with the specified data. This parameter must not be `nil`. @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. */ - (void)appendPartWithFileData:(NSData *)data name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType; /** Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"`, followed by the encoded data and the multipart form boundary. @param data The data to be encoded and appended to the form data. @param name The name to be associated with the specified data. This parameter must not be `nil`. */ - (void)appendPartWithFormData:(NSData *)data name:(NSString *)name; /** Appends HTTP headers, followed by the encoded data and the multipart form boundary. @param headers The HTTP headers to be appended to the form data. @param body The data to be encoded and appended to the form data. This parameter must not be `nil`. */ - (void)appendPartWithHeaders:(nullable NSDictionary *)headers body:(NSData *)body; /** Throttles request bandwidth by limiting the packet size and adding a delay for each chunk read from the upload stream. When uploading over a 3G or EDGE connection, requests may fail with "request body stream exhausted". Setting a maximum packet size and delay according to the recommended values (`kAFUploadStream3GSuggestedPacketSize` and `kAFUploadStream3GSuggestedDelay`) lowers the risk of the input stream exceeding its allocated bandwidth. Unfortunately, there is no definite way to distinguish between a 3G, EDGE, or LTE connection over `NSURLConnection`. As such, it is not recommended that you throttle bandwidth based solely on network reachability. Instead, you should consider checking for the "request body stream exhausted" in a failure block, and then retrying the request with throttled bandwidth. @param numberOfBytes Maximum packet size, in number of bytes. The default packet size for an input stream is 16kb. @param delay Duration of delay each time a packet is read. By default, no delay is set. */ - (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes delay:(NSTimeInterval)delay; @end #pragma mark - /** `AFJSONRequestSerializer` is a subclass of `AFHTTPRequestSerializer` that encodes parameters as JSON using `NSJSONSerialization`, setting the `Content-Type` of the encoded request to `application/json`. */ @interface AFJSONRequestSerializer : AFHTTPRequestSerializer /** Options for writing the request JSON data from Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONWritingOptions". `0` by default. */ @property (nonatomic, assign) NSJSONWritingOptions writingOptions; /** Creates and returns a JSON serializer with specified reading and writing options. @param writingOptions The specified JSON writing options. */ + (instancetype)serializerWithWritingOptions:(NSJSONWritingOptions)writingOptions; @end #pragma mark - /** `AFPropertyListRequestSerializer` is a subclass of `AFHTTPRequestSerializer` that encodes parameters as JSON using `NSPropertyListSerializer`, setting the `Content-Type` of the encoded request to `application/x-plist`. */ @interface AFPropertyListRequestSerializer : AFHTTPRequestSerializer /** The property list format. Possible values are described in "NSPropertyListFormat". */ @property (nonatomic, assign) NSPropertyListFormat format; /** @warning The `writeOptions` property is currently unused. */ @property (nonatomic, assign) NSPropertyListWriteOptions writeOptions; /** Creates and returns a property list serializer with a specified format, read options, and write options. @param format The property list format. @param writeOptions The property list write options. @warning The `writeOptions` property is currently unused. */ + (instancetype)serializerWithFormat:(NSPropertyListFormat)format writeOptions:(NSPropertyListWriteOptions)writeOptions; @end #pragma mark - ///---------------- /// @name Constants ///---------------- /** ## Error Domains The following error domain is predefined. - `NSString * const AFURLRequestSerializationErrorDomain` ### Constants `AFURLRequestSerializationErrorDomain` AFURLRequestSerializer errors. Error codes for `AFURLRequestSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`. */ extern NSString * const AFURLRequestSerializationErrorDomain; /** ## User info dictionary keys These keys may exist in the user info dictionary, in addition to those defined for NSError. - `NSString * const AFNetworkingOperationFailingURLRequestErrorKey` ### Constants `AFNetworkingOperationFailingURLRequestErrorKey` The corresponding value is an `NSURLRequest` containing the request of the operation associated with an error. This key is only present in the `AFURLRequestSerializationErrorDomain`. */ extern NSString * const AFNetworkingOperationFailingURLRequestErrorKey; /** ## Throttling Bandwidth for HTTP Request Input Streams @see -throttleBandwidthWithPacketSize:delay: ### Constants `kAFUploadStream3GSuggestedPacketSize` Maximum packet size, in number of bytes. Equal to 16kb. `kAFUploadStream3GSuggestedDelay` Duration of delay each time a packet is read. Equal to 0.2 seconds. */ extern NSUInteger const kAFUploadStream3GSuggestedPacketSize; extern NSTimeInterval const kAFUploadStream3GSuggestedDelay; NS_ASSUME_NONNULL_END ================================================ FILE: shakefun/shakefun/AFNetworking/AFURLRequestSerialization.m ================================================ // AFURLRequestSerialization.m // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFURLRequestSerialization.h" #if __IPHONE_OS_VERSION_MIN_REQUIRED #import #else #import #endif NSString * const AFURLRequestSerializationErrorDomain = @"com.alamofire.error.serialization.request"; NSString * const AFNetworkingOperationFailingURLRequestErrorKey = @"com.alamofire.serialization.request.error.response"; typedef NSString * (^AFQueryStringSerializationBlock)(NSURLRequest *request, id parameters, NSError *__autoreleasing *error); static NSString * AFBase64EncodedStringFromString(NSString *string) { NSData *data = [NSData dataWithBytes:[string UTF8String] length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]]; NSUInteger length = [data length]; NSMutableData *mutableData = [NSMutableData dataWithLength:((length + 2) / 3) * 4]; uint8_t *input = (uint8_t *)[data bytes]; uint8_t *output = (uint8_t *)[mutableData mutableBytes]; for (NSUInteger i = 0; i < length; i += 3) { NSUInteger value = 0; for (NSUInteger j = i; j < (i + 3); j++) { value <<= 8; if (j < length) { value |= (0xFF & input[j]); } } static uint8_t const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; NSUInteger idx = (i / 3) * 4; output[idx + 0] = kAFBase64EncodingTable[(value >> 18) & 0x3F]; output[idx + 1] = kAFBase64EncodingTable[(value >> 12) & 0x3F]; output[idx + 2] = (i + 1) < length ? kAFBase64EncodingTable[(value >> 6) & 0x3F] : '='; output[idx + 3] = (i + 2) < length ? kAFBase64EncodingTable[(value >> 0) & 0x3F] : '='; } return [[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding]; } static NSString * const kAFCharactersToBeEscapedInQueryString = @":/?&=;+!@#$()',*"; static NSString * AFPercentEscapedQueryStringKeyFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { static NSString * const kAFCharactersToLeaveUnescapedInQueryStringPairKey = @"[]."; return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kAFCharactersToLeaveUnescapedInQueryStringPairKey, (__bridge CFStringRef)kAFCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding)); } static NSString * AFPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kAFCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding)); } #pragma mark - @interface AFQueryStringPair : NSObject @property (readwrite, nonatomic, strong) id field; @property (readwrite, nonatomic, strong) id value; - (id)initWithField:(id)field value:(id)value; - (NSString *)URLEncodedStringValueWithEncoding:(NSStringEncoding)stringEncoding; @end @implementation AFQueryStringPair - (id)initWithField:(id)field value:(id)value { self = [super init]; if (!self) { return nil; } self.field = field; self.value = value; return self; } - (NSString *)URLEncodedStringValueWithEncoding:(NSStringEncoding)stringEncoding { if (!self.value || [self.value isEqual:[NSNull null]]) { return AFPercentEscapedQueryStringKeyFromStringWithEncoding([self.field description], stringEncoding); } else { return [NSString stringWithFormat:@"%@=%@", AFPercentEscapedQueryStringKeyFromStringWithEncoding([self.field description], stringEncoding), AFPercentEscapedQueryStringValueFromStringWithEncoding([self.value description], stringEncoding)]; } } @end #pragma mark - extern NSArray * AFQueryStringPairsFromDictionary(NSDictionary *dictionary); extern NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value); static NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding stringEncoding) { NSMutableArray *mutablePairs = [NSMutableArray array]; for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) { [mutablePairs addObject:[pair URLEncodedStringValueWithEncoding:stringEncoding]]; } return [mutablePairs componentsJoinedByString:@"&"]; } NSArray * AFQueryStringPairsFromDictionary(NSDictionary *dictionary) { return AFQueryStringPairsFromKeyAndValue(nil, dictionary); } NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) { NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES selector:@selector(compare:)]; if ([value isKindOfClass:[NSDictionary class]]) { NSDictionary *dictionary = value; // Sort dictionary keys to ensure consistent ordering in query string, which is important when deserializing potentially ambiguous sequences, such as an array of dictionaries for (id nestedKey in [dictionary.allKeys sortedArrayUsingDescriptors:@[ sortDescriptor ]]) { id nestedValue = dictionary[nestedKey]; if (nestedValue) { [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)]; } } } else if ([value isKindOfClass:[NSArray class]]) { NSArray *array = value; for (id nestedValue in array) { [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)]; } } else if ([value isKindOfClass:[NSSet class]]) { NSSet *set = value; for (id obj in [set sortedArrayUsingDescriptors:@[ sortDescriptor ]]) { [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue(key, obj)]; } } else { [mutableQueryStringComponents addObject:[[AFQueryStringPair alloc] initWithField:key value:value]]; } return mutableQueryStringComponents; } #pragma mark - @interface AFStreamingMultipartFormData : NSObject - (instancetype)initWithURLRequest:(NSMutableURLRequest *)urlRequest stringEncoding:(NSStringEncoding)encoding; - (NSMutableURLRequest *)requestByFinalizingMultipartFormData; @end #pragma mark - static NSArray * AFHTTPRequestSerializerObservedKeyPaths() { static NSArray *_AFHTTPRequestSerializerObservedKeyPaths = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _AFHTTPRequestSerializerObservedKeyPaths = @[NSStringFromSelector(@selector(allowsCellularAccess)), NSStringFromSelector(@selector(cachePolicy)), NSStringFromSelector(@selector(HTTPShouldHandleCookies)), NSStringFromSelector(@selector(HTTPShouldUsePipelining)), NSStringFromSelector(@selector(networkServiceType)), NSStringFromSelector(@selector(timeoutInterval))]; }); return _AFHTTPRequestSerializerObservedKeyPaths; } static void *AFHTTPRequestSerializerObserverContext = &AFHTTPRequestSerializerObserverContext; @interface AFHTTPRequestSerializer () @property (readwrite, nonatomic, strong) NSMutableSet *mutableObservedChangedKeyPaths; @property (readwrite, nonatomic, strong) NSMutableDictionary *mutableHTTPRequestHeaders; @property (readwrite, nonatomic, assign) AFHTTPRequestQueryStringSerializationStyle queryStringSerializationStyle; @property (readwrite, nonatomic, copy) AFQueryStringSerializationBlock queryStringSerialization; @end @implementation AFHTTPRequestSerializer + (instancetype)serializer { return [[self alloc] init]; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.stringEncoding = NSUTF8StringEncoding; self.mutableHTTPRequestHeaders = [NSMutableDictionary dictionary]; // Accept-Language HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 NSMutableArray *acceptLanguagesComponents = [NSMutableArray array]; [[NSLocale preferredLanguages] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { float q = 1.0f - (idx * 0.1f); [acceptLanguagesComponents addObject:[NSString stringWithFormat:@"%@;q=%0.1g", obj, q]]; *stop = q <= 0.5f; }]; [self setValue:[acceptLanguagesComponents componentsJoinedByString:@", "] forHTTPHeaderField:@"Accept-Language"]; NSString *userAgent = nil; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]]; #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) userAgent = [NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]; #endif #pragma clang diagnostic pop if (userAgent) { if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) { NSMutableString *mutableUserAgent = [userAgent mutableCopy]; if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) { userAgent = mutableUserAgent; } } [self setValue:userAgent forHTTPHeaderField:@"User-Agent"]; } // HTTP Method Definitions; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html self.HTTPMethodsEncodingParametersInURI = [NSSet setWithObjects:@"GET", @"HEAD", @"DELETE", nil]; self.mutableObservedChangedKeyPaths = [NSMutableSet set]; for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { if ([self respondsToSelector:NSSelectorFromString(keyPath)]) { [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext]; } } return self; } - (void)dealloc { for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { if ([self respondsToSelector:NSSelectorFromString(keyPath)]) { [self removeObserver:self forKeyPath:keyPath context:AFHTTPRequestSerializerObserverContext]; } } } #pragma mark - // Workarounds for crashing behavior using Key-Value Observing with XCTest // See https://github.com/AFNetworking/AFNetworking/issues/2523 - (void)setAllowsCellularAccess:(BOOL)allowsCellularAccess { [self willChangeValueForKey:NSStringFromSelector(@selector(allowsCellularAccess))]; _allowsCellularAccess = allowsCellularAccess; [self didChangeValueForKey:NSStringFromSelector(@selector(allowsCellularAccess))]; } - (void)setCachePolicy:(NSURLRequestCachePolicy)cachePolicy { [self willChangeValueForKey:NSStringFromSelector(@selector(cachePolicy))]; _cachePolicy = cachePolicy; [self didChangeValueForKey:NSStringFromSelector(@selector(cachePolicy))]; } - (void)setHTTPShouldHandleCookies:(BOOL)HTTPShouldHandleCookies { [self willChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldHandleCookies))]; _HTTPShouldHandleCookies = HTTPShouldHandleCookies; [self didChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldHandleCookies))]; } - (void)setHTTPShouldUsePipelining:(BOOL)HTTPShouldUsePipelining { [self willChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldUsePipelining))]; _HTTPShouldUsePipelining = HTTPShouldUsePipelining; [self didChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldUsePipelining))]; } - (void)setNetworkServiceType:(NSURLRequestNetworkServiceType)networkServiceType { [self willChangeValueForKey:NSStringFromSelector(@selector(networkServiceType))]; _networkServiceType = networkServiceType; [self didChangeValueForKey:NSStringFromSelector(@selector(networkServiceType))]; } - (void)setTimeoutInterval:(NSTimeInterval)timeoutInterval { [self willChangeValueForKey:NSStringFromSelector(@selector(timeoutInterval))]; _timeoutInterval = timeoutInterval; [self didChangeValueForKey:NSStringFromSelector(@selector(timeoutInterval))]; } #pragma mark - - (NSDictionary *)HTTPRequestHeaders { return [NSDictionary dictionaryWithDictionary:self.mutableHTTPRequestHeaders]; } - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field { [self.mutableHTTPRequestHeaders setValue:value forKey:field]; } - (NSString *)valueForHTTPHeaderField:(NSString *)field { return [self.mutableHTTPRequestHeaders valueForKey:field]; } - (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username password:(NSString *)password { NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", username, password]; [self setValue:[NSString stringWithFormat:@"Basic %@", AFBase64EncodedStringFromString(basicAuthCredentials)] forHTTPHeaderField:@"Authorization"]; } - (void)setAuthorizationHeaderFieldWithToken:(NSString *)token { [self setValue:[NSString stringWithFormat:@"Token token=\"%@\"", token] forHTTPHeaderField:@"Authorization"]; } - (void)clearAuthorizationHeader { [self.mutableHTTPRequestHeaders removeObjectForKey:@"Authorization"]; } #pragma mark - - (void)setQueryStringSerializationWithStyle:(AFHTTPRequestQueryStringSerializationStyle)style { self.queryStringSerializationStyle = style; self.queryStringSerialization = nil; } - (void)setQueryStringSerializationWithBlock:(NSString *(^)(NSURLRequest *, id, NSError *__autoreleasing *))block { self.queryStringSerialization = block; } #pragma mark - - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters { return [self requestWithMethod:method URLString:URLString parameters:parameters error:nil]; } - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(method); NSParameterAssert(URLString); NSURL *url = [NSURL URLWithString:URLString]; NSParameterAssert(url); NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url]; mutableRequest.HTTPMethod = method; for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { if ([self.mutableObservedChangedKeyPaths containsObject:keyPath]) { [mutableRequest setValue:[self valueForKeyPath:keyPath] forKey:keyPath]; } } mutableRequest = [[self requestBySerializingRequest:mutableRequest withParameters:parameters error:error] mutableCopy]; return mutableRequest; } - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(NSDictionary *)parameters constructingBodyWithBlock:(void (^)(id formData))block { return [self multipartFormRequestWithMethod:method URLString:URLString parameters:parameters constructingBodyWithBlock:block error:nil]; } - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(NSDictionary *)parameters constructingBodyWithBlock:(void (^)(id formData))block error:(NSError *__autoreleasing *)error { NSParameterAssert(method); NSParameterAssert(![method isEqualToString:@"GET"] && ![method isEqualToString:@"HEAD"]); NSMutableURLRequest *mutableRequest = [self requestWithMethod:method URLString:URLString parameters:nil error:error]; __block AFStreamingMultipartFormData *formData = [[AFStreamingMultipartFormData alloc] initWithURLRequest:mutableRequest stringEncoding:NSUTF8StringEncoding]; if (parameters) { for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) { NSData *data = nil; if ([pair.value isKindOfClass:[NSData class]]) { data = pair.value; } else if ([pair.value isEqual:[NSNull null]]) { data = [NSData data]; } else { data = [[pair.value description] dataUsingEncoding:self.stringEncoding]; } if (data) { [formData appendPartWithFormData:data name:[pair.field description]]; } } } if (block) { block(formData); } return [formData requestByFinalizingMultipartFormData]; } - (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request writingStreamContentsToFile:(NSURL *)fileURL completionHandler:(void (^)(NSError *error))handler { NSParameterAssert(request.HTTPBodyStream); NSParameterAssert([fileURL isFileURL]); NSInputStream *inputStream = request.HTTPBodyStream; NSOutputStream *outputStream = [[NSOutputStream alloc] initWithURL:fileURL append:NO]; __block NSError *error = nil; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [inputStream open]; [outputStream open]; while ([inputStream hasBytesAvailable] && [outputStream hasSpaceAvailable]) { uint8_t buffer[1024]; NSInteger bytesRead = [inputStream read:buffer maxLength:1024]; if (inputStream.streamError || bytesRead < 0) { error = inputStream.streamError; break; } NSInteger bytesWritten = [outputStream write:buffer maxLength:(NSUInteger)bytesRead]; if (outputStream.streamError || bytesWritten < 0) { error = outputStream.streamError; break; } if (bytesRead == 0 && bytesWritten == 0) { break; } } [outputStream close]; [inputStream close]; if (handler) { dispatch_async(dispatch_get_main_queue(), ^{ handler(error); }); } }); NSMutableURLRequest *mutableRequest = [request mutableCopy]; mutableRequest.HTTPBodyStream = nil; return mutableRequest; } #pragma mark - AFURLRequestSerialization - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(request); NSMutableURLRequest *mutableRequest = [request mutableCopy]; [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { if (![request valueForHTTPHeaderField:field]) { [mutableRequest setValue:value forHTTPHeaderField:field]; } }]; if (parameters) { NSString *query = nil; if (self.queryStringSerialization) { NSError *serializationError; query = self.queryStringSerialization(request, parameters, &serializationError); if (serializationError) { if (error) { *error = serializationError; } return nil; } } else { switch (self.queryStringSerializationStyle) { case AFHTTPRequestQueryStringDefaultStyle: query = AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding); break; } } if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]]; } else { if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { [mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; } [mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]]; } } return mutableRequest; } #pragma mark - NSKeyValueObserving + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key { if ([AFHTTPRequestSerializerObservedKeyPaths() containsObject:key]) { return NO; } return [super automaticallyNotifiesObserversForKey:key]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(__unused id)object change:(NSDictionary *)change context:(void *)context { if (context == AFHTTPRequestSerializerObserverContext) { if ([change[NSKeyValueChangeNewKey] isEqual:[NSNull null]]) { [self.mutableObservedChangedKeyPaths removeObject:keyPath]; } else { [self.mutableObservedChangedKeyPaths addObject:keyPath]; } } } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { self = [self init]; if (!self) { return nil; } self.mutableHTTPRequestHeaders = [[decoder decodeObjectOfClass:[NSDictionary class] forKey:NSStringFromSelector(@selector(mutableHTTPRequestHeaders))] mutableCopy]; self.queryStringSerializationStyle = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(queryStringSerializationStyle))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:self.mutableHTTPRequestHeaders forKey:NSStringFromSelector(@selector(mutableHTTPRequestHeaders))]; [coder encodeInteger:self.queryStringSerializationStyle forKey:NSStringFromSelector(@selector(queryStringSerializationStyle))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFHTTPRequestSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.mutableHTTPRequestHeaders = [self.mutableHTTPRequestHeaders mutableCopyWithZone:zone]; serializer.queryStringSerializationStyle = self.queryStringSerializationStyle; serializer.queryStringSerialization = self.queryStringSerialization; return serializer; } @end #pragma mark - static NSString * AFCreateMultipartFormBoundary() { return [NSString stringWithFormat:@"Boundary+%08X%08X", arc4random(), arc4random()]; } static NSString * const kAFMultipartFormCRLF = @"\r\n"; static inline NSString * AFMultipartFormInitialBoundary(NSString *boundary) { return [NSString stringWithFormat:@"--%@%@", boundary, kAFMultipartFormCRLF]; } static inline NSString * AFMultipartFormEncapsulationBoundary(NSString *boundary) { return [NSString stringWithFormat:@"%@--%@%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF]; } static inline NSString * AFMultipartFormFinalBoundary(NSString *boundary) { return [NSString stringWithFormat:@"%@--%@--%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF]; } static inline NSString * AFContentTypeForPathExtension(NSString *extension) { #ifdef __UTTYPE__ NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL); NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType); if (!contentType) { return @"application/octet-stream"; } else { return contentType; } #else #pragma unused (extension) return @"application/octet-stream"; #endif } NSUInteger const kAFUploadStream3GSuggestedPacketSize = 1024 * 16; NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2; @interface AFHTTPBodyPart : NSObject @property (nonatomic, assign) NSStringEncoding stringEncoding; @property (nonatomic, strong) NSDictionary *headers; @property (nonatomic, copy) NSString *boundary; @property (nonatomic, strong) id body; @property (nonatomic, assign) unsigned long long bodyContentLength; @property (nonatomic, strong) NSInputStream *inputStream; @property (nonatomic, assign) BOOL hasInitialBoundary; @property (nonatomic, assign) BOOL hasFinalBoundary; @property (readonly, nonatomic, assign, getter = hasBytesAvailable) BOOL bytesAvailable; @property (readonly, nonatomic, assign) unsigned long long contentLength; - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length; @end @interface AFMultipartBodyStream : NSInputStream @property (nonatomic, assign) NSUInteger numberOfBytesInPacket; @property (nonatomic, assign) NSTimeInterval delay; @property (nonatomic, strong) NSInputStream *inputStream; @property (readonly, nonatomic, assign) unsigned long long contentLength; @property (readonly, nonatomic, assign, getter = isEmpty) BOOL empty; - (id)initWithStringEncoding:(NSStringEncoding)encoding; - (void)setInitialAndFinalBoundaries; - (void)appendHTTPBodyPart:(AFHTTPBodyPart *)bodyPart; @end #pragma mark - @interface AFStreamingMultipartFormData () @property (readwrite, nonatomic, copy) NSMutableURLRequest *request; @property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding; @property (readwrite, nonatomic, copy) NSString *boundary; @property (readwrite, nonatomic, strong) AFMultipartBodyStream *bodyStream; @end @implementation AFStreamingMultipartFormData - (id)initWithURLRequest:(NSMutableURLRequest *)urlRequest stringEncoding:(NSStringEncoding)encoding { self = [super init]; if (!self) { return nil; } self.request = urlRequest; self.stringEncoding = encoding; self.boundary = AFCreateMultipartFormBoundary(); self.bodyStream = [[AFMultipartBodyStream alloc] initWithStringEncoding:encoding]; return self; } - (BOOL)appendPartWithFileURL:(NSURL *)fileURL name:(NSString *)name error:(NSError * __autoreleasing *)error { NSParameterAssert(fileURL); NSParameterAssert(name); NSString *fileName = [fileURL lastPathComponent]; NSString *mimeType = AFContentTypeForPathExtension([fileURL pathExtension]); return [self appendPartWithFileURL:fileURL name:name fileName:fileName mimeType:mimeType error:error]; } - (BOOL)appendPartWithFileURL:(NSURL *)fileURL name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType error:(NSError * __autoreleasing *)error { NSParameterAssert(fileURL); NSParameterAssert(name); NSParameterAssert(fileName); NSParameterAssert(mimeType); if (![fileURL isFileURL]) { NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey: NSLocalizedStringFromTable(@"Expected URL to be a file URL", @"AFNetworking", nil)}; if (error) { *error = [[NSError alloc] initWithDomain:AFURLRequestSerializationErrorDomain code:NSURLErrorBadURL userInfo:userInfo]; } return NO; } else if ([fileURL checkResourceIsReachableAndReturnError:error] == NO) { NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey: NSLocalizedStringFromTable(@"File URL not reachable.", @"AFNetworking", nil)}; if (error) { *error = [[NSError alloc] initWithDomain:AFURLRequestSerializationErrorDomain code:NSURLErrorBadURL userInfo:userInfo]; } return NO; } NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:error]; if (!fileAttributes) { return NO; } NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; bodyPart.stringEncoding = self.stringEncoding; bodyPart.headers = mutableHeaders; bodyPart.boundary = self.boundary; bodyPart.body = fileURL; bodyPart.bodyContentLength = [fileAttributes[NSFileSize] unsignedLongLongValue]; [self.bodyStream appendHTTPBodyPart:bodyPart]; return YES; } - (void)appendPartWithInputStream:(NSInputStream *)inputStream name:(NSString *)name fileName:(NSString *)fileName length:(int64_t)length mimeType:(NSString *)mimeType { NSParameterAssert(name); NSParameterAssert(fileName); NSParameterAssert(mimeType); NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; bodyPart.stringEncoding = self.stringEncoding; bodyPart.headers = mutableHeaders; bodyPart.boundary = self.boundary; bodyPart.body = inputStream; bodyPart.bodyContentLength = (unsigned long long)length; [self.bodyStream appendHTTPBodyPart:bodyPart]; } - (void)appendPartWithFileData:(NSData *)data name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType { NSParameterAssert(name); NSParameterAssert(fileName); NSParameterAssert(mimeType); NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; [self appendPartWithHeaders:mutableHeaders body:data]; } - (void)appendPartWithFormData:(NSData *)data name:(NSString *)name { NSParameterAssert(name); NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"]; [self appendPartWithHeaders:mutableHeaders body:data]; } - (void)appendPartWithHeaders:(NSDictionary *)headers body:(NSData *)body { NSParameterAssert(body); AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; bodyPart.stringEncoding = self.stringEncoding; bodyPart.headers = headers; bodyPart.boundary = self.boundary; bodyPart.bodyContentLength = [body length]; bodyPart.body = body; [self.bodyStream appendHTTPBodyPart:bodyPart]; } - (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes delay:(NSTimeInterval)delay { self.bodyStream.numberOfBytesInPacket = numberOfBytes; self.bodyStream.delay = delay; } - (NSMutableURLRequest *)requestByFinalizingMultipartFormData { if ([self.bodyStream isEmpty]) { return self.request; } // Reset the initial and final boundaries to ensure correct Content-Length [self.bodyStream setInitialAndFinalBoundaries]; [self.request setHTTPBodyStream:self.bodyStream]; [self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.boundary] forHTTPHeaderField:@"Content-Type"]; [self.request setValue:[NSString stringWithFormat:@"%llu", [self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"]; return self.request; } @end #pragma mark - @interface NSStream () @property (readwrite) NSStreamStatus streamStatus; @property (readwrite, copy) NSError *streamError; @end @interface AFMultipartBodyStream () @property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding; @property (readwrite, nonatomic, strong) NSMutableArray *HTTPBodyParts; @property (readwrite, nonatomic, strong) NSEnumerator *HTTPBodyPartEnumerator; @property (readwrite, nonatomic, strong) AFHTTPBodyPart *currentHTTPBodyPart; @property (readwrite, nonatomic, strong) NSOutputStream *outputStream; @property (readwrite, nonatomic, strong) NSMutableData *buffer; @end @implementation AFMultipartBodyStream #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wimplicit-atomic-properties" #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1100) @synthesize delegate; #endif @synthesize streamStatus; @synthesize streamError; #pragma clang diagnostic pop - (id)initWithStringEncoding:(NSStringEncoding)encoding { self = [super init]; if (!self) { return nil; } self.stringEncoding = encoding; self.HTTPBodyParts = [NSMutableArray array]; self.numberOfBytesInPacket = NSIntegerMax; return self; } - (void)setInitialAndFinalBoundaries { if ([self.HTTPBodyParts count] > 0) { for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { bodyPart.hasInitialBoundary = NO; bodyPart.hasFinalBoundary = NO; } [[self.HTTPBodyParts firstObject] setHasInitialBoundary:YES]; [[self.HTTPBodyParts lastObject] setHasFinalBoundary:YES]; } } - (void)appendHTTPBodyPart:(AFHTTPBodyPart *)bodyPart { [self.HTTPBodyParts addObject:bodyPart]; } - (BOOL)isEmpty { return [self.HTTPBodyParts count] == 0; } #pragma mark - NSInputStream - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length { if ([self streamStatus] == NSStreamStatusClosed) { return 0; } NSInteger totalNumberOfBytesRead = 0; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" while ((NSUInteger)totalNumberOfBytesRead < MIN(length, self.numberOfBytesInPacket)) { if (!self.currentHTTPBodyPart || ![self.currentHTTPBodyPart hasBytesAvailable]) { if (!(self.currentHTTPBodyPart = [self.HTTPBodyPartEnumerator nextObject])) { break; } } else { NSUInteger maxLength = length - (NSUInteger)totalNumberOfBytesRead; NSInteger numberOfBytesRead = [self.currentHTTPBodyPart read:&buffer[totalNumberOfBytesRead] maxLength:maxLength]; if (numberOfBytesRead == -1) { self.streamError = self.currentHTTPBodyPart.inputStream.streamError; break; } else { totalNumberOfBytesRead += numberOfBytesRead; if (self.delay > 0.0f) { [NSThread sleepForTimeInterval:self.delay]; } } } } #pragma clang diagnostic pop return totalNumberOfBytesRead; } - (BOOL)getBuffer:(__unused uint8_t **)buffer length:(__unused NSUInteger *)len { return NO; } - (BOOL)hasBytesAvailable { return [self streamStatus] == NSStreamStatusOpen; } #pragma mark - NSStream - (void)open { if (self.streamStatus == NSStreamStatusOpen) { return; } self.streamStatus = NSStreamStatusOpen; [self setInitialAndFinalBoundaries]; self.HTTPBodyPartEnumerator = [self.HTTPBodyParts objectEnumerator]; } - (void)close { self.streamStatus = NSStreamStatusClosed; } - (id)propertyForKey:(__unused NSString *)key { return nil; } - (BOOL)setProperty:(__unused id)property forKey:(__unused NSString *)key { return NO; } - (void)scheduleInRunLoop:(__unused NSRunLoop *)aRunLoop forMode:(__unused NSString *)mode {} - (void)removeFromRunLoop:(__unused NSRunLoop *)aRunLoop forMode:(__unused NSString *)mode {} - (unsigned long long)contentLength { unsigned long long length = 0; for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { length += [bodyPart contentLength]; } return length; } #pragma mark - Undocumented CFReadStream Bridged Methods - (void)_scheduleInCFRunLoop:(__unused CFRunLoopRef)aRunLoop forMode:(__unused CFStringRef)aMode {} - (void)_unscheduleFromCFRunLoop:(__unused CFRunLoopRef)aRunLoop forMode:(__unused CFStringRef)aMode {} - (BOOL)_setCFClientFlags:(__unused CFOptionFlags)inFlags callback:(__unused CFReadStreamClientCallBack)inCallback context:(__unused CFStreamClientContext *)inContext { return NO; } #pragma mark - NSCopying -(id)copyWithZone:(NSZone *)zone { AFMultipartBodyStream *bodyStreamCopy = [[[self class] allocWithZone:zone] initWithStringEncoding:self.stringEncoding]; for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { [bodyStreamCopy appendHTTPBodyPart:[bodyPart copy]]; } [bodyStreamCopy setInitialAndFinalBoundaries]; return bodyStreamCopy; } @end #pragma mark - typedef enum { AFEncapsulationBoundaryPhase = 1, AFHeaderPhase = 2, AFBodyPhase = 3, AFFinalBoundaryPhase = 4, } AFHTTPBodyPartReadPhase; @interface AFHTTPBodyPart () { AFHTTPBodyPartReadPhase _phase; NSInputStream *_inputStream; unsigned long long _phaseReadOffset; } - (BOOL)transitionToNextPhase; - (NSInteger)readData:(NSData *)data intoBuffer:(uint8_t *)buffer maxLength:(NSUInteger)length; @end @implementation AFHTTPBodyPart - (id)init { self = [super init]; if (!self) { return nil; } [self transitionToNextPhase]; return self; } - (void)dealloc { if (_inputStream) { [_inputStream close]; _inputStream = nil; } } - (NSInputStream *)inputStream { if (!_inputStream) { if ([self.body isKindOfClass:[NSData class]]) { _inputStream = [NSInputStream inputStreamWithData:self.body]; } else if ([self.body isKindOfClass:[NSURL class]]) { _inputStream = [NSInputStream inputStreamWithURL:self.body]; } else if ([self.body isKindOfClass:[NSInputStream class]]) { _inputStream = self.body; } else { _inputStream = [NSInputStream inputStreamWithData:[NSData data]]; } } return _inputStream; } - (NSString *)stringForHeaders { NSMutableString *headerString = [NSMutableString string]; for (NSString *field in [self.headers allKeys]) { [headerString appendString:[NSString stringWithFormat:@"%@: %@%@", field, [self.headers valueForKey:field], kAFMultipartFormCRLF]]; } [headerString appendString:kAFMultipartFormCRLF]; return [NSString stringWithString:headerString]; } - (unsigned long long)contentLength { unsigned long long length = 0; NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding]; length += [encapsulationBoundaryData length]; NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding]; length += [headersData length]; length += _bodyContentLength; NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]); length += [closingBoundaryData length]; return length; } - (BOOL)hasBytesAvailable { // Allows `read:maxLength:` to be called again if `AFMultipartFormFinalBoundary` doesn't fit into the available buffer if (_phase == AFFinalBoundaryPhase) { return YES; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wcovered-switch-default" switch (self.inputStream.streamStatus) { case NSStreamStatusNotOpen: case NSStreamStatusOpening: case NSStreamStatusOpen: case NSStreamStatusReading: case NSStreamStatusWriting: return YES; case NSStreamStatusAtEnd: case NSStreamStatusClosed: case NSStreamStatusError: default: return NO; } #pragma clang diagnostic pop } - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length { NSInteger totalNumberOfBytesRead = 0; if (_phase == AFEncapsulationBoundaryPhase) { NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding]; totalNumberOfBytesRead += [self readData:encapsulationBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; } if (_phase == AFHeaderPhase) { NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding]; totalNumberOfBytesRead += [self readData:headersData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; } if (_phase == AFBodyPhase) { NSInteger numberOfBytesRead = 0; numberOfBytesRead = [self.inputStream read:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; if (numberOfBytesRead == -1) { return -1; } else { totalNumberOfBytesRead += numberOfBytesRead; if ([self.inputStream streamStatus] >= NSStreamStatusAtEnd) { [self transitionToNextPhase]; } } } if (_phase == AFFinalBoundaryPhase) { NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]); totalNumberOfBytesRead += [self readData:closingBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; } return totalNumberOfBytesRead; } - (NSInteger)readData:(NSData *)data intoBuffer:(uint8_t *)buffer maxLength:(NSUInteger)length { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" NSRange range = NSMakeRange((NSUInteger)_phaseReadOffset, MIN([data length] - ((NSUInteger)_phaseReadOffset), length)); [data getBytes:buffer range:range]; #pragma clang diagnostic pop _phaseReadOffset += range.length; if (((NSUInteger)_phaseReadOffset) >= [data length]) { [self transitionToNextPhase]; } return (NSInteger)range.length; } - (BOOL)transitionToNextPhase { if (![[NSThread currentThread] isMainThread]) { dispatch_sync(dispatch_get_main_queue(), ^{ [self transitionToNextPhase]; }); return YES; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wcovered-switch-default" switch (_phase) { case AFEncapsulationBoundaryPhase: _phase = AFHeaderPhase; break; case AFHeaderPhase: [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; [self.inputStream open]; _phase = AFBodyPhase; break; case AFBodyPhase: [self.inputStream close]; _phase = AFFinalBoundaryPhase; break; case AFFinalBoundaryPhase: default: _phase = AFEncapsulationBoundaryPhase; break; } _phaseReadOffset = 0; #pragma clang diagnostic pop return YES; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFHTTPBodyPart *bodyPart = [[[self class] allocWithZone:zone] init]; bodyPart.stringEncoding = self.stringEncoding; bodyPart.headers = self.headers; bodyPart.bodyContentLength = self.bodyContentLength; bodyPart.body = self.body; bodyPart.boundary = self.boundary; return bodyPart; } @end #pragma mark - @implementation AFJSONRequestSerializer + (instancetype)serializer { return [self serializerWithWritingOptions:(NSJSONWritingOptions)0]; } + (instancetype)serializerWithWritingOptions:(NSJSONWritingOptions)writingOptions { AFJSONRequestSerializer *serializer = [[self alloc] init]; serializer.writingOptions = writingOptions; return serializer; } #pragma mark - AFURLRequestSerialization - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(request); if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { return [super requestBySerializingRequest:request withParameters:parameters error:error]; } NSMutableURLRequest *mutableRequest = [request mutableCopy]; [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { if (![request valueForHTTPHeaderField:field]) { [mutableRequest setValue:value forHTTPHeaderField:field]; } }]; if (parameters) { if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { [mutableRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; } [mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]]; } return mutableRequest; } #pragma mark - NSSecureCoding - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.writingOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(writingOptions))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeInteger:self.writingOptions forKey:NSStringFromSelector(@selector(writingOptions))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFJSONRequestSerializer *serializer = [super copyWithZone:zone]; serializer.writingOptions = self.writingOptions; return serializer; } @end #pragma mark - @implementation AFPropertyListRequestSerializer + (instancetype)serializer { return [self serializerWithFormat:NSPropertyListXMLFormat_v1_0 writeOptions:0]; } + (instancetype)serializerWithFormat:(NSPropertyListFormat)format writeOptions:(NSPropertyListWriteOptions)writeOptions { AFPropertyListRequestSerializer *serializer = [[self alloc] init]; serializer.format = format; serializer.writeOptions = writeOptions; return serializer; } #pragma mark - AFURLRequestSerializer - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(request); if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { return [super requestBySerializingRequest:request withParameters:parameters error:error]; } NSMutableURLRequest *mutableRequest = [request mutableCopy]; [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { if (![request valueForHTTPHeaderField:field]) { [mutableRequest setValue:value forHTTPHeaderField:field]; } }]; if (parameters) { if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { [mutableRequest setValue:@"application/x-plist" forHTTPHeaderField:@"Content-Type"]; } [mutableRequest setHTTPBody:[NSPropertyListSerialization dataWithPropertyList:parameters format:self.format options:self.writeOptions error:error]]; } return mutableRequest; } #pragma mark - NSSecureCoding - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.format = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(format))] unsignedIntegerValue]; self.writeOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(writeOptions))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeInteger:self.format forKey:NSStringFromSelector(@selector(format))]; [coder encodeObject:@(self.writeOptions) forKey:NSStringFromSelector(@selector(writeOptions))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFPropertyListRequestSerializer *serializer = [super copyWithZone:zone]; serializer.format = self.format; serializer.writeOptions = self.writeOptions; return serializer; } @end ================================================ FILE: shakefun/shakefun/AFNetworking/AFURLResponseSerialization.h ================================================ // AFURLResponseSerialization.h // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import NS_ASSUME_NONNULL_BEGIN /** The `AFURLResponseSerialization` protocol is adopted by an object that decodes data into a more useful object representation, according to details in the server response. Response serializers may additionally perform validation on the incoming response and data. For example, a JSON response serializer may check for an acceptable status code (`2XX` range) and content type (`application/json`), decoding a valid JSON response into an object. */ @protocol AFURLResponseSerialization /** The response object decoded from the data associated with a specified response. @param response The response to be processed. @param data The response data to be decoded. @param error The error that occurred while attempting to decode the response data. @return The object decoded from the specified response data. */ - (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response data:(nullable NSData *)data error:(NSError * __nullable __autoreleasing *)error; @end #pragma mark - /** `AFHTTPResponseSerializer` conforms to the `AFURLRequestSerialization` & `AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. Any request or response serializer dealing with HTTP is encouraged to subclass `AFHTTPResponseSerializer` in order to ensure consistent default behavior. */ @interface AFHTTPResponseSerializer : NSObject - (instancetype)init; /** The string encoding used to serialize data received from the server, when no string encoding is specified by the response. `NSUTF8StringEncoding` by default. */ @property (nonatomic, assign) NSStringEncoding stringEncoding; /** Creates and returns a serializer with default configuration. */ + (instancetype)serializer; ///----------------------------------------- /// @name Configuring Response Serialization ///----------------------------------------- /** The acceptable HTTP status codes for responses. When non-`nil`, responses with status codes not contained by the set will result in an error during validation. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html */ @property (nonatomic, copy, nullable) NSIndexSet *acceptableStatusCodes; /** The acceptable MIME types for responses. When non-`nil`, responses with a `Content-Type` with MIME types that do not intersect with the set will result in an error during validation. */ @property (nonatomic, copy, nullable) NSSet *acceptableContentTypes; /** Validates the specified response and data. In its base implementation, this method checks for an acceptable status code and content type. Subclasses may wish to add other domain-specific checks. @param response The response to be validated. @param data The data associated with the response. @param error The error that occurred while attempting to validate the response. @return `YES` if the response is valid, otherwise `NO`. */ - (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response data:(nullable NSData *)data error:(NSError * __nullable __autoreleasing *)error; @end #pragma mark - /** `AFJSONResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes JSON responses. By default, `AFJSONResponseSerializer` accepts the following MIME types, which includes the official standard, `application/json`, as well as other commonly-used types: - `application/json` - `text/json` - `text/javascript` */ @interface AFJSONResponseSerializer : AFHTTPResponseSerializer - (instancetype)init; /** Options for reading the response JSON data and creating the Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default. */ @property (nonatomic, assign) NSJSONReadingOptions readingOptions; /** Whether to remove keys with `NSNull` values from response JSON. Defaults to `NO`. */ @property (nonatomic, assign) BOOL removesKeysWithNullValues; /** Creates and returns a JSON serializer with specified reading and writing options. @param readingOptions The specified JSON reading options. */ + (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions; @end #pragma mark - /** `AFXMLParserResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLParser` objects. By default, `AFXMLParserResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types: - `application/xml` - `text/xml` */ @interface AFXMLParserResponseSerializer : AFHTTPResponseSerializer @end #pragma mark - #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED /** `AFXMLDocumentResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects. By default, `AFXMLDocumentResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types: - `application/xml` - `text/xml` */ @interface AFXMLDocumentResponseSerializer : AFHTTPResponseSerializer - (instancetype)init; /** Input and output options specifically intended for `NSXMLDocument` objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default. */ @property (nonatomic, assign) NSUInteger options; /** Creates and returns an XML document serializer with the specified options. @param mask The XML document options. */ + (instancetype)serializerWithXMLDocumentOptions:(NSUInteger)mask; @end #endif #pragma mark - /** `AFPropertyListResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects. By default, `AFPropertyListResponseSerializer` accepts the following MIME types: - `application/x-plist` */ @interface AFPropertyListResponseSerializer : AFHTTPResponseSerializer - (instancetype)init; /** The property list format. Possible values are described in "NSPropertyListFormat". */ @property (nonatomic, assign) NSPropertyListFormat format; /** The property list reading options. Possible values are described in "NSPropertyListMutabilityOptions." */ @property (nonatomic, assign) NSPropertyListReadOptions readOptions; /** Creates and returns a property list serializer with a specified format, read options, and write options. @param format The property list format. @param readOptions The property list reading options. */ + (instancetype)serializerWithFormat:(NSPropertyListFormat)format readOptions:(NSPropertyListReadOptions)readOptions; @end #pragma mark - /** `AFImageResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes image responses. By default, `AFImageResponseSerializer` accepts the following MIME types, which correspond to the image formats supported by UIImage or NSImage: - `image/tiff` - `image/jpeg` - `image/gif` - `image/png` - `image/ico` - `image/x-icon` - `image/bmp` - `image/x-bmp` - `image/x-xbitmap` - `image/x-win-bitmap` */ @interface AFImageResponseSerializer : AFHTTPResponseSerializer #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) /** The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance. */ @property (nonatomic, assign) CGFloat imageScale; /** Whether to automatically inflate response image data for compressed formats (such as PNG or JPEG). Enabling this can significantly improve drawing performance on iOS when used with `setCompletionBlockWithSuccess:failure:`, as it allows a bitmap representation to be constructed in the background rather than on the main thread. `YES` by default. */ @property (nonatomic, assign) BOOL automaticallyInflatesResponseImage; #endif @end #pragma mark - /** `AFCompoundSerializer` is a subclass of `AFHTTPResponseSerializer` that delegates the response serialization to the first `AFHTTPResponseSerializer` object that returns an object for `responseObjectForResponse:data:error:`, falling back on the default behavior of `AFHTTPResponseSerializer`. This is useful for supporting multiple potential types and structures of server responses with a single serializer. */ @interface AFCompoundResponseSerializer : AFHTTPResponseSerializer /** The component response serializers. */ @property (readonly, nonatomic, copy) NSArray *responseSerializers; /** Creates and returns a compound serializer comprised of the specified response serializers. @warning Each response serializer specified must be a subclass of `AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`. */ + (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers; @end ///---------------- /// @name Constants ///---------------- /** ## Error Domains The following error domain is predefined. - `NSString * const AFURLResponseSerializationErrorDomain` ### Constants `AFURLResponseSerializationErrorDomain` AFURLResponseSerializer errors. Error codes for `AFURLResponseSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`. */ extern NSString * const AFURLResponseSerializationErrorDomain; /** ## User info dictionary keys These keys may exist in the user info dictionary, in addition to those defined for NSError. - `NSString * const AFNetworkingOperationFailingURLResponseErrorKey` - `NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey` ### Constants `AFNetworkingOperationFailingURLResponseErrorKey` The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`. `AFNetworkingOperationFailingURLResponseDataErrorKey` The corresponding value is an `NSData` containing the original data of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`. */ extern NSString * const AFNetworkingOperationFailingURLResponseErrorKey; extern NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey; NS_ASSUME_NONNULL_END ================================================ FILE: shakefun/shakefun/AFNetworking/AFURLResponseSerialization.m ================================================ // AFURLResponseSerialization.m // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFURLResponseSerialization.h" #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #import #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) #import #endif NSString * const AFURLResponseSerializationErrorDomain = @"com.alamofire.error.serialization.response"; NSString * const AFNetworkingOperationFailingURLResponseErrorKey = @"com.alamofire.serialization.response.error.response"; NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey = @"com.alamofire.serialization.response.error.data"; static NSError * AFErrorWithUnderlyingError(NSError *error, NSError *underlyingError) { if (!error) { return underlyingError; } if (!underlyingError || error.userInfo[NSUnderlyingErrorKey]) { return error; } NSMutableDictionary *mutableUserInfo = [error.userInfo mutableCopy]; mutableUserInfo[NSUnderlyingErrorKey] = underlyingError; return [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:mutableUserInfo]; } static BOOL AFErrorOrUnderlyingErrorHasCodeInDomain(NSError *error, NSInteger code, NSString *domain) { if ([error.domain isEqualToString:domain] && error.code == code) { return YES; } else if (error.userInfo[NSUnderlyingErrorKey]) { return AFErrorOrUnderlyingErrorHasCodeInDomain(error.userInfo[NSUnderlyingErrorKey], code, domain); } return NO; } static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingOptions readingOptions) { if ([JSONObject isKindOfClass:[NSArray class]]) { NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)JSONObject count]]; for (id value in (NSArray *)JSONObject) { [mutableArray addObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions)]; } return (readingOptions & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray]; } else if ([JSONObject isKindOfClass:[NSDictionary class]]) { NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:JSONObject]; for (id key in [(NSDictionary *)JSONObject allKeys]) { id value = (NSDictionary *)JSONObject[key]; if (!value || [value isEqual:[NSNull null]]) { [mutableDictionary removeObjectForKey:key]; } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) { mutableDictionary[key] = AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions); } } return (readingOptions & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary]; } return JSONObject; } @implementation AFHTTPResponseSerializer + (instancetype)serializer { return [[self alloc] init]; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.stringEncoding = NSUTF8StringEncoding; self.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)]; self.acceptableContentTypes = nil; return self; } #pragma mark - - (BOOL)validateResponse:(NSHTTPURLResponse *)response data:(NSData *)data error:(NSError * __autoreleasing *)error { BOOL responseIsValid = YES; NSError *validationError = nil; if (response && [response isKindOfClass:[NSHTTPURLResponse class]]) { if (self.acceptableContentTypes && ![self.acceptableContentTypes containsObject:[response MIMEType]]) { if ([data length] > 0 && [response URL]) { NSMutableDictionary *mutableUserInfo = [@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: unacceptable content-type: %@", @"AFNetworking", nil), [response MIMEType]], NSURLErrorFailingURLErrorKey:[response URL], AFNetworkingOperationFailingURLResponseErrorKey: response, } mutableCopy]; if (data) { mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data; } validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:mutableUserInfo], validationError); } responseIsValid = NO; } if (self.acceptableStatusCodes && ![self.acceptableStatusCodes containsIndex:(NSUInteger)response.statusCode] && [response URL]) { NSMutableDictionary *mutableUserInfo = [@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: %@ (%ld)", @"AFNetworking", nil), [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], (long)response.statusCode], NSURLErrorFailingURLErrorKey:[response URL], AFNetworkingOperationFailingURLResponseErrorKey: response, } mutableCopy]; if (data) { mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data; } validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorBadServerResponse userInfo:mutableUserInfo], validationError); responseIsValid = NO; } } if (error && !responseIsValid) { *error = validationError; } return responseIsValid; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { [self validateResponse:(NSHTTPURLResponse *)response data:data error:error]; return data; } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { self = [self init]; if (!self) { return nil; } self.acceptableStatusCodes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableStatusCodes))]; self.acceptableContentTypes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableContentTypes))]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:self.acceptableStatusCodes forKey:NSStringFromSelector(@selector(acceptableStatusCodes))]; [coder encodeObject:self.acceptableContentTypes forKey:NSStringFromSelector(@selector(acceptableContentTypes))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFHTTPResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.acceptableStatusCodes = [self.acceptableStatusCodes copyWithZone:zone]; serializer.acceptableContentTypes = [self.acceptableContentTypes copyWithZone:zone]; return serializer; } @end #pragma mark - @implementation AFJSONResponseSerializer + (instancetype)serializer { return [self serializerWithReadingOptions:(NSJSONReadingOptions)0]; } + (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions { AFJSONResponseSerializer *serializer = [[self alloc] init]; serializer.readingOptions = readingOptions; return serializer; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil]; return self; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } // Workaround for behavior of Rails to return a single space for `head :ok` (a workaround for a bug in Safari), which is not interpreted as valid input by NSJSONSerialization. // See https://github.com/rails/rails/issues/1742 NSStringEncoding stringEncoding = self.stringEncoding; if (response.textEncodingName) { CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName); if (encoding != kCFStringEncodingInvalidId) { stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding); } } id responseObject = nil; NSError *serializationError = nil; @autoreleasepool { NSString *responseString = [[NSString alloc] initWithData:data encoding:stringEncoding]; if (responseString && ![responseString isEqualToString:@" "]) { // Workaround for a bug in NSJSONSerialization when Unicode character escape codes are used instead of the actual character // See http://stackoverflow.com/a/12843465/157142 data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; if (data) { if ([data length] > 0) { responseObject = [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError]; } else { return nil; } } else { NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string", @"AFNetworking", nil), NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", @"AFNetworking", nil), responseString] }; serializationError = [NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo]; } } } if (self.removesKeysWithNullValues && responseObject) { responseObject = AFJSONObjectByRemovingKeysWithNullValues(responseObject, self.readingOptions); } if (error) { *error = AFErrorWithUnderlyingError(serializationError, *error); } return responseObject; } #pragma mark - NSSecureCoding - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.readingOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readingOptions))] unsignedIntegerValue]; self.removesKeysWithNullValues = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(removesKeysWithNullValues))] boolValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:@(self.readingOptions) forKey:NSStringFromSelector(@selector(readingOptions))]; [coder encodeObject:@(self.removesKeysWithNullValues) forKey:NSStringFromSelector(@selector(removesKeysWithNullValues))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFJSONResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.readingOptions = self.readingOptions; serializer.removesKeysWithNullValues = self.removesKeysWithNullValues; return serializer; } @end #pragma mark - @implementation AFXMLParserResponseSerializer + (instancetype)serializer { AFXMLParserResponseSerializer *serializer = [[self alloc] init]; return serializer; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil]; return self; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSHTTPURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } return [[NSXMLParser alloc] initWithData:data]; } @end #pragma mark - #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED @implementation AFXMLDocumentResponseSerializer + (instancetype)serializer { return [self serializerWithXMLDocumentOptions:0]; } + (instancetype)serializerWithXMLDocumentOptions:(NSUInteger)mask { AFXMLDocumentResponseSerializer *serializer = [[self alloc] init]; serializer.options = mask; return serializer; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil]; return self; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } NSError *serializationError = nil; NSXMLDocument *document = [[NSXMLDocument alloc] initWithData:data options:self.options error:&serializationError]; if (error) { *error = AFErrorWithUnderlyingError(serializationError, *error); } return document; } #pragma mark - NSSecureCoding - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.options = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(options))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:@(self.options) forKey:NSStringFromSelector(@selector(options))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFXMLDocumentResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.options = self.options; return serializer; } @end #endif #pragma mark - @implementation AFPropertyListResponseSerializer + (instancetype)serializer { return [self serializerWithFormat:NSPropertyListXMLFormat_v1_0 readOptions:0]; } + (instancetype)serializerWithFormat:(NSPropertyListFormat)format readOptions:(NSPropertyListReadOptions)readOptions { AFPropertyListResponseSerializer *serializer = [[self alloc] init]; serializer.format = format; serializer.readOptions = readOptions; return serializer; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/x-plist", nil]; return self; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } id responseObject; NSError *serializationError = nil; if (data) { responseObject = [NSPropertyListSerialization propertyListWithData:data options:self.readOptions format:NULL error:&serializationError]; } if (error) { *error = AFErrorWithUnderlyingError(serializationError, *error); } return responseObject; } #pragma mark - NSSecureCoding - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.format = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(format))] unsignedIntegerValue]; self.readOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readOptions))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:@(self.format) forKey:NSStringFromSelector(@selector(format))]; [coder encodeObject:@(self.readOptions) forKey:NSStringFromSelector(@selector(readOptions))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFPropertyListResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.format = self.format; serializer.readOptions = self.readOptions; return serializer; } @end #pragma mark - #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) #import @interface UIImage (AFNetworkingSafeImageLoading) + (UIImage *)af_safeImageWithData:(NSData *)data; @end static NSLock* imageLock = nil; @implementation UIImage (AFNetworkingSafeImageLoading) + (UIImage *)af_safeImageWithData:(NSData *)data { UIImage* image = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ imageLock = [[NSLock alloc] init]; }); [imageLock lock]; image = [UIImage imageWithData:data]; [imageLock unlock]; return image; } @end static UIImage * AFImageWithDataAtScale(NSData *data, CGFloat scale) { UIImage *image = [UIImage af_safeImageWithData:data]; if (image.images) { return image; } return [[UIImage alloc] initWithCGImage:[image CGImage] scale:scale orientation:image.imageOrientation]; } static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *response, NSData *data, CGFloat scale) { if (!data || [data length] == 0) { return nil; } CGImageRef imageRef = NULL; CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); if ([response.MIMEType isEqualToString:@"image/png"]) { imageRef = CGImageCreateWithPNGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault); } else if ([response.MIMEType isEqualToString:@"image/jpeg"]) { imageRef = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault); if (imageRef) { CGColorSpaceRef imageColorSpace = CGImageGetColorSpace(imageRef); CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(imageColorSpace); // CGImageCreateWithJPEGDataProvider does not properly handle CMKY, so fall back to AFImageWithDataAtScale if (imageColorSpaceModel == kCGColorSpaceModelCMYK) { CGImageRelease(imageRef); imageRef = NULL; } } } CGDataProviderRelease(dataProvider); UIImage *image = AFImageWithDataAtScale(data, scale); if (!imageRef) { if (image.images || !image) { return image; } imageRef = CGImageCreateCopy([image CGImage]); if (!imageRef) { return nil; } } size_t width = CGImageGetWidth(imageRef); size_t height = CGImageGetHeight(imageRef); size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); if (width * height > 1024 * 1024 || bitsPerComponent > 8) { CGImageRelease(imageRef); return image; } // CGImageGetBytesPerRow() calculates incorrectly in iOS 5.0, so defer to CGBitmapContextCreate size_t bytesPerRow = 0; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); if (colorSpaceModel == kCGColorSpaceModelRGB) { uint32_t alpha = (bitmapInfo & kCGBitmapAlphaInfoMask); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wassign-enum" if (alpha == kCGImageAlphaNone) { bitmapInfo &= ~kCGBitmapAlphaInfoMask; bitmapInfo |= kCGImageAlphaNoneSkipFirst; } else if (!(alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast)) { bitmapInfo &= ~kCGBitmapAlphaInfoMask; bitmapInfo |= kCGImageAlphaPremultipliedFirst; } #pragma clang diagnostic pop } CGContextRef context = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); CGColorSpaceRelease(colorSpace); if (!context) { CGImageRelease(imageRef); return image; } CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), imageRef); CGImageRef inflatedImageRef = CGBitmapContextCreateImage(context); CGContextRelease(context); UIImage *inflatedImage = [[UIImage alloc] initWithCGImage:inflatedImageRef scale:scale orientation:image.imageOrientation]; CGImageRelease(inflatedImageRef); CGImageRelease(imageRef); return inflatedImage; } #endif @implementation AFImageResponseSerializer - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"image/tiff", @"image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil]; #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) self.imageScale = [[UIScreen mainScreen] scale]; self.automaticallyInflatesResponseImage = YES; #endif return self; } #pragma mark - AFURLResponseSerializer - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) if (self.automaticallyInflatesResponseImage) { return AFInflatedImageFromResponseWithDataAtScale((NSHTTPURLResponse *)response, data, self.imageScale); } else { return AFImageWithDataAtScale(data, self.imageScale); } #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) // Ensure that the image is set to it's correct pixel width and height NSBitmapImageRep *bitimage = [[NSBitmapImageRep alloc] initWithData:data]; NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize([bitimage pixelsWide], [bitimage pixelsHigh])]; [image addRepresentation:bitimage]; return image; #endif return nil; } #pragma mark - NSSecureCoding - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) NSNumber *imageScale = [decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(imageScale))]; #if CGFLOAT_IS_DOUBLE self.imageScale = [imageScale doubleValue]; #else self.imageScale = [imageScale floatValue]; #endif self.automaticallyInflatesResponseImage = [decoder decodeBoolForKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))]; #endif return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) [coder encodeObject:@(self.imageScale) forKey:NSStringFromSelector(@selector(imageScale))]; [coder encodeBool:self.automaticallyInflatesResponseImage forKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))]; #endif } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFImageResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) serializer.imageScale = self.imageScale; serializer.automaticallyInflatesResponseImage = self.automaticallyInflatesResponseImage; #endif return serializer; } @end #pragma mark - @interface AFCompoundResponseSerializer () @property (readwrite, nonatomic, copy) NSArray *responseSerializers; @end @implementation AFCompoundResponseSerializer + (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers { AFCompoundResponseSerializer *serializer = [[self alloc] init]; serializer.responseSerializers = responseSerializers; return serializer; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { for (id serializer in self.responseSerializers) { if (![serializer isKindOfClass:[AFHTTPResponseSerializer class]]) { continue; } NSError *serializerError = nil; id responseObject = [serializer responseObjectForResponse:response data:data error:&serializerError]; if (responseObject) { if (error) { *error = AFErrorWithUnderlyingError(serializerError, *error); } return responseObject; } } return [super responseObjectForResponse:response data:data error:error]; } #pragma mark - NSSecureCoding - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.responseSerializers = [decoder decodeObjectOfClass:[NSArray class] forKey:NSStringFromSelector(@selector(responseSerializers))]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:self.responseSerializers forKey:NSStringFromSelector(@selector(responseSerializers))]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { AFCompoundResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.responseSerializers = self.responseSerializers; return serializer; } @end ================================================ FILE: shakefun/shakefun/AFNetworking/AFURLSessionManager.h ================================================ // AFURLSessionManager.h // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import "AFURLResponseSerialization.h" #import "AFURLRequestSerialization.h" #import "AFSecurityPolicy.h" #import "AFNetworkReachabilityManager.h" #ifndef NS_DESIGNATED_INITIALIZER #if __has_attribute(objc_designated_initializer) #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) #else #define NS_DESIGNATED_INITIALIZER #endif #endif /** `AFURLSessionManager` creates and manages an `NSURLSession` object based on a specified `NSURLSessionConfiguration` object, which conforms to ``, ``, ``, and ``. ## Subclassing Notes This is the base class for `AFHTTPSessionManager`, which adds functionality specific to making HTTP requests. If you are looking to extend `AFURLSessionManager` specifically for HTTP, consider subclassing `AFHTTPSessionManager` instead. ## NSURLSession & NSURLSessionTask Delegate Methods `AFURLSessionManager` implements the following delegate methods: ### `NSURLSessionDelegate` - `URLSession:didBecomeInvalidWithError:` - `URLSession:didReceiveChallenge:completionHandler:` - `URLSessionDidFinishEventsForBackgroundURLSession:` ### `NSURLSessionTaskDelegate` - `URLSession:willPerformHTTPRedirection:newRequest:completionHandler:` - `URLSession:task:didReceiveChallenge:completionHandler:` - `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:` - `URLSession:task:didCompleteWithError:` ### `NSURLSessionDataDelegate` - `URLSession:dataTask:didReceiveResponse:completionHandler:` - `URLSession:dataTask:didBecomeDownloadTask:` - `URLSession:dataTask:didReceiveData:` - `URLSession:dataTask:willCacheResponse:completionHandler:` ### `NSURLSessionDownloadDelegate` - `URLSession:downloadTask:didFinishDownloadingToURL:` - `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:` - `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:` If any of these methods are overridden in a subclass, they _must_ call the `super` implementation first. ## Network Reachability Monitoring Network reachability status and change monitoring is available through the `reachabilityManager` property. Applications may choose to monitor network reachability conditions in order to prevent or suspend any outbound requests. See `AFNetworkReachabilityManager` for more details. ## NSCoding Caveats - Encoded managers do not include any block properties. Be sure to set delegate callback blocks when using `-initWithCoder:` or `NSKeyedUnarchiver`. ## NSCopying Caveats - `-copy` and `-copyWithZone:` return a new manager with a new `NSURLSession` created from the configuration of the original. - Operation copies do not include any delegate callback blocks, as they often strongly captures a reference to `self`, which would otherwise have the unintuitive side-effect of pointing to the _original_ session manager when copied. @warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance. */ NS_ASSUME_NONNULL_BEGIN #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) @interface AFURLSessionManager : NSObject /** The managed session. */ @property (readonly, nonatomic, strong) NSURLSession *session; /** The operation queue on which delegate callbacks are run. */ @property (readonly, nonatomic, strong) NSOperationQueue *operationQueue; /** Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `AFJSONResponseSerializer`. @warning `responseSerializer` must not be `nil`. */ @property (nonatomic, strong) id responseSerializer; ///------------------------------- /// @name Managing Security Policy ///------------------------------- /** The security policy used by created request operations to evaluate server trust for secure connections. `AFURLSessionManager` uses the `defaultPolicy` unless otherwise specified. */ @property (nonatomic, strong) AFSecurityPolicy *securityPolicy; ///-------------------------------------- /// @name Monitoring Network Reachability ///-------------------------------------- /** The network reachability manager. `AFURLSessionManager` uses the `sharedManager` by default. */ @property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager; ///---------------------------- /// @name Getting Session Tasks ///---------------------------- /** The data, upload, and download tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray *tasks; /** The data tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray *dataTasks; /** The upload tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray *uploadTasks; /** The download tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray *downloadTasks; ///------------------------------- /// @name Managing Callback Queues ///------------------------------- /** The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. */ #if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong, nullable) dispatch_queue_t completionQueue; #else @property (nonatomic, assign, nullable) dispatch_queue_t completionQueue; #endif /** The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. */ #if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong, nullable) dispatch_group_t completionGroup; #else @property (nonatomic, assign, nullable) dispatch_group_t completionGroup; #endif ///--------------------------------- /// @name Working Around System Bugs ///--------------------------------- /** Whether to attempt to retry creation of upload tasks for background sessions when initial call returns `nil`. `NO` by default. @bug As of iOS 7.0, there is a bug where upload tasks created for background tasks are sometimes `nil`. As a workaround, if this property is `YES`, AFNetworking will follow Apple's recommendation to try creating the task again. @see https://github.com/AFNetworking/AFNetworking/issues/1675 */ @property (nonatomic, assign) BOOL attemptsToRecreateUploadTasksForBackgroundSessions; ///--------------------- /// @name Initialization ///--------------------- /** Creates and returns a manager for a session created with the specified configuration. This is the designated initializer. @param configuration The configuration used to create the managed session. @return A manager for a newly-created session. */ - (instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; /** Invalidates the managed session, optionally canceling pending tasks. @param cancelPendingTasks Whether or not to cancel pending tasks. */ - (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks; ///------------------------- /// @name Running Data Tasks ///------------------------- /** Creates an `NSURLSessionDataTask` with the specified request. @param request The HTTP request for the request. @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. */ - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(nullable void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler; ///--------------------------- /// @name Running Upload Tasks ///--------------------------- /** Creates an `NSURLSessionUploadTask` with the specified request for a local file. @param request The HTTP request for the request. @param fileURL A URL to the local file to be uploaded. @param progress A progress object monitoring the current upload progress. @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. @see `attemptsToRecreateUploadTasksForBackgroundSessions` */ - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL progress:(NSProgress * __nullable __autoreleasing * __nullable)progress completionHandler:(nullable void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler; /** Creates an `NSURLSessionUploadTask` with the specified request for an HTTP body. @param request The HTTP request for the request. @param bodyData A data object containing the HTTP body to be uploaded. @param progress A progress object monitoring the current upload progress. @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. */ - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData progress:(NSProgress * __nullable __autoreleasing * __nullable)progress completionHandler:(nullable void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler; /** Creates an `NSURLSessionUploadTask` with the specified streaming request. @param request The HTTP request for the request. @param progress A progress object monitoring the current upload progress. @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. */ - (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request progress:(NSProgress * __nullable __autoreleasing * __nullable)progress completionHandler:(nullable void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler; ///----------------------------- /// @name Running Download Tasks ///----------------------------- /** Creates an `NSURLSessionDownloadTask` with the specified request. @param request The HTTP request for the request. @param progress A progress object monitoring the current download progress. @param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL. @param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any. @warning If using a background `NSURLSessionConfiguration` on iOS, these blocks will be lost when the app is terminated. Background sessions may prefer to use `-setDownloadTaskDidFinishDownloadingBlock:` to specify the URL for saving the downloaded file, rather than the destination block of this method. */ - (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request progress:(NSProgress * __nullable __autoreleasing * __nullable)progress destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(nullable void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler; /** Creates an `NSURLSessionDownloadTask` with the specified resume data. @param resumeData The data used to resume downloading. @param progress A progress object monitoring the current download progress. @param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL. @param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any. */ - (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData progress:(NSProgress * __nullable __autoreleasing * __nullable)progress destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(nullable void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler; ///--------------------------------- /// @name Getting Progress for Tasks ///--------------------------------- /** Returns the upload progress of the specified task. @param uploadTask The session upload task. Must not be `nil`. @return An `NSProgress` object reporting the upload progress of a task, or `nil` if the progress is unavailable. */ - (nullable NSProgress *)uploadProgressForTask:(NSURLSessionUploadTask *)uploadTask; /** Returns the download progress of the specified task. @param downloadTask The session download task. Must not be `nil`. @return An `NSProgress` object reporting the download progress of a task, or `nil` if the progress is unavailable. */ - (nullable NSProgress *)downloadProgressForTask:(NSURLSessionDownloadTask *)downloadTask; ///----------------------------------------- /// @name Setting Session Delegate Callbacks ///----------------------------------------- /** Sets a block to be executed when the managed session becomes invalid, as handled by the `NSURLSessionDelegate` method `URLSession:didBecomeInvalidWithError:`. @param block A block object to be executed when the managed session becomes invalid. The block has no return value, and takes two arguments: the session, and the error related to the cause of invalidation. */ - (void)setSessionDidBecomeInvalidBlock:(nullable void (^)(NSURLSession *session, NSError *error))block; /** Sets a block to be executed when a connection level authentication challenge has occurred, as handled by the `NSURLSessionDelegate` method `URLSession:didReceiveChallenge:completionHandler:`. @param block A block object to be executed when a connection level authentication challenge has occurred. The block returns the disposition of the authentication challenge, and takes three arguments: the session, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge. */ - (void)setSessionDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __nullable __autoreleasing * __nullable credential))block; ///-------------------------------------- /// @name Setting Task Delegate Callbacks ///-------------------------------------- /** Sets a block to be executed when a task requires a new request body stream to send to the remote server, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:needNewBodyStream:`. @param block A block object to be executed when a task requires a new request body stream. */ - (void)setTaskNeedNewBodyStreamBlock:(nullable NSInputStream * (^)(NSURLSession *session, NSURLSessionTask *task))block; /** Sets a block to be executed when an HTTP request is attempting to perform a redirection to a different URL, as handled by the `NSURLSessionTaskDelegate` method `URLSession:willPerformHTTPRedirection:newRequest:completionHandler:`. @param block A block object to be executed when an HTTP request is attempting to perform a redirection to a different URL. The block returns the request to be made for the redirection, and takes four arguments: the session, the task, the redirection response, and the request corresponding to the redirection response. */ - (void)setTaskWillPerformHTTPRedirectionBlock:(nullable NSURLRequest * (^)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request))block; /** Sets a block to be executed when a session task has received a request specific authentication challenge, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didReceiveChallenge:completionHandler:`. @param block A block object to be executed when a session task has received a request specific authentication challenge. The block returns the disposition of the authentication challenge, and takes four arguments: the session, the task, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge. */ - (void)setTaskDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __nullable __autoreleasing * __nullable credential))block; /** Sets a block to be executed periodically to track upload progress, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`. @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes five arguments: the session, the task, the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread. */ - (void)setTaskDidSendBodyDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend))block; /** Sets a block to be executed as the last message related to a specific task, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didCompleteWithError:`. @param block A block object to be executed when a session task is completed. The block has no return value, and takes three arguments: the session, the task, and any error that occurred in the process of executing the task. */ - (void)setTaskDidCompleteBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, NSError *error))block; ///------------------------------------------- /// @name Setting Data Task Delegate Callbacks ///------------------------------------------- /** Sets a block to be executed when a data task has received a response, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didReceiveResponse:completionHandler:`. @param block A block object to be executed when a data task has received a response. The block returns the disposition of the session response, and takes three arguments: the session, the data task, and the received response. */ - (void)setDataTaskDidReceiveResponseBlock:(nullable NSURLSessionResponseDisposition (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response))block; /** Sets a block to be executed when a data task has become a download task, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didBecomeDownloadTask:`. @param block A block object to be executed when a data task has become a download task. The block has no return value, and takes three arguments: the session, the data task, and the download task it has become. */ - (void)setDataTaskDidBecomeDownloadTaskBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask))block; /** Sets a block to be executed when a data task receives data, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didReceiveData:`. @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the session, the data task, and the data received. This block may be called multiple times, and will execute on the session manager operation queue. */ - (void)setDataTaskDidReceiveDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data))block; /** Sets a block to be executed to determine the caching behavior of a data task, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:willCacheResponse:completionHandler:`. @param block A block object to be executed to determine the caching behavior of a data task. The block returns the response to cache, and takes three arguments: the session, the data task, and the proposed cached URL response. */ - (void)setDataTaskWillCacheResponseBlock:(nullable NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block; /** Sets a block to be executed once all messages enqueued for a session have been delivered, as handled by the `NSURLSessionDataDelegate` method `URLSessionDidFinishEventsForBackgroundURLSession:`. @param block A block object to be executed once all messages enqueued for a session have been delivered. The block has no return value and takes a single argument: the session. */ - (void)setDidFinishEventsForBackgroundURLSessionBlock:(nullable void (^)(NSURLSession *session))block; ///----------------------------------------------- /// @name Setting Download Task Delegate Callbacks ///----------------------------------------------- /** Sets a block to be executed when a download task has completed a download, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didFinishDownloadingToURL:`. @param block A block object to be executed when a download task has completed. The block returns the URL the download should be moved to, and takes three arguments: the session, the download task, and the temporary location of the downloaded file. If the file manager encounters an error while attempting to move the temporary file to the destination, an `AFURLSessionDownloadTaskDidFailToMoveFileNotification` will be posted, with the download task as its object, and the user info of the error. */ - (void)setDownloadTaskDidFinishDownloadingBlock:(nullable NSURL * (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block; /** Sets a block to be executed periodically to track download progress, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:`. @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes five arguments: the session, the download task, the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the session manager operation queue. */ - (void)setDownloadTaskDidWriteDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite))block; /** Sets a block to be executed when a download task has been resumed, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:`. @param block A block object to be executed when a download task has been resumed. The block has no return value and takes four arguments: the session, the download task, the file offset of the resumed download, and the total number of bytes expected to be downloaded. */ - (void)setDownloadTaskDidResumeBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes))block; @end #endif ///-------------------- /// @name Notifications ///-------------------- /** Posted when a task begins executing. @deprecated Use `AFNetworkingTaskDidResumeNotification` instead. */ extern NSString * const AFNetworkingTaskDidStartNotification DEPRECATED_ATTRIBUTE; /** Posted when a task resumes. */ extern NSString * const AFNetworkingTaskDidResumeNotification; /** Posted when a task finishes executing. Includes a userInfo dictionary with additional information about the task. @deprecated Use `AFNetworkingTaskDidCompleteNotification` instead. */ extern NSString * const AFNetworkingTaskDidFinishNotification DEPRECATED_ATTRIBUTE; /** Posted when a task finishes executing. Includes a userInfo dictionary with additional information about the task. */ extern NSString * const AFNetworkingTaskDidCompleteNotification; /** Posted when a task suspends its execution. */ extern NSString * const AFNetworkingTaskDidSuspendNotification; /** Posted when a session is invalidated. */ extern NSString * const AFURLSessionDidInvalidateNotification; /** Posted when a session download task encountered an error when moving the temporary download file to a specified destination. */ extern NSString * const AFURLSessionDownloadTaskDidFailToMoveFileNotification; /** The raw response data of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if response data exists for the task. @deprecated Use `AFNetworkingTaskDidCompleteResponseDataKey` instead. */ extern NSString * const AFNetworkingTaskDidFinishResponseDataKey DEPRECATED_ATTRIBUTE; /** The raw response data of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if response data exists for the task. */ extern NSString * const AFNetworkingTaskDidCompleteResponseDataKey; /** The serialized response object of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the response was serialized. @deprecated Use `AFNetworkingTaskDidCompleteSerializedResponseKey` instead. */ extern NSString * const AFNetworkingTaskDidFinishSerializedResponseKey DEPRECATED_ATTRIBUTE; /** The serialized response object of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the response was serialized. */ extern NSString * const AFNetworkingTaskDidCompleteSerializedResponseKey; /** The response serializer used to serialize the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the task has an associated response serializer. @deprecated Use `AFNetworkingTaskDidCompleteResponseSerializerKey` instead. */ extern NSString * const AFNetworkingTaskDidFinishResponseSerializerKey DEPRECATED_ATTRIBUTE; /** The response serializer used to serialize the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the task has an associated response serializer. */ extern NSString * const AFNetworkingTaskDidCompleteResponseSerializerKey; /** The file path associated with the download task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an the response data has been stored directly to disk. @deprecated Use `AFNetworkingTaskDidCompleteAssetPathKey` instead. */ extern NSString * const AFNetworkingTaskDidFinishAssetPathKey DEPRECATED_ATTRIBUTE; /** The file path associated with the download task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an the response data has been stored directly to disk. */ extern NSString * const AFNetworkingTaskDidCompleteAssetPathKey; /** Any error associated with the task, or the serialization of the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an error exists. @deprecated Use `AFNetworkingTaskDidCompleteErrorKey` instead. */ extern NSString * const AFNetworkingTaskDidFinishErrorKey DEPRECATED_ATTRIBUTE; /** Any error associated with the task, or the serialization of the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an error exists. */ extern NSString * const AFNetworkingTaskDidCompleteErrorKey; NS_ASSUME_NONNULL_END ================================================ FILE: shakefun/shakefun/AFNetworking/AFURLSessionManager.m ================================================ // AFURLSessionManager.m // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFURLSessionManager.h" #import #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) static dispatch_queue_t url_session_manager_creation_queue() { static dispatch_queue_t af_url_session_manager_creation_queue; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_url_session_manager_creation_queue = dispatch_queue_create("com.alamofire.networking.session.manager.creation", DISPATCH_QUEUE_SERIAL); }); return af_url_session_manager_creation_queue; } static dispatch_queue_t url_session_manager_processing_queue() { static dispatch_queue_t af_url_session_manager_processing_queue; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_url_session_manager_processing_queue = dispatch_queue_create("com.alamofire.networking.session.manager.processing", DISPATCH_QUEUE_CONCURRENT); }); return af_url_session_manager_processing_queue; } static dispatch_group_t url_session_manager_completion_group() { static dispatch_group_t af_url_session_manager_completion_group; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_url_session_manager_completion_group = dispatch_group_create(); }); return af_url_session_manager_completion_group; } NSString * const AFNetworkingTaskDidResumeNotification = @"com.alamofire.networking.task.resume"; NSString * const AFNetworkingTaskDidCompleteNotification = @"com.alamofire.networking.task.complete"; NSString * const AFNetworkingTaskDidSuspendNotification = @"com.alamofire.networking.task.suspend"; NSString * const AFURLSessionDidInvalidateNotification = @"com.alamofire.networking.session.invalidate"; NSString * const AFURLSessionDownloadTaskDidFailToMoveFileNotification = @"com.alamofire.networking.session.download.file-manager-error"; NSString * const AFNetworkingTaskDidStartNotification = @"com.alamofire.networking.task.resume"; // Deprecated NSString * const AFNetworkingTaskDidFinishNotification = @"com.alamofire.networking.task.complete"; // Deprecated NSString * const AFNetworkingTaskDidCompleteSerializedResponseKey = @"com.alamofire.networking.task.complete.serializedresponse"; NSString * const AFNetworkingTaskDidCompleteResponseSerializerKey = @"com.alamofire.networking.task.complete.responseserializer"; NSString * const AFNetworkingTaskDidCompleteResponseDataKey = @"com.alamofire.networking.complete.finish.responsedata"; NSString * const AFNetworkingTaskDidCompleteErrorKey = @"com.alamofire.networking.task.complete.error"; NSString * const AFNetworkingTaskDidCompleteAssetPathKey = @"com.alamofire.networking.task.complete.assetpath"; NSString * const AFNetworkingTaskDidFinishSerializedResponseKey = @"com.alamofire.networking.task.complete.serializedresponse"; // Deprecated NSString * const AFNetworkingTaskDidFinishResponseSerializerKey = @"com.alamofire.networking.task.complete.responseserializer"; // Deprecated NSString * const AFNetworkingTaskDidFinishResponseDataKey = @"com.alamofire.networking.complete.finish.responsedata"; // Deprecated NSString * const AFNetworkingTaskDidFinishErrorKey = @"com.alamofire.networking.task.complete.error"; // Deprecated NSString * const AFNetworkingTaskDidFinishAssetPathKey = @"com.alamofire.networking.task.complete.assetpath"; // Deprecated static NSString * const AFURLSessionManagerLockName = @"com.alamofire.networking.session.manager.lock"; static NSUInteger const AFMaximumNumberOfAttemptsToRecreateBackgroundSessionUploadTask = 3; static void * AFTaskStateChangedContext = &AFTaskStateChangedContext; typedef void (^AFURLSessionDidBecomeInvalidBlock)(NSURLSession *session, NSError *error); typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionDidReceiveAuthenticationChallengeBlock)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential); typedef NSURLRequest * (^AFURLSessionTaskWillPerformHTTPRedirectionBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request); typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionTaskDidReceiveAuthenticationChallengeBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential); typedef void (^AFURLSessionDidFinishEventsForBackgroundURLSessionBlock)(NSURLSession *session); typedef NSInputStream * (^AFURLSessionTaskNeedNewBodyStreamBlock)(NSURLSession *session, NSURLSessionTask *task); typedef void (^AFURLSessionTaskDidSendBodyDataBlock)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend); typedef void (^AFURLSessionTaskDidCompleteBlock)(NSURLSession *session, NSURLSessionTask *task, NSError *error); typedef NSURLSessionResponseDisposition (^AFURLSessionDataTaskDidReceiveResponseBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response); typedef void (^AFURLSessionDataTaskDidBecomeDownloadTaskBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask); typedef void (^AFURLSessionDataTaskDidReceiveDataBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data); typedef NSCachedURLResponse * (^AFURLSessionDataTaskWillCacheResponseBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse); typedef NSURL * (^AFURLSessionDownloadTaskDidFinishDownloadingBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location); typedef void (^AFURLSessionDownloadTaskDidWriteDataBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite); typedef void (^AFURLSessionDownloadTaskDidResumeBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes); typedef void (^AFURLSessionTaskCompletionHandler)(NSURLResponse *response, id responseObject, NSError *error); #pragma mark - @interface AFURLSessionManagerTaskDelegate : NSObject @property (nonatomic, weak) AFURLSessionManager *manager; @property (nonatomic, strong) NSMutableData *mutableData; @property (nonatomic, strong) NSProgress *progress; @property (nonatomic, copy) NSURL *downloadFileURL; @property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading; @property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler; @end @implementation AFURLSessionManagerTaskDelegate - (instancetype)init { self = [super init]; if (!self) { return nil; } self.mutableData = [NSMutableData data]; self.progress = [NSProgress progressWithTotalUnitCount:0]; return self; } #pragma mark - NSURLSessionTaskDelegate - (void)URLSession:(__unused NSURLSession *)session task:(__unused NSURLSessionTask *)task didSendBodyData:(__unused int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { self.progress.totalUnitCount = totalBytesExpectedToSend; self.progress.completedUnitCount = totalBytesSent; } - (void)URLSession:(__unused NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" __strong AFURLSessionManager *manager = self.manager; __block id responseObject = nil; __block NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer; //Performance Improvement from #2672 NSData *data = nil; if (self.mutableData) { data = [self.mutableData copy]; //We no longer need the reference, so nil it out to gain back some memory. self.mutableData = nil; } if (self.downloadFileURL) { userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL; } else if (data) { userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data; } if (error) { userInfo[AFNetworkingTaskDidCompleteErrorKey] = error; dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{ if (self.completionHandler) { self.completionHandler(task.response, responseObject, error); } dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo]; }); }); } else { dispatch_async(url_session_manager_processing_queue(), ^{ NSError *serializationError = nil; responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError]; if (self.downloadFileURL) { responseObject = self.downloadFileURL; } if (responseObject) { userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject; } if (serializationError) { userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError; } dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{ if (self.completionHandler) { self.completionHandler(task.response, responseObject, serializationError); } dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo]; }); }); }); } #pragma clang diagnostic pop } #pragma mark - NSURLSessionDataTaskDelegate - (void)URLSession:(__unused NSURLSession *)session dataTask:(__unused NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { [self.mutableData appendData:data]; } #pragma mark - NSURLSessionDownloadTaskDelegate - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { NSError *fileManagerError = nil; self.downloadFileURL = nil; if (self.downloadTaskDidFinishDownloading) { self.downloadFileURL = self.downloadTaskDidFinishDownloading(session, downloadTask, location); if (self.downloadFileURL) { [[NSFileManager defaultManager] moveItemAtURL:location toURL:self.downloadFileURL error:&fileManagerError]; if (fileManagerError) { [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:fileManagerError.userInfo]; } } } } - (void)URLSession:(__unused NSURLSession *)session downloadTask:(__unused NSURLSessionDownloadTask *)downloadTask didWriteData:(__unused int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { self.progress.totalUnitCount = totalBytesExpectedToWrite; self.progress.completedUnitCount = totalBytesWritten; } - (void)URLSession:(__unused NSURLSession *)session downloadTask:(__unused NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes { self.progress.totalUnitCount = expectedTotalBytes; self.progress.completedUnitCount = fileOffset; } @end #pragma mark - /** * A workaround for issues related to key-value observing the `state` of an `NSURLSessionTask`. * * See: * - https://github.com/AFNetworking/AFNetworking/issues/1477 * - https://github.com/AFNetworking/AFNetworking/issues/2638 * - https://github.com/AFNetworking/AFNetworking/pull/2702 */ static inline void af_swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) { Method originalMethod = class_getInstanceMethod(class, originalSelector); Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); method_exchangeImplementations(originalMethod, swizzledMethod); } static inline BOOL af_addMethod(Class class, SEL selector, Method method) { return class_addMethod(class, selector, method_getImplementation(method), method_getTypeEncoding(method)); } static NSString * const AFNSURLSessionTaskDidResumeNotification = @"com.alamofire.networking.nsurlsessiontask.resume"; static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofire.networking.nsurlsessiontask.suspend"; @interface _AFURLSessionTaskSwizzling : NSObject @end @implementation _AFURLSessionTaskSwizzling + (void)load { /** WARNING: Trouble Ahead https://github.com/AFNetworking/AFNetworking/pull/2702 */ if (NSClassFromString(@"NSURLSessionTask")) { /** iOS 7 and iOS 8 differ in NSURLSessionTask implementation, which makes the next bit of code a bit tricky. Many Unit Tests have been built to validate as much of this behavior has possible. Here is what we know: - NSURLSessionTasks are implemented with class clusters, meaning the class you request from the API isn't actually the type of class you will get back. - Simply referencing `[NSURLSessionTask class]` will not work. You need to ask an `NSURLSession` to actually create an object, and grab the class from there. - On iOS 7, `localDataTask` is a `__NSCFLocalDataTask`, which inherits from `__NSCFLocalSessionTask`, which inherits from `__NSCFURLSessionTask`. - On iOS 8, `localDataTask` is a `__NSCFLocalDataTask`, which inherits from `__NSCFLocalSessionTask`, which inherits from `NSURLSessionTask`. - On iOS 7, `__NSCFLocalSessionTask` and `__NSCFURLSessionTask` are the only two classes that have their own implementations of `resume` and `suspend`, and `__NSCFLocalSessionTask` DOES NOT CALL SUPER. This means both classes need to be swizzled. - On iOS 8, `NSURLSessionTask` is the only class that implements `resume` and `suspend`. This means this is the only class that needs to be swizzled. - Because `NSURLSessionTask` is not involved in the class hierarchy for every version of iOS, its easier to add the swizzled methods to a dummy class and manage them there. Some Assumptions: - No implementations of `resume` or `suspend` call super. If this were to change in a future version of iOS, we'd need to handle it. - No background task classes override `resume` or `suspend` The current solution: 1) Grab an instance of `__NSCFLocalDataTask` by asking an instance of `NSURLSession` for a data task. 2) Grab a pointer to the original implementation of `af_resume` 3) Check to see if the current class has an implementation of resume. If so, continue to step 4. 4) Grab the super class of the current class. 5) Grab a pointer for the current class to the current implementation of `resume`. 6) Grab a pointer for the super class to the current implementation of `resume`. 7) If the current class implementation of `resume` is not equal to the super class implementation of `resume` AND the current implementation of `resume` is not equal to the original implementation of `af_resume`, THEN swizzle the methods 8) Set the current class to the super class, and repeat steps 3-8 */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnonnull" NSURLSessionDataTask *localDataTask = [[NSURLSession sessionWithConfiguration:nil] dataTaskWithURL:nil]; #pragma clang diagnostic pop IMP originalAFResumeIMP = method_getImplementation(class_getInstanceMethod([_AFURLSessionTaskSwizzling class], @selector(af_resume))); Class currentClass = [localDataTask class]; while (class_getInstanceMethod(currentClass, @selector(resume))) { Class superClass = [currentClass superclass]; IMP classResumeIMP = method_getImplementation(class_getInstanceMethod(currentClass, @selector(resume))); IMP superclassResumeIMP = method_getImplementation(class_getInstanceMethod(superClass, @selector(resume))); if (classResumeIMP != superclassResumeIMP && originalAFResumeIMP != classResumeIMP) { [self swizzleResumeAndSuspendMethodForClass:currentClass]; } currentClass = [currentClass superclass]; } [localDataTask cancel]; } } + (void)swizzleResumeAndSuspendMethodForClass:(Class)class { Method afResumeMethod = class_getInstanceMethod(self, @selector(af_resume)); Method afSuspendMethod = class_getInstanceMethod(self, @selector(af_suspend)); af_addMethod(class, @selector(af_resume), afResumeMethod); af_addMethod(class, @selector(af_suspend), afSuspendMethod); af_swizzleSelector(class, @selector(resume), @selector(af_resume)); af_swizzleSelector(class, @selector(suspend), @selector(af_suspend)); } - (NSURLSessionTaskState)state { NSAssert(NO, @"State method should never be called in the actual dummy class"); return NSURLSessionTaskStateCanceling; } - (void)af_resume { NSAssert([self respondsToSelector:@selector(state)], @"Does not respond to state"); NSURLSessionTaskState state = [self state]; [self af_resume]; if (state != NSURLSessionTaskStateRunning) { [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidResumeNotification object:self]; } } - (void)af_suspend { NSAssert([self respondsToSelector:@selector(state)], @"Does not respond to state"); NSURLSessionTaskState state = [self state]; [self af_suspend]; if (state != NSURLSessionTaskStateSuspended) { [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidSuspendNotification object:self]; } } @end #pragma mark - @interface AFURLSessionManager () @property (readwrite, nonatomic, strong) NSURLSessionConfiguration *sessionConfiguration; @property (readwrite, nonatomic, strong) NSOperationQueue *operationQueue; @property (readwrite, nonatomic, strong) NSURLSession *session; @property (readwrite, nonatomic, strong) NSMutableDictionary *mutableTaskDelegatesKeyedByTaskIdentifier; @property (readonly, nonatomic, copy) NSString *taskDescriptionForSessionTasks; @property (readwrite, nonatomic, strong) NSLock *lock; @property (readwrite, nonatomic, copy) AFURLSessionDidBecomeInvalidBlock sessionDidBecomeInvalid; @property (readwrite, nonatomic, copy) AFURLSessionDidReceiveAuthenticationChallengeBlock sessionDidReceiveAuthenticationChallenge; @property (readwrite, nonatomic, copy) AFURLSessionDidFinishEventsForBackgroundURLSessionBlock didFinishEventsForBackgroundURLSession; @property (readwrite, nonatomic, copy) AFURLSessionTaskWillPerformHTTPRedirectionBlock taskWillPerformHTTPRedirection; @property (readwrite, nonatomic, copy) AFURLSessionTaskDidReceiveAuthenticationChallengeBlock taskDidReceiveAuthenticationChallenge; @property (readwrite, nonatomic, copy) AFURLSessionTaskNeedNewBodyStreamBlock taskNeedNewBodyStream; @property (readwrite, nonatomic, copy) AFURLSessionTaskDidSendBodyDataBlock taskDidSendBodyData; @property (readwrite, nonatomic, copy) AFURLSessionTaskDidCompleteBlock taskDidComplete; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveResponseBlock dataTaskDidReceiveResponse; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidBecomeDownloadTaskBlock dataTaskDidBecomeDownloadTask; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveDataBlock dataTaskDidReceiveData; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskWillCacheResponseBlock dataTaskWillCacheResponse; @property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading; @property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidWriteDataBlock downloadTaskDidWriteData; @property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidResumeBlock downloadTaskDidResume; @end @implementation AFURLSessionManager - (instancetype)init { return [self initWithSessionConfiguration:nil]; } - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration { self = [super init]; if (!self) { return nil; } if (!configuration) { configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; } self.sessionConfiguration = configuration; self.operationQueue = [[NSOperationQueue alloc] init]; self.operationQueue.maxConcurrentOperationCount = 1; self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue]; self.responseSerializer = [AFJSONResponseSerializer serializer]; self.securityPolicy = [AFSecurityPolicy defaultPolicy]; self.reachabilityManager = [AFNetworkReachabilityManager sharedManager]; self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init]; self.lock = [[NSLock alloc] init]; self.lock.name = AFURLSessionManagerLockName; [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { for (NSURLSessionDataTask *task in dataTasks) { [self addDelegateForDataTask:task completionHandler:nil]; } for (NSURLSessionUploadTask *uploadTask in uploadTasks) { [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil]; } for (NSURLSessionDownloadTask *downloadTask in downloadTasks) { [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil]; } }]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidResume:) name:AFNSURLSessionTaskDidResumeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidSuspend:) name:AFNSURLSessionTaskDidSuspendNotification object:nil]; return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - - (NSString *)taskDescriptionForSessionTasks { return [NSString stringWithFormat:@"%p", self]; } - (void)taskDidResume:(NSNotification *)notification { NSURLSessionTask *task = notification.object; if ([task respondsToSelector:@selector(taskDescription)]) { if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) { dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidResumeNotification object:task]; }); } } } - (void)taskDidSuspend:(NSNotification *)notification { NSURLSessionTask *task = notification.object; if ([task respondsToSelector:@selector(taskDescription)]) { if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) { dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidSuspendNotification object:task]; }); } } } #pragma mark - - (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task { NSParameterAssert(task); AFURLSessionManagerTaskDelegate *delegate = nil; [self.lock lock]; delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)]; [self.lock unlock]; return delegate; } - (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate forTask:(NSURLSessionTask *)task { NSParameterAssert(task); NSParameterAssert(delegate); [self.lock lock]; self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate; [self.lock unlock]; } - (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; delegate.manager = self; delegate.completionHandler = completionHandler; dataTask.taskDescription = self.taskDescriptionForSessionTasks; [self setDelegate:delegate forTask:dataTask]; } - (void)addDelegateForUploadTask:(NSURLSessionUploadTask *)uploadTask progress:(NSProgress * __autoreleasing *)progress completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; delegate.manager = self; delegate.completionHandler = completionHandler; int64_t totalUnitCount = uploadTask.countOfBytesExpectedToSend; if(totalUnitCount == NSURLSessionTransferSizeUnknown) { NSString *contentLength = [uploadTask.originalRequest valueForHTTPHeaderField:@"Content-Length"]; if(contentLength) { totalUnitCount = (int64_t)[contentLength longLongValue]; } } if (delegate.progress) { delegate.progress.totalUnitCount = totalUnitCount; } else { delegate.progress = [NSProgress progressWithTotalUnitCount:totalUnitCount]; } delegate.progress.pausingHandler = ^{ [uploadTask suspend]; }; delegate.progress.cancellationHandler = ^{ [uploadTask cancel]; }; if (progress) { *progress = delegate.progress; } uploadTask.taskDescription = self.taskDescriptionForSessionTasks; [self setDelegate:delegate forTask:uploadTask]; } - (void)addDelegateForDownloadTask:(NSURLSessionDownloadTask *)downloadTask progress:(NSProgress * __autoreleasing *)progress destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler { AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; delegate.manager = self; delegate.completionHandler = completionHandler; if (destination) { delegate.downloadTaskDidFinishDownloading = ^NSURL * (NSURLSession * __unused session, NSURLSessionDownloadTask *task, NSURL *location) { return destination(location, task.response); }; } if (progress) { *progress = delegate.progress; } downloadTask.taskDescription = self.taskDescriptionForSessionTasks; [self setDelegate:delegate forTask:downloadTask]; } - (void)removeDelegateForTask:(NSURLSessionTask *)task { NSParameterAssert(task); [self.lock lock]; [self.mutableTaskDelegatesKeyedByTaskIdentifier removeObjectForKey:@(task.taskIdentifier)]; [self.lock unlock]; } - (void)removeAllDelegates { [self.lock lock]; [self.mutableTaskDelegatesKeyedByTaskIdentifier removeAllObjects]; [self.lock unlock]; } #pragma mark - - (NSArray *)tasksForKeyPath:(NSString *)keyPath { __block NSArray *tasks = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { if ([keyPath isEqualToString:NSStringFromSelector(@selector(dataTasks))]) { tasks = dataTasks; } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(uploadTasks))]) { tasks = uploadTasks; } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(downloadTasks))]) { tasks = downloadTasks; } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(tasks))]) { tasks = [@[dataTasks, uploadTasks, downloadTasks] valueForKeyPath:@"@unionOfArrays.self"]; } dispatch_semaphore_signal(semaphore); }]; dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); return tasks; } - (NSArray *)tasks { return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; } - (NSArray *)dataTasks { return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; } - (NSArray *)uploadTasks { return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; } - (NSArray *)downloadTasks { return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; } #pragma mark - - (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks { dispatch_async(dispatch_get_main_queue(), ^{ if (cancelPendingTasks) { [self.session invalidateAndCancel]; } else { [self.session finishTasksAndInvalidate]; } }); } #pragma mark - - (void)setResponseSerializer:(id )responseSerializer { NSParameterAssert(responseSerializer); _responseSerializer = responseSerializer; } #pragma mark - - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { __block NSURLSessionDataTask *dataTask = nil; dispatch_sync(url_session_manager_creation_queue(), ^{ dataTask = [self.session dataTaskWithRequest:request]; }); [self addDelegateForDataTask:dataTask completionHandler:completionHandler]; return dataTask; } #pragma mark - - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL progress:(NSProgress * __autoreleasing *)progress completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { __block NSURLSessionUploadTask *uploadTask = nil; dispatch_sync(url_session_manager_creation_queue(), ^{ uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL]; }); if (!uploadTask && self.attemptsToRecreateUploadTasksForBackgroundSessions && self.session.configuration.identifier) { for (NSUInteger attempts = 0; !uploadTask && attempts < AFMaximumNumberOfAttemptsToRecreateBackgroundSessionUploadTask; attempts++) { uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL]; } } [self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler]; return uploadTask; } - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData progress:(NSProgress * __autoreleasing *)progress completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { __block NSURLSessionUploadTask *uploadTask = nil; dispatch_sync(url_session_manager_creation_queue(), ^{ uploadTask = [self.session uploadTaskWithRequest:request fromData:bodyData]; }); [self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler]; return uploadTask; } - (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request progress:(NSProgress * __autoreleasing *)progress completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { __block NSURLSessionUploadTask *uploadTask = nil; dispatch_sync(url_session_manager_creation_queue(), ^{ uploadTask = [self.session uploadTaskWithStreamedRequest:request]; }); [self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler]; return uploadTask; } #pragma mark - - (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request progress:(NSProgress * __autoreleasing *)progress destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler { __block NSURLSessionDownloadTask *downloadTask = nil; dispatch_sync(url_session_manager_creation_queue(), ^{ downloadTask = [self.session downloadTaskWithRequest:request]; }); [self addDelegateForDownloadTask:downloadTask progress:progress destination:destination completionHandler:completionHandler]; return downloadTask; } - (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData progress:(NSProgress * __autoreleasing *)progress destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler { __block NSURLSessionDownloadTask *downloadTask = nil; dispatch_sync(url_session_manager_creation_queue(), ^{ downloadTask = [self.session downloadTaskWithResumeData:resumeData]; }); [self addDelegateForDownloadTask:downloadTask progress:progress destination:destination completionHandler:completionHandler]; return downloadTask; } #pragma mark - - (NSProgress *)uploadProgressForTask:(NSURLSessionUploadTask *)uploadTask { return [[self delegateForTask:uploadTask] progress]; } - (NSProgress *)downloadProgressForTask:(NSURLSessionDownloadTask *)downloadTask { return [[self delegateForTask:downloadTask] progress]; } #pragma mark - - (void)setSessionDidBecomeInvalidBlock:(void (^)(NSURLSession *session, NSError *error))block { self.sessionDidBecomeInvalid = block; } - (void)setSessionDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block { self.sessionDidReceiveAuthenticationChallenge = block; } - (void)setDidFinishEventsForBackgroundURLSessionBlock:(void (^)(NSURLSession *session))block { self.didFinishEventsForBackgroundURLSession = block; } #pragma mark - - (void)setTaskNeedNewBodyStreamBlock:(NSInputStream * (^)(NSURLSession *session, NSURLSessionTask *task))block { self.taskNeedNewBodyStream = block; } - (void)setTaskWillPerformHTTPRedirectionBlock:(NSURLRequest * (^)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request))block { self.taskWillPerformHTTPRedirection = block; } - (void)setTaskDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block { self.taskDidReceiveAuthenticationChallenge = block; } - (void)setTaskDidSendBodyDataBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend))block { self.taskDidSendBodyData = block; } - (void)setTaskDidCompleteBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, NSError *error))block { self.taskDidComplete = block; } #pragma mark - - (void)setDataTaskDidReceiveResponseBlock:(NSURLSessionResponseDisposition (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response))block { self.dataTaskDidReceiveResponse = block; } - (void)setDataTaskDidBecomeDownloadTaskBlock:(void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask))block { self.dataTaskDidBecomeDownloadTask = block; } - (void)setDataTaskDidReceiveDataBlock:(void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data))block { self.dataTaskDidReceiveData = block; } - (void)setDataTaskWillCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block { self.dataTaskWillCacheResponse = block; } #pragma mark - - (void)setDownloadTaskDidFinishDownloadingBlock:(NSURL * (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block { self.downloadTaskDidFinishDownloading = block; } - (void)setDownloadTaskDidWriteDataBlock:(void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite))block { self.downloadTaskDidWriteData = block; } - (void)setDownloadTaskDidResumeBlock:(void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes))block { self.downloadTaskDidResume = block; } #pragma mark - NSObject - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, self.session, self.operationQueue]; } - (BOOL)respondsToSelector:(SEL)selector { if (selector == @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:)) { return self.taskWillPerformHTTPRedirection != nil; } else if (selector == @selector(URLSession:dataTask:didReceiveResponse:completionHandler:)) { return self.dataTaskDidReceiveResponse != nil; } else if (selector == @selector(URLSession:dataTask:willCacheResponse:completionHandler:)) { return self.dataTaskWillCacheResponse != nil; } else if (selector == @selector(URLSessionDidFinishEventsForBackgroundURLSession:)) { return self.didFinishEventsForBackgroundURLSession != nil; } return [[self class] instancesRespondToSelector:selector]; } #pragma mark - NSURLSessionDelegate - (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error { if (self.sessionDidBecomeInvalid) { self.sessionDidBecomeInvalid(session, error); } [self removeAllDelegates]; [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDidInvalidateNotification object:session]; } - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; __block NSURLCredential *credential = nil; if (self.sessionDidReceiveAuthenticationChallenge) { disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential); } else { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; if (credential) { disposition = NSURLSessionAuthChallengeUseCredential; } else { disposition = NSURLSessionAuthChallengePerformDefaultHandling; } } else { disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; } } else { disposition = NSURLSessionAuthChallengePerformDefaultHandling; } } if (completionHandler) { completionHandler(disposition, credential); } } #pragma mark - NSURLSessionTaskDelegate - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler { NSURLRequest *redirectRequest = request; if (self.taskWillPerformHTTPRedirection) { redirectRequest = self.taskWillPerformHTTPRedirection(session, task, response, request); } if (completionHandler) { completionHandler(redirectRequest); } } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; __block NSURLCredential *credential = nil; if (self.taskDidReceiveAuthenticationChallenge) { disposition = self.taskDidReceiveAuthenticationChallenge(session, task, challenge, &credential); } else { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { disposition = NSURLSessionAuthChallengeUseCredential; credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; } else { disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; } } else { disposition = NSURLSessionAuthChallengePerformDefaultHandling; } } if (completionHandler) { completionHandler(disposition, credential); } } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:(void (^)(NSInputStream *bodyStream))completionHandler { NSInputStream *inputStream = nil; if (self.taskNeedNewBodyStream) { inputStream = self.taskNeedNewBodyStream(session, task); } else if (task.originalRequest.HTTPBodyStream && [task.originalRequest.HTTPBodyStream conformsToProtocol:@protocol(NSCopying)]) { inputStream = [task.originalRequest.HTTPBodyStream copy]; } if (completionHandler) { completionHandler(inputStream); } } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { int64_t totalUnitCount = totalBytesExpectedToSend; if(totalUnitCount == NSURLSessionTransferSizeUnknown) { NSString *contentLength = [task.originalRequest valueForHTTPHeaderField:@"Content-Length"]; if(contentLength) { totalUnitCount = (int64_t) [contentLength longLongValue]; } } AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task]; [delegate URLSession:session task:task didSendBodyData:bytesSent totalBytesSent:totalBytesSent totalBytesExpectedToSend:totalUnitCount]; if (self.taskDidSendBodyData) { self.taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalUnitCount); } } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task]; // delegate may be nil when completing a task in the background if (delegate) { [delegate URLSession:session task:task didCompleteWithError:error]; [self removeDelegateForTask:task]; } if (self.taskDidComplete) { self.taskDidComplete(session, task, error); } } #pragma mark - NSURLSessionDataDelegate - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow; if (self.dataTaskDidReceiveResponse) { disposition = self.dataTaskDidReceiveResponse(session, dataTask, response); } if (completionHandler) { completionHandler(disposition); } } - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask]; if (delegate) { [self removeDelegateForTask:dataTask]; [self setDelegate:delegate forTask:downloadTask]; } if (self.dataTaskDidBecomeDownloadTask) { self.dataTaskDidBecomeDownloadTask(session, dataTask, downloadTask); } } - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask]; [delegate URLSession:session dataTask:dataTask didReceiveData:data]; if (self.dataTaskDidReceiveData) { self.dataTaskDidReceiveData(session, dataTask, data); } } - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler { NSCachedURLResponse *cachedResponse = proposedResponse; if (self.dataTaskWillCacheResponse) { cachedResponse = self.dataTaskWillCacheResponse(session, dataTask, proposedResponse); } if (completionHandler) { completionHandler(cachedResponse); } } - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session { if (self.didFinishEventsForBackgroundURLSession) { dispatch_async(dispatch_get_main_queue(), ^{ self.didFinishEventsForBackgroundURLSession(session); }); } } #pragma mark - NSURLSessionDownloadDelegate - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask]; if (self.downloadTaskDidFinishDownloading) { NSURL *fileURL = self.downloadTaskDidFinishDownloading(session, downloadTask, location); if (fileURL) { delegate.downloadFileURL = fileURL; NSError *error = nil; [[NSFileManager defaultManager] moveItemAtURL:location toURL:fileURL error:&error]; if (error) { [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:error.userInfo]; } return; } } if (delegate) { [delegate URLSession:session downloadTask:downloadTask didFinishDownloadingToURL:location]; } } - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask]; [delegate URLSession:session downloadTask:downloadTask didWriteData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite]; if (self.downloadTaskDidWriteData) { self.downloadTaskDidWriteData(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); } } - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask]; [delegate URLSession:session downloadTask:downloadTask didResumeAtOffset:fileOffset expectedTotalBytes:expectedTotalBytes]; if (self.downloadTaskDidResume) { self.downloadTaskDidResume(session, downloadTask, fileOffset, expectedTotalBytes); } } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"]; self = [self initWithSessionConfiguration:configuration]; if (!self) { return nil; } return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:self.session.configuration forKey:@"sessionConfiguration"]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { return [[[self class] allocWithZone:zone] initWithSessionConfiguration:self.session.configuration]; } @end #endif ================================================ FILE: shakefun/shakefun/AppDelegate.h ================================================ // // AppDelegate.h // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #import #import @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; - (void)saveContext; - (NSURL *)applicationDocumentsDirectory; @end ================================================ FILE: shakefun/shakefun/AppDelegate.m ================================================ // // AppDelegate.m // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #import "AppDelegate.h" #import "ViewController.h" #import "CoreData+MagicalRecord.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [MagicalRecord setupAutoMigratingCoreDataStack]; ViewController *rootview = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"ViewController"]; UINavigationController *naviController = [[UINavigationController alloc] initWithRootViewController:rootview]; self.window.rootViewController = naviController; [self.window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. // Saves changes in the application's managed object context before the application terminates. [self saveContext]; } #pragma mark - Core Data stack @synthesize managedObjectContext = _managedObjectContext; @synthesize managedObjectModel = _managedObjectModel; @synthesize persistentStoreCoordinator = _persistentStoreCoordinator; - (NSURL *)applicationDocumentsDirectory { // The directory the application uses to store the Core Data store file. This code uses a directory named "zm.shakefun" in the application's documents directory. return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; } - (NSManagedObjectModel *)managedObjectModel { // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model. if (_managedObjectModel != nil) { return _managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"shakefun" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } // Create the coordinator and store _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"shakefun.sqlite"]; NSError *error = nil; NSString *failureReason = @"There was an error creating or loading the application's saved data."; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { // Report any error we got. NSMutableDictionary *dict = [NSMutableDictionary dictionary]; dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data"; dict[NSLocalizedFailureReasonErrorKey] = failureReason; dict[NSUnderlyingErrorKey] = error; error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict]; // Replace this with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return _persistentStoreCoordinator; } - (NSManagedObjectContext *)managedObjectContext { // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) if (_managedObjectContext != nil) { return _managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (!coordinator) { return nil; } _managedObjectContext = [[NSManagedObjectContext alloc] init]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; return _managedObjectContext; } #pragma mark - Core Data Saving support - (void)saveContext { NSManagedObjectContext *managedObjectContext = self.managedObjectContext; if (managedObjectContext != nil) { NSError *error = nil; if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { // Replace this implementation with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } } @end ================================================ FILE: shakefun/shakefun/Base.lproj/LaunchScreen.xib ================================================ ================================================ FILE: shakefun/shakefun/Base.lproj/Main.storyboard ================================================ Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. ================================================ FILE: shakefun/shakefun/CollectViewController.h ================================================ // // CollectViewController.h // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #ifndef shakefun_CollectViewController_h #define shakefun_CollectViewController_h #import @interface CollectViewController : UIViewController { } - (IBAction)buttonStartCollectToggle:(id)sender; @property (weak, nonatomic) IBOutlet UITextView *textViewLogInfo; @property (weak, nonatomic) IBOutlet UITextField *textfieldPageNum; @end #endif ================================================ FILE: shakefun/shakefun/CollectViewController.m ================================================ // // CollectViewController.m // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #import #import "CollectViewController.h" #import "URLEntity.h" #import "ViewController.h" #import "AFNetworking.h" @implementation CollectViewController { } -(void)viewDidLoad { [super viewDidLoad]; [self.navigationController setNavigationBarHidden:NO animated:YES]; self.textViewLogInfo.text = @""; } - (IBAction)buttonStartCollectToggle:(id)sender { //http://www.hao123.com/gaoxiao?pn=2 [self.view endEditing:YES]; if (self.textfieldPageNum.text.length <= 0) { return; } NSInteger page = [self.textfieldPageNum.text integerValue]; NSString *pageurl = [NSString stringWithFormat:@"http://www.hao123.com/gaoxiao?pn=%ld", (long)page]; AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"]; //发送请求 [manager POST:pageurl parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { NSString *result = [[NSString alloc]initWithData:operation.responseData encoding:NSUTF8StringEncoding]; NSArray *urls = [result componentsSeparatedFromString:@" CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier zm.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS NSAppTransportSecurity NSAllowsArbitraryLoads NSMainNibFile LaunchScreen UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/MagicalImportFunctions.h ================================================ // // MagicalImportFunctions.h // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import NSDate * adjustDateForDST(NSDate *date); NSDate * dateFromString(NSString *value, NSString *format); NSNumber * numberFromString(NSString *value); NSString * attributeNameFromString(NSString *value); NSString * primaryKeyNameFromString(NSString *value); #if TARGET_OS_IPHONE #import UIColor * UIColorFromString(NSString *serializedColor); #else #import NSColor * NSColorFromString(NSString *serializedColor); #endif extern id (*colorFromString)(NSString *); ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/MagicalImportFunctions.m ================================================ // // MagicalImportFunctions.m // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalImportFunctions.h" #pragma mark - Data import helper functions NSString * attributeNameFromString(NSString *value) { NSString *firstCharacter = [[value substringToIndex:1] capitalizedString]; return [firstCharacter stringByAppendingString:[value substringFromIndex:1]]; } NSString * primaryKeyNameFromString(NSString *value) { NSString *firstCharacter = [[value substringToIndex:1] lowercaseString]; return [firstCharacter stringByAppendingFormat:@"%@ID", [value substringFromIndex:1]]; } NSDate * adjustDateForDST(NSDate *date) { NSTimeInterval dstOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffsetForDate:date]; NSDate *actualDate = [date dateByAddingTimeInterval:dstOffset]; return actualDate; } NSDate * dateFromString(NSString *value, NSString *format) { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setTimeZone:[NSTimeZone localTimeZone]]; [formatter setLocale:[NSLocale currentLocale]]; [formatter setDateFormat:format]; NSDate *parsedDate = [formatter dateFromString:value]; return parsedDate; } NSNumber * numberFromString(NSString *value) { return [NSNumber numberWithDouble:[value doubleValue]]; } NSInteger* newColorComponentsFromString(NSString *serializedColor); NSInteger* newColorComponentsFromString(NSString *serializedColor) { NSScanner *colorScanner = [NSScanner scannerWithString:serializedColor]; NSString *colorType; [colorScanner scanUpToString:@"(" intoString:&colorType]; NSInteger *componentValues = malloc(4 * sizeof(NSInteger)); if ([colorType hasPrefix:@"rgba"]) { NSCharacterSet *rgbaCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"(,)"]; NSInteger *componentValue = componentValues; while (![colorScanner isAtEnd]) { [colorScanner scanCharactersFromSet:rgbaCharacterSet intoString:nil]; [colorScanner scanInteger:componentValue]; componentValue++; } } //else if ([colorType hasPrefix:@"hsba"]) //else if ([colorType hasPrefix:@""]) return componentValues; } #if TARGET_OS_IPHONE UIColor * UIColorFromString(NSString *serializedColor) { NSInteger *componentValues = newColorComponentsFromString(serializedColor); UIColor *color = [UIColor colorWithRed:(componentValues[0] / 255.0f) green:(componentValues[1] / 255.0f) blue:(componentValues[2] / 255.0f) alpha:componentValues[3]]; free(componentValues); return color; } id (*colorFromString)(NSString *) = UIColorFromString; #else NSColor * NSColorFromString(NSString *serializedColor) { NSInteger *componentValues = newColorComponentsFromString(serializedColor); NSColor *color = [NSColor colorWithDeviceRed:(componentValues[0] / 255.0f) green:(componentValues[1] / 255.0f) blue:(componentValues[2] / 255.0f) alpha:componentValues[3]]; free(componentValues); return color; } id (*colorFromString)(NSString *) = NSColorFromString; #endif ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.h ================================================ // // NSAttributeDescription+MagicalDataImport.h // Magical Record // // Created by Saul Mora on 9/4/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import @interface NSAttributeDescription (MagicalRecord_DataImport) - (NSString *) MR_primaryKey; - (id) MR_valueForKeyPath:(NSString *)keyPath fromObjectData:(id)objectData; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSAttributeDescription+MagicalDataImport.m ================================================ // // NSAttributeDescription+MagicalDataImport.m // Magical Record // // Created by Saul Mora on 9/4/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import "NSAttributeDescription+MagicalDataImport.h" #import "NSManagedObject+MagicalDataImport.h" #import "MagicalImportFunctions.h" @implementation NSAttributeDescription (MagicalRecord_DataImport) - (NSString *) MR_primaryKey; { return nil; } - (id) MR_valueForKeyPath:(NSString *)keyPath fromObjectData:(id)objectData; { id value = [objectData valueForKeyPath:keyPath]; NSAttributeType attributeType = [self attributeType]; NSString *desiredAttributeType = [[self userInfo] valueForKey:kMagicalRecordImportAttributeValueClassNameKey]; if (desiredAttributeType) { if ([desiredAttributeType hasSuffix:@"Color"]) { value = colorFromString(value); } } else { if (attributeType == NSDateAttributeType) { if (![value isKindOfClass:[NSDate class]]) { NSString *dateFormat = [[self userInfo] valueForKey:kMagicalRecordImportCustomDateFormatKey]; value = dateFromString([value description], dateFormat ?: kMagicalRecordImportDefaultDateFormatString); } // value = adjustDateForDST(value); } else if (attributeType == NSInteger16AttributeType || attributeType == NSInteger32AttributeType || attributeType == NSInteger64AttributeType || attributeType == NSDecimalAttributeType || attributeType == NSDoubleAttributeType || attributeType == NSFloatAttributeType) { if (![value isKindOfClass:[NSNumber class]] && value != [NSNull null]) { value = numberFromString([value description]); } } } return value == [NSNull null] ? nil : value; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.h ================================================ // // NSEntityDescription+MagicalDataImport.h // Magical Record // // Created by Saul Mora on 9/5/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // @interface NSEntityDescription (MagicalRecord_DataImport) - (NSAttributeDescription *) MR_primaryAttributeToRelateBy; - (NSManagedObject *) MR_createInstanceInContext:(NSManagedObjectContext *)context; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSEntityDescription+MagicalDataImport.m ================================================ // // NSEntityDescription+MagicalDataImport.m // Magical Record // // Created by Saul Mora on 9/5/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import "CoreData+MagicalRecord.h" @implementation NSEntityDescription (MagicalRecord_DataImport) - (NSAttributeDescription *) MR_primaryAttributeToRelateBy; { NSString *lookupKey = [[self userInfo] valueForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: primaryKeyNameFromString([self name]); NSDictionary *attributesByName = [self attributesByName]; if ([attributesByName count] == 0) return nil; NSAttributeDescription *primaryAttribute = [attributesByName objectForKey:lookupKey]; return primaryAttribute; } - (NSManagedObject *) MR_createInstanceInContext:(NSManagedObjectContext *)context; { Class relatedClass = NSClassFromString([self managedObjectClassName]); NSManagedObject *newInstance = [relatedClass MR_createInContext:context]; return newInstance; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.h ================================================ // // NSNumber+MagicalDataImport.h // Magical Record // // Created by Saul Mora on 9/4/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import @interface NSNumber (MagicalRecord_DataImport) - (NSString *) MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo; - (id) MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSNumber+MagicalDataImport.m ================================================ // // NSNumber+MagicalDataImport.m // Magical Record // // Created by Saul Mora on 9/4/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import "NSNumber+MagicalDataImport.h" @implementation NSNumber (MagicalRecord_DataImport) - (id) MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo { return self; } - (NSString *) MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo { return nil; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.h ================================================ // // NSDictionary+MagicalDataImport.h // Magical Record // // Created by Saul Mora on 9/4/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import @interface NSObject (MagicalRecord_DataImport) - (NSString *) MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo; - (id) MR_valueForAttribute:(NSAttributeDescription *)attributeInfo; - (NSString *) MR_lookupKeyForRelationship:(NSRelationshipDescription *)relationshipInfo; - (id) MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSObject+MagicalDataImport.m ================================================ // // NSDictionary+MagicalDataImport.m // Magical Record // // Created by Saul Mora on 9/4/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import "NSObject+MagicalDataImport.h" #import "NSManagedObject+MagicalDataImport.h" #import "MagicalRecord.h" #import "CoreData+MagicalRecord.h" NSUInteger const kMagicalRecordImportMaximumAttributeFailoverDepth = 10; @implementation NSObject (MagicalRecord_DataImport) //#warning If you implement valueForUndefinedKey: in any NSObject in your code, this may be the problem if something broke - (id) MR_valueForUndefinedKey:(NSString *)key { return nil; } - (NSString *) MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo; { NSString *attributeName = [attributeInfo name]; NSString *lookupKey = [[attributeInfo userInfo] valueForKey:kMagicalRecordImportAttributeKeyMapKey] ?: attributeName; id value = [self valueForKeyPath:lookupKey]; for (NSUInteger i = 1; i < kMagicalRecordImportMaximumAttributeFailoverDepth && value == nil; i++) { attributeName = [NSString stringWithFormat:@"%@.%lu", kMagicalRecordImportAttributeKeyMapKey, (unsigned long)i]; lookupKey = [[attributeInfo userInfo] valueForKey:attributeName]; if (lookupKey == nil) { return nil; } value = [self valueForKeyPath:lookupKey]; } return value != nil ? lookupKey : nil; } - (id) MR_valueForAttribute:(NSAttributeDescription *)attributeInfo { NSString *lookupKey = [self MR_lookupKeyForAttribute:attributeInfo]; return lookupKey ? [self valueForKeyPath:lookupKey] : nil; } - (NSString *) MR_lookupKeyForRelationship:(NSRelationshipDescription *)relationshipInfo { NSEntityDescription *destinationEntity = [relationshipInfo destinationEntity]; if (destinationEntity == nil) { MRLog(@"Unable to find entity for type '%@'", [self valueForKey:kMagicalRecordImportRelationshipTypeKey]); return nil; } NSString *primaryKeyName = [relationshipInfo MR_primaryKey]; NSAttributeDescription *primaryKeyAttribute = [[destinationEntity attributesByName] valueForKey:primaryKeyName]; NSString *lookupKey = [[primaryKeyAttribute userInfo] valueForKey:kMagicalRecordImportAttributeKeyMapKey] ?: [primaryKeyAttribute name]; return lookupKey; } - (id) MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo { NSString *lookupKey = [self MR_lookupKeyForRelationship:relationshipInfo]; return lookupKey ? [self valueForKeyPath:lookupKey] : nil; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.h ================================================ // // NSRelationshipDescription+MagicalDataImport.h // Magical Record // // Created by Saul Mora on 9/4/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import @interface NSRelationshipDescription (MagicalRecord_DataImport) - (NSString *) MR_primaryKey; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSRelationshipDescription+MagicalDataImport.m ================================================ // // NSRelationshipDescription+MagicalDataImport.m // Magical Record // // Created by Saul Mora on 9/4/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import "NSRelationshipDescription+MagicalDataImport.h" #import "NSManagedObject+MagicalDataImport.h" #import "MagicalImportFunctions.h" #import "MagicalRecord.h" @implementation NSRelationshipDescription (MagicalRecord_DataImport) - (NSString *) MR_primaryKey; { NSString *primaryKeyName = [[self userInfo] valueForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: primaryKeyNameFromString([[self destinationEntity] name]); return primaryKeyName; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.h ================================================ // // NSString+MagicalRecord_MagicalDataImport.h // Magical Record // // Created by Saul Mora on 12/10/11. // Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. // #import @interface NSString (MagicalRecord_DataImport) - (NSString *) MR_capitalizedFirstCharacterString; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/DataImport/NSString+MagicalDataImport.m ================================================ // // NSString+MagicalRecord_MagicalDataImport.m // Magical Record // // Created by Saul Mora on 12/10/11. // Copyright (c) 2011 Magical Panda Software LLC. All rights reserved. // #import "NSString+MagicalDataImport.h" @implementation NSString (MagicalRecord_DataImport) - (NSString *) MR_capitalizedFirstCharacterString; { if ([self length] > 0) { NSString *firstChar = [[self substringToIndex:1] capitalizedString]; return [firstChar stringByAppendingString:[self substringFromIndex:1]]; } return self; } - (id) MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo { return self; } - (NSString *) MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo { return nil; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.h ================================================ // // NSManagedObject+MagicalAggregation.h // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import @interface NSManagedObject (MagicalAggregation) + (NSNumber *) MR_numberOfEntities; + (NSNumber *) MR_numberOfEntitiesWithContext:(NSManagedObjectContext *)context; + (NSNumber *) MR_numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm; + (NSNumber *) MR_numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (NSUInteger) MR_countOfEntities; + (NSUInteger) MR_countOfEntitiesWithContext:(NSManagedObjectContext *)context; + (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter; + (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter inContext:(NSManagedObjectContext *)context; + (BOOL) MR_hasAtLeastOneEntity; + (BOOL) MR_hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context; + (NSNumber *)MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; + (NSNumber *)MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate; - (id) MR_objectWithMinValueFor:(NSString *)property; - (id) MR_objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalAggregation.m ================================================ // // NSManagedObject+MagicalAggregation.m // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "NSManagedObject+MagicalAggregation.h" #import "NSManagedObjectContext+MagicalRecord.h" #import "NSManagedObjectContext+MagicalThreading.h" #import "NSManagedObject+MagicalRequests.h" #import "NSManagedObject+MagicalRecord.h" #import "NSManagedObject+MagicalFinders.h" #import "MagicalRecord+ErrorHandling.h" @implementation NSManagedObject (MagicalAggregation) #pragma mark - #pragma mark Number of Entities + (NSNumber *) MR_numberOfEntitiesWithContext:(NSManagedObjectContext *)context { return [NSNumber numberWithUnsignedInteger:[self MR_countOfEntitiesWithContext:context]]; } + (NSNumber *) MR_numberOfEntities { return [self MR_numberOfEntitiesWithContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSNumber *) MR_numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context { return [NSNumber numberWithUnsignedInteger:[self MR_countOfEntitiesWithPredicate:searchTerm inContext:context]]; } + (NSNumber *) MR_numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm; { return [self MR_numberOfEntitiesWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSUInteger) MR_countOfEntities; { return [self MR_countOfEntitiesWithContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSUInteger) MR_countOfEntitiesWithContext:(NSManagedObjectContext *)context; { NSError *error = nil; NSUInteger count = [context countForFetchRequest:[self MR_createFetchRequestInContext:context] error:&error]; [MagicalRecord handleErrors:error]; return count; } + (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter; { return [self MR_countOfEntitiesWithPredicate:searchFilter inContext:[NSManagedObjectContext MR_defaultContext]]; } + (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter inContext:(NSManagedObjectContext *)context; { NSError *error = nil; NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; [request setPredicate:searchFilter]; NSUInteger count = [context countForFetchRequest:request error:&error]; [MagicalRecord handleErrors:error]; return count; } + (BOOL) MR_hasAtLeastOneEntity { return [self MR_hasAtLeastOneEntityInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (BOOL) MR_hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context { return [[self MR_numberOfEntitiesWithContext:context] intValue] > 0; } - (NSNumber *) MR_maxValueFor:(NSString *)property { NSManagedObject *obj = [[self class] MR_findFirstByAttribute:property withValue:[NSString stringWithFormat:@"max(%@)", property]]; return [obj valueForKey:property]; } - (id) MR_objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [[self class] MR_createFetchRequestInContext:context]; NSPredicate *searchFor = [NSPredicate predicateWithFormat:@"SELF = %@ AND %K = min(%@)", self, property, property]; [request setPredicate:searchFor]; return [[self class] MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } - (id) MR_objectWithMinValueFor:(NSString *)property { return [self MR_objectWithMinValueFor:property inContext:[self managedObjectContext]]; } + (NSNumber *) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context { NSExpression *ex = [NSExpression expressionForFunction:function arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:attributeName]]]; NSExpressionDescription *ed = [[NSExpressionDescription alloc] init]; [ed setName:@"result"]; [ed setExpression:ex]; // determine the type of attribute, required to set the expression return type NSAttributeDescription *attributeDescription = [[[self MR_entityDescription] attributesByName] objectForKey:attributeName]; [ed setExpressionResultType:[attributeDescription attributeType]]; NSArray *properties = [NSArray arrayWithObject:ed]; NSFetchRequest *request = [self MR_requestAllWithPredicate:predicate inContext:context]; [request setPropertiesToFetch:properties]; [request setResultType:NSDictionaryResultType]; NSDictionary *resultsDictionary = [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; NSNumber *resultValue = [resultsDictionary objectForKey:@"result"]; return resultValue; } + (NSNumber *) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate { return [self MR_aggregateOperation:function onAttribute:attributeName withPredicate:predicate inContext:[NSManagedObjectContext MR_defaultContext]]; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.h ================================================ // // NSManagedObject+JSONHelpers.h // // Created by Saul Mora on 6/28/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import extern NSString * const kMagicalRecordImportCustomDateFormatKey; extern NSString * const kMagicalRecordImportDefaultDateFormatString; extern NSString * const kMagicalRecordImportAttributeKeyMapKey; extern NSString * const kMagicalRecordImportAttributeValueClassNameKey; extern NSString * const kMagicalRecordImportRelationshipMapKey; extern NSString * const kMagicalRecordImportRelationshipLinkedByKey; extern NSString * const kMagicalRecordImportRelationshipTypeKey; @interface NSManagedObject (MagicalRecord_DataImport) - (BOOL) MR_importValuesForKeysWithObject:(id)objectData; + (id) MR_importFromObject:(id)data; + (id) MR_importFromObject:(id)data inContext:(NSManagedObjectContext *)context; + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData; + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData inContext:(NSManagedObjectContext *)context; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalDataImport.m ================================================ // // NSManagedObject+JSONHelpers.m // // Created by Saul Mora on 6/28/11. // Copyright 2011 Magical Panda Software LLC. All rights reserved. // #import "CoreData+MagicalRecord.h" #import void MR_swapMethodsFromClass(Class c, SEL orig, SEL new); NSString * const kMagicalRecordImportCustomDateFormatKey = @"dateFormat"; NSString * const kMagicalRecordImportDefaultDateFormatString = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; NSString * const kMagicalRecordImportAttributeKeyMapKey = @"mappedKeyName"; NSString * const kMagicalRecordImportAttributeValueClassNameKey = @"attributeValueClassName"; NSString * const kMagicalRecordImportRelationshipMapKey = @"mappedKeyName"; NSString * const kMagicalRecordImportRelationshipLinkedByKey = @"relatedByAttribute"; NSString * const kMagicalRecordImportRelationshipTypeKey = @"type"; //this needs to be revisited NSString * const kMagicalRecordImportAttributeUseDefaultValueWhenNotPresent = @"useDefaultValueWhenNotPresent"; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" @implementation NSManagedObject (MagicalRecord_DataImport) - (BOOL) MR_importValue:(id)value forKey:(NSString *)key { NSString *selectorString = [NSString stringWithFormat:@"import%@:", [key MR_capitalizedFirstCharacterString]]; SEL selector = NSSelectorFromString(selectorString); if ([self respondsToSelector:selector]) { [self performSelector:selector withObject:value]; return YES; } return NO; } - (void) MR_setAttributes:(NSDictionary *)attributes forKeysWithObject:(id)objectData { for (NSString *attributeName in attributes) { NSAttributeDescription *attributeInfo = [attributes valueForKey:attributeName]; NSString *lookupKeyPath = [objectData MR_lookupKeyForAttribute:attributeInfo]; if (lookupKeyPath) { id value = [attributeInfo MR_valueForKeyPath:lookupKeyPath fromObjectData:objectData]; if (![self MR_importValue:value forKey:attributeName]) { [self setValue:value forKey:attributeName]; } } else { if ([[[attributeInfo userInfo] objectForKey:kMagicalRecordImportAttributeUseDefaultValueWhenNotPresent] boolValue]) { id value = [attributeInfo defaultValue]; if (![self MR_importValue:value forKey:attributeName]) { [self setValue:value forKey:attributeName]; } } } } } - (NSManagedObject *) MR_findObjectForRelationship:(NSRelationshipDescription *)relationshipInfo withData:(id)singleRelatedObjectData { NSEntityDescription *destinationEntity = [relationshipInfo destinationEntity]; NSManagedObject *objectForRelationship = nil; id relatedValue = [singleRelatedObjectData MR_relatedValueForRelationship:relationshipInfo]; if (relatedValue) { NSManagedObjectContext *context = [self managedObjectContext]; Class managedObjectClass = NSClassFromString([destinationEntity managedObjectClassName]); NSString *primaryKey = [relationshipInfo MR_primaryKey]; objectForRelationship = [managedObjectClass MR_findFirstByAttribute:primaryKey withValue:relatedValue inContext:context]; } return objectForRelationship; } - (void) MR_addObject:(NSManagedObject *)relatedObject forRelationship:(NSRelationshipDescription *)relationshipInfo { NSAssert2(relatedObject != nil, @"Cannot add nil to %@ for attribute %@", NSStringFromClass([self class]), [relationshipInfo name]); NSAssert2([relatedObject entity] == [relationshipInfo destinationEntity], @"related object entity %@ not same as destination entity %@", [relatedObject entity], [relationshipInfo destinationEntity]); //add related object to set NSString *addRelationMessageFormat = @"set%@:"; id relationshipSource = self; if ([relationshipInfo isToMany]) { addRelationMessageFormat = @"add%@Object:"; if ([relationshipInfo respondsToSelector:@selector(isOrdered)] && [relationshipInfo isOrdered]) { //Need to get the ordered set NSString *selectorName = [[relationshipInfo name] stringByAppendingString:@"Set"]; relationshipSource = [self performSelector:NSSelectorFromString(selectorName)]; addRelationMessageFormat = @"addObject:"; } } NSString *addRelatedObjectToSetMessage = [NSString stringWithFormat:addRelationMessageFormat, attributeNameFromString([relationshipInfo name])]; SEL selector = NSSelectorFromString(addRelatedObjectToSetMessage); @try { [relationshipSource performSelector:selector withObject:relatedObject]; } @catch (NSException *exception) { MRLog(@"Adding object for relationship failed: %@\n", relationshipInfo); MRLog(@"relatedObject.entity %@", [relatedObject entity]); MRLog(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]); MRLog(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage); MRLog(@"perform selector error: %@", exception); } } - (void) MR_setRelationships:(NSDictionary *)relationships forKeysWithObject:(id)relationshipData withBlock:(void(^)(NSRelationshipDescription *,id))setRelationshipBlock { for (NSString *relationshipName in relationships) { if ([self MR_importValue:relationshipData forKey:relationshipName]) { continue; } NSRelationshipDescription *relationshipInfo = [relationships valueForKey:relationshipName]; NSString *lookupKey = [[relationshipInfo userInfo] valueForKey:kMagicalRecordImportRelationshipMapKey] ?: relationshipName; id relatedObjectData = [relationshipData valueForKeyPath:lookupKey]; if (relatedObjectData == nil || [relatedObjectData isEqual:[NSNull null]]) { continue; } SEL shouldImportSelector = NSSelectorFromString([NSString stringWithFormat:@"shouldImport%@:", [relationshipName MR_capitalizedFirstCharacterString]]); BOOL implementsShouldImport = (BOOL)[self respondsToSelector:shouldImportSelector]; void (^establishRelationship)(NSRelationshipDescription *, id) = ^(NSRelationshipDescription *blockInfo, id blockData) { if (!(implementsShouldImport && !(BOOL)[self performSelector:shouldImportSelector withObject:relatedObjectData])) { setRelationshipBlock(blockInfo, blockData); } }; if ([relationshipInfo isToMany] && [relatedObjectData isKindOfClass:[NSArray class]]) { for (id singleRelatedObjectData in relatedObjectData) { establishRelationship(relationshipInfo, singleRelatedObjectData); } } else { establishRelationship(relationshipInfo, relatedObjectData); } } } - (BOOL) MR_preImport:(id)objectData; { if ([self respondsToSelector:@selector(shouldImport:)]) { BOOL shouldImport = (BOOL)[self performSelector:@selector(shouldImport:) withObject:objectData]; if (!shouldImport) { return NO; } } if ([self respondsToSelector:@selector(willImport:)]) { [self performSelector:@selector(willImport:) withObject:objectData]; } MR_swapMethodsFromClass([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:)); return YES; } - (BOOL) MR_postImport:(id)objectData; { MR_swapMethodsFromClass([objectData class], @selector(valueForUndefinedKey:), @selector(MR_valueForUndefinedKey:)); if ([self respondsToSelector:@selector(didImport:)]) { [self performSelector:@selector(didImport:) withObject:objectData]; } return YES; } - (BOOL) MR_performDataImportFromObject:(id)objectData relationshipBlock:(void(^)(NSRelationshipDescription*, id))relationshipBlock; { BOOL didStartimporting = [self MR_preImport:objectData]; if (!didStartimporting) return NO; NSDictionary *attributes = [[self entity] attributesByName]; [self MR_setAttributes:attributes forKeysWithObject:objectData]; NSDictionary *relationships = [[self entity] relationshipsByName]; [self MR_setRelationships:relationships forKeysWithObject:objectData withBlock:relationshipBlock]; return [self MR_postImport:objectData]; } - (BOOL) MR_importValuesForKeysWithObject:(id)objectData { typeof(self) weakself = self; return [self MR_performDataImportFromObject:objectData relationshipBlock:^(NSRelationshipDescription *relationshipInfo, id localObjectData) { NSManagedObject *relatedObject = [weakself MR_findObjectForRelationship:relationshipInfo withData:localObjectData]; if (relatedObject == nil) { NSEntityDescription *entityDescription = [relationshipInfo destinationEntity]; relatedObject = [entityDescription MR_createInstanceInContext:[weakself managedObjectContext]]; } [relatedObject MR_importValuesForKeysWithObject:localObjectData]; [weakself MR_addObject:relatedObject forRelationship:relationshipInfo]; } ]; } + (id) MR_importFromObject:(id)objectData inContext:(NSManagedObjectContext *)context; { NSAttributeDescription *primaryAttribute = [[self MR_entityDescription] MR_primaryAttributeToRelateBy]; id value = [objectData MR_valueForAttribute:primaryAttribute]; NSManagedObject *managedObject = [self MR_findFirstByAttribute:[primaryAttribute name] withValue:value inContext:context]; if (managedObject == nil) { managedObject = [self MR_createInContext:context]; } [managedObject MR_importValuesForKeysWithObject:objectData]; return managedObject; } + (id) MR_importFromObject:(id)objectData { return [self MR_importFromObject:objectData inContext:[NSManagedObjectContext MR_defaultContext]]; } + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData { return [self MR_importFromArray:listOfObjectData inContext:[NSManagedObjectContext MR_defaultContext]]; } + (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData inContext:(NSManagedObjectContext *)context { NSMutableArray *objectIDs = [NSMutableArray array]; [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { [listOfObjectData enumerateObjectsWithOptions:0 usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSDictionary *objectData = (NSDictionary *)obj; NSManagedObject *dataObject = [self MR_importFromObject:objectData inContext:localContext]; if ([context obtainPermanentIDsForObjects:[NSArray arrayWithObject:dataObject] error:nil]) { [objectIDs addObject:[dataObject objectID]]; } }]; }]; return [self MR_findAllWithPredicate:[NSPredicate predicateWithFormat:@"self IN %@", objectIDs] inContext:context]; } @end #pragma clang diagnostic pop void MR_swapMethodsFromClass(Class c, SEL orig, SEL new) { Method origMethod = class_getInstanceMethod(c, orig); Method newMethod = class_getInstanceMethod(c, new); if (class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); } else { method_exchangeImplementations(origMethod, newMethod); } } ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.h ================================================ // // NSManagedObject+MagicalFinders.h // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import @interface NSManagedObject (MagicalFinders) + (NSArray *) MR_findAll; + (NSArray *) MR_findAllInContext:(NSManagedObjectContext *)context; + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending; + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm; + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm; + (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (id) MR_findFirst; + (id) MR_findFirstInContext:(NSManagedObjectContext *)context; + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm; + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (id) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending; + (id) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes; + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context; + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ...; + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ...; + (id) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; + (id) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; + (id) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending; + (id) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue; + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending; + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id)delegate; + (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id)delegate inContext:(NSManagedObjectContext *)context; + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate; + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate inContext:(NSManagedObjectContext *)context; + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending; + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate; + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate inContext:(NSManagedObjectContext *)context; #endif @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalFinders.m ================================================ // // NSManagedObject+MagicalFinders.m // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "NSManagedObject+MagicalFinders.h" #import "NSManagedObject+MagicalRequests.h" #import "NSManagedObject+MagicalRecord.h" #import "NSManagedObjectContext+MagicalThreading.h" @implementation NSManagedObject (MagicalFinders) #pragma mark - Finding Data + (NSArray *) MR_findAllInContext:(NSManagedObjectContext *)context { return [self MR_executeFetchRequest:[self MR_requestAllInContext:context] inContext:context]; } + (NSArray *) MR_findAll { return [self MR_findAllInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending inContext:context]; return [self MR_executeFetchRequest:request inContext:context]; } + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending { return [self MR_findAllSortedBy:sortTerm ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:context]; return [self MR_executeFetchRequest:request inContext:context]; } + (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm { return [self MR_findAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; [request setPredicate:searchTerm]; return [self MR_executeFetchRequest:request inContext:context]; } + (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm { return [self MR_findAllWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (id) MR_findFirstInContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } + (id) MR_findFirst { return [self MR_findFirstInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (id) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestFirstByAttribute:attribute withValue:searchValue inContext:context]; // [request setPropertiesToFetch:[NSArray arrayWithObject:attribute]]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } + (id) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue { return [self MR_findFirstByAttribute:attribute withValue:searchValue inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (id) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; { NSFetchRequest *request = [self MR_requestAllSortedBy:attribute ascending:ascending inContext:context]; [request setFetchLimit:1]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } + (id) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending; { return [self MR_findFirstOrderedByAttribute:attribute ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm { return [self MR_findFirstWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestFirstWithPredicate:searchTerm inContext:context]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } + (id) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestAllSortedBy:property ascending:ascending withPredicate:searchterm inContext:context]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } + (id) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending { return [self MR_findFirstWithPredicate:searchterm sortedBy:property ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; [request setPredicate:searchTerm]; [request setPropertiesToFetch:attributes]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes { return [self MR_findFirstWithPredicate:searchTerm andRetrieveAttributes:attributes inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ... { NSFetchRequest *request = [self MR_requestAllSortedBy:sortBy ascending:ascending withPredicate:searchTerm inContext:context]; [request setPropertiesToFetch:[self MR_propertiesNamed:attributes]]; return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context]; } + (id) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ... { return [self MR_findFirstWithPredicate:searchTerm sortedBy:sortBy ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread] andRetrieveAttributes:attributes]; } + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestAllWhere:attribute isEqualTo:searchValue inContext:context]; return [self MR_executeFetchRequest:request inContext:context]; } + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue { return [self MR_findByAttribute:attribute withValue:searchValue inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context { NSPredicate *searchTerm = [NSPredicate predicateWithFormat:@"%K = %@", attribute, searchValue]; NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:context]; return [self MR_executeFetchRequest:request inContext:context]; } + (NSArray *) MR_findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending { return [self MR_findByAttribute:attribute withValue:searchValue andOrderBy:sortTerm ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } #pragma mark - #pragma mark NSFetchedResultsController helpers #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + (NSFetchedResultsController *) MR_fetchController:(NSFetchRequest *)request delegate:(id)delegate useFileCache:(BOOL)useFileCache groupedBy:(NSString *)groupKeyPath inContext:(NSManagedObjectContext *)context { NSString *cacheName = useFileCache ? [NSString stringWithFormat:@"MagicalRecord-Cache-%@", NSStringFromClass([self class])] : nil; NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:groupKeyPath cacheName:cacheName]; controller.delegate = delegate; return controller; } + (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id)delegate; { return [self MR_fetchAllWithDelegate:delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id)delegate inContext:(NSManagedObjectContext *)context; { NSFetchRequest *request = [self MR_requestAllInContext:context]; NSFetchedResultsController *controller = [self MR_fetchController:request delegate:delegate useFileCache:NO groupedBy:nil inContext:context]; [self MR_performFetch:controller]; return controller; } + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:context]; NSFetchedResultsController *controller = [self MR_fetchController:request delegate:delegate useFileCache:NO groupedBy:group inContext:context]; [self MR_performFetch:controller]; return controller; } + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate { return [self MR_fetchAllGroupedBy:group withPredicate:searchTerm sortedBy:sortTerm ascending:ascending delegate:delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; { return [self MR_fetchAllGroupedBy:group withPredicate:searchTerm sortedBy:sortTerm ascending:ascending delegate:nil inContext:context]; } + (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending { return [self MR_fetchAllGroupedBy:group withPredicate:searchTerm sortedBy:sortTerm ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:context]; NSFetchedResultsController *controller = [self MR_fetchController:request delegate:nil useFileCache:NO groupedBy:groupingKeyPath inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; [self MR_performFetch:controller]; return controller; } + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath; { return [self MR_fetchAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm groupBy:groupingKeyPath inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate inContext:(NSManagedObjectContext *)context { NSFetchedResultsController *controller = [self MR_fetchAllGroupedBy:groupingKeyPath withPredicate:searchTerm sortedBy:sortTerm ascending:ascending delegate:delegate inContext:context]; [self MR_performFetch:controller]; return controller; } + (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate { return [self MR_fetchAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm groupBy:groupingKeyPath delegate:delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } #endif @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.h ================================================ // // // Created by Saul Mora on 11/15/09. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #import #import "MagicalRecord.h" #define kMagicalRecordDefaultBatchSize 20 @interface NSManagedObject (MagicalRecord) + (NSUInteger) MR_defaultBatchSize; + (void) MR_setDefaultBatchSize:(NSUInteger)newBatchSize; + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request; + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context; + (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request; + (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context; #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + (void) MR_performFetch:(NSFetchedResultsController *)controller; #endif + (NSEntityDescription *) MR_entityDescription; + (NSEntityDescription *) MR_entityDescriptionInContext:(NSManagedObjectContext *)context; + (NSArray *) MR_propertiesNamed:(NSArray *)properties; + (id) MR_createEntity; + (id) MR_createInContext:(NSManagedObjectContext *)context; - (BOOL) MR_deleteEntity; - (BOOL) MR_deleteInContext:(NSManagedObjectContext *)context; + (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate; + (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; + (BOOL) MR_truncateAll; + (BOOL) MR_truncateAllInContext:(NSManagedObjectContext *)context; + (NSArray *) MR_ascendingSortDescriptors:(NSArray *)attributesToSortBy; + (NSArray *) MR_descendingSortDescriptors:(NSArray *)attributesToSortBy; - (id) MR_inContext:(NSManagedObjectContext *)otherContext; - (id) MR_inThreadContext; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRecord.m ================================================ // Created by Saul Mora on 11/15/09. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #import "CoreData+MagicalRecord.h" static NSUInteger defaultBatchSize = kMagicalRecordDefaultBatchSize; @implementation NSManagedObject (MagicalRecord) + (void) MR_setDefaultBatchSize:(NSUInteger)newBatchSize { @synchronized(self) { defaultBatchSize = newBatchSize; } } + (NSUInteger) MR_defaultBatchSize { return defaultBatchSize; } + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context { __block NSArray *results = nil; [context performBlockAndWait:^{ NSError *error = nil; results = [context executeFetchRequest:request error:&error]; if (results == nil) { [MagicalRecord handleErrors:error]; } }]; return results; } + (NSArray *) MR_executeFetchRequest:(NSFetchRequest *)request { return [self MR_executeFetchRequest:request inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context { [request setFetchLimit:1]; NSArray *results = [self MR_executeFetchRequest:request inContext:context]; if ([results count] == 0) { return nil; } return [results objectAtIndex:0]; } + (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request { return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } #if TARGET_OS_IPHONE + (void) MR_performFetch:(NSFetchedResultsController *)controller { NSError *error = nil; if (![controller performFetch:&error]) { [MagicalRecord handleErrors:error]; } } #endif + (NSString *) MR_entityName { return NSStringFromClass(self); } + (NSEntityDescription *) MR_entityDescriptionInContext:(NSManagedObjectContext *)context { if ([self respondsToSelector:@selector(entityInManagedObjectContext:)]) { NSEntityDescription *entity = [self performSelector:@selector(entityInManagedObjectContext:) withObject:context]; return entity; } else { NSString *entityName = [self MR_entityName]; return [NSEntityDescription entityForName:entityName inManagedObjectContext:context]; } } + (NSEntityDescription *) MR_entityDescription { return [self MR_entityDescriptionInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSArray *) MR_propertiesNamed:(NSArray *)properties { NSEntityDescription *description = [self MR_entityDescription]; NSMutableArray *propertiesWanted = [NSMutableArray array]; if (properties) { NSDictionary *propDict = [description propertiesByName]; for (NSString *propertyName in properties) { NSPropertyDescription *property = [propDict objectForKey:propertyName]; if (property) { [propertiesWanted addObject:property]; } else { MRLog(@"Property '%@' not found in %lx properties for %@", propertyName, (unsigned long)[propDict count], NSStringFromClass(self)); } } } return propertiesWanted; } + (NSArray *) MR_sortAscending:(BOOL)ascending attributes:(NSArray *)attributesToSortBy { NSMutableArray *attributes = [NSMutableArray array]; for (NSString *attributeName in attributesToSortBy) { NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:attributeName ascending:ascending]; [attributes addObject:sortDescriptor]; } return attributes; } + (NSArray *) MR_ascendingSortDescriptors:(NSArray *)attributesToSortBy { return [self MR_sortAscending:YES attributes:attributesToSortBy]; } + (NSArray *) MR_descendingSortDescriptors:(NSArray *)attributesToSortBy { return [self MR_sortAscending:NO attributes:attributesToSortBy]; } #pragma mark - + (id) MR_createInContext:(NSManagedObjectContext *)context { if ([self respondsToSelector:@selector(insertInManagedObjectContext:)]) { id entity = [self performSelector:@selector(insertInManagedObjectContext:) withObject:context]; return entity; } else { return [NSEntityDescription insertNewObjectForEntityForName:[self MR_entityName] inManagedObjectContext:context]; } } + (id) MR_createEntity { NSManagedObject *newEntity = [self MR_createInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; return newEntity; } - (BOOL) MR_deleteInContext:(NSManagedObjectContext *)context { [context deleteObject:self]; return YES; } - (BOOL) MR_deleteEntity { [self MR_deleteInContext:[self managedObjectContext]]; return YES; } + (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestAllWithPredicate:predicate inContext:context]; [request setReturnsObjectsAsFaults:YES]; [request setIncludesPropertyValues:NO]; NSArray *objectsToTruncate = [self MR_executeFetchRequest:request inContext:context]; for (id objectToTruncate in objectsToTruncate) { [objectToTruncate MR_deleteInContext:context]; } return YES; } + (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate { return [self MR_deleteAllMatchingPredicate:predicate inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (BOOL) MR_truncateAllInContext:(NSManagedObjectContext *)context { NSArray *allEntities = [self MR_findAllInContext:context]; for (NSManagedObject *obj in allEntities) { [obj MR_deleteInContext:context]; } return YES; } + (BOOL) MR_truncateAll { [self MR_truncateAllInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; return YES; } - (id) MR_inContext:(NSManagedObjectContext *)otherContext { NSError *error = nil; NSManagedObject *inContext = [otherContext existingObjectWithID:[self objectID] error:&error]; [MagicalRecord handleErrors:error]; return inContext; } - (id) MR_inThreadContext { NSManagedObject *weakSelf = self; return [weakSelf MR_inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.h ================================================ // // NSManagedObject+MagicalRequests.h // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import @interface NSManagedObject (MagicalRequests) + (NSFetchRequest *) MR_createFetchRequest; + (NSFetchRequest *) MR_createFetchRequestInContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) MR_requestAll; + (NSFetchRequest *) MR_requestAllInContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) MR_requestAllWithPredicate:(NSPredicate *)searchTerm; + (NSFetchRequest *) MR_requestAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) MR_requestAllWhere:(NSString *)property isEqualTo:(id)value; + (NSFetchRequest *) MR_requestAllWhere:(NSString *)property isEqualTo:(id)value inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) MR_requestFirstWithPredicate:(NSPredicate *)searchTerm; + (NSFetchRequest *) MR_requestFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) MR_requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; + (NSFetchRequest *) MR_requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending; + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm; + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObject/NSManagedObject+MagicalRequests.m ================================================ // // NSManagedObject+MagicalRequests.m // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "NSManagedObject+MagicalRequests.h" #import "NSManagedObject+MagicalRecord.h" #import "NSManagedObjectContext+MagicalThreading.h" @implementation NSManagedObject (MagicalRequests) + (NSFetchRequest *)MR_createFetchRequestInContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:[self MR_entityDescriptionInContext:context]]; return request; } + (NSFetchRequest *) MR_createFetchRequest { return [self MR_createFetchRequestInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchRequest *) MR_requestAll { return [self MR_createFetchRequestInContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchRequest *) MR_requestAllInContext:(NSManagedObjectContext *)context { return [self MR_createFetchRequestInContext:context]; } + (NSFetchRequest *) MR_requestAllWithPredicate:(NSPredicate *)searchTerm; { return [self MR_requestAllWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchRequest *) MR_requestAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; { NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; [request setPredicate:searchTerm]; return request; } + (NSFetchRequest *) MR_requestAllWhere:(NSString *)property isEqualTo:(id)value { return [self MR_requestAllWhere:property isEqualTo:value inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchRequest *) MR_requestAllWhere:(NSString *)property isEqualTo:(id)value inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; [request setPredicate:[NSPredicate predicateWithFormat:@"%K = %@", property, value]]; return request; } + (NSFetchRequest *) MR_requestFirstWithPredicate:(NSPredicate *)searchTerm { return [self MR_requestFirstWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchRequest *) MR_requestFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_createFetchRequestInContext:context]; [request setPredicate:searchTerm]; [request setFetchLimit:1]; return request; } + (NSFetchRequest *) MR_requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; { return [self MR_requestFirstByAttribute:attribute withValue:searchValue inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchRequest *) MR_requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; { NSFetchRequest *request = [self MR_requestAllWhere:attribute isEqualTo:searchValue inContext:context]; [request setFetchLimit:1]; return request; } + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context { return [self MR_requestAllSortedBy:sortTerm ascending:ascending withPredicate:nil inContext:context]; } + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending { return [self MR_requestAllSortedBy:sortTerm ascending:ascending inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; } + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context { NSFetchRequest *request = [self MR_requestAllInContext:context]; if (searchTerm) { [request setPredicate:searchTerm]; } [request setFetchBatchSize:[self MR_defaultBatchSize]]; NSMutableArray* sortDescriptors = [[NSMutableArray alloc] init]; NSArray* sortKeys = [sortTerm componentsSeparatedByString:@","]; for (NSString* sortKey in sortKeys) { NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:ascending]; [sortDescriptors addObject:sortDescriptor]; } [request setSortDescriptors:sortDescriptors]; return request; } + (NSFetchRequest *) MR_requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm; { NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm ascending:ascending withPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]]; return request; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.h ================================================ // // NSManagedObjectContext+MagicalObserving.h // Magical Record // // Created by Saul Mora on 3/9/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import @interface NSManagedObjectContext (MagicalObserving) - (void) MR_observeContext:(NSManagedObjectContext *)otherContext; - (void) MR_stopObservingContext:(NSManagedObjectContext *)otherContext; - (void) MR_observeContextOnMainThread:(NSManagedObjectContext *)otherContext; - (void) MR_observeiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; - (void) MR_stopObservingiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalObserving.m ================================================ // // NSManagedObjectContext+MagicalObserving.m // Magical Record // // Created by Saul Mora on 3/9/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "NSManagedObjectContext+MagicalObserving.h" #import "NSManagedObjectContext+MagicalRecord.h" #import "MagicalRecord.h" #import "MagicalRecord+iCloud.h" NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification = @"kMagicalRecordDidMergeChangesFromiCloudNotification"; @implementation NSManagedObjectContext (MagicalObserving) #pragma mark - Context Observation Helpers - (void) MR_observeContext:(NSManagedObjectContext *)otherContext { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver:self selector:@selector(MR_mergeChangesFromNotification:) name:NSManagedObjectContextDidSaveNotification object:otherContext]; } - (void) MR_observeContextOnMainThread:(NSManagedObjectContext *)otherContext { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver:self selector:@selector(MR_mergeChangesOnMainThread:) name:NSManagedObjectContextDidSaveNotification object:otherContext]; } - (void) MR_stopObservingContext:(NSManagedObjectContext *)otherContext { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:NSManagedObjectContextDidSaveNotification object:otherContext]; } #pragma mark - Context iCloud Merge Helpers - (void) MR_mergeChangesFromiCloud:(NSNotification *)notification; { [self performBlock:^{ MRLog(@"Merging changes From iCloud %@context%@", self == [NSManagedObjectContext MR_defaultContext] ? @"*** DEFAULT *** " : @"", ([NSThread isMainThread] ? @" *** on Main Thread ***" : @"")); [self mergeChangesFromContextDidSaveNotification:notification]; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter postNotificationName:kMagicalRecordDidMergeChangesFromiCloudNotification object:self userInfo:[notification userInfo]]; }]; } - (void) MR_mergeChangesFromNotification:(NSNotification *)notification; { MRLog(@"Merging changes to %@context%@", self == [NSManagedObjectContext MR_defaultContext] ? @"*** DEFAULT *** " : @"", ([NSThread isMainThread] ? @" *** on Main Thread ***" : @"")); [self mergeChangesFromContextDidSaveNotification:notification]; } - (void) MR_mergeChangesOnMainThread:(NSNotification *)notification; { if ([NSThread isMainThread]) { [self MR_mergeChangesFromNotification:notification]; } else { [self performSelectorOnMainThread:@selector(MR_mergeChangesFromNotification:) withObject:notification waitUntilDone:YES]; } } - (void) MR_observeiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; { if (![MagicalRecord isICloudEnabled]) return; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver:self selector:@selector(MR_mergeChangesFromiCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator]; } - (void) MR_stopObservingiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; { if (![MagicalRecord isICloudEnabled]) return; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator]; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.h ================================================ // // NSManagedObjectContext+MagicalRecord.h // // Created by Saul Mora on 11/23/09. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #import "MagicalRecord.h" extern NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification; @interface NSManagedObjectContext (MagicalRecord) + (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator; + (NSManagedObjectContext *) MR_context NS_RETURNS_RETAINED; + (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext NS_RETURNS_RETAINED; + (NSManagedObjectContext *) MR_newMainQueueContext NS_RETURNS_RETAINED; + (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator NS_RETURNS_RETAINED; + (void) MR_resetDefaultContext; + (NSManagedObjectContext *) MR_rootSavingContext; + (NSManagedObjectContext *) MR_defaultContext; - (NSString *) MR_description; - (NSString *) MR_parentChain; @property (nonatomic, copy, setter = MR_setWorkingName:) NSString *MR_workingName; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalRecord.m ================================================ // // NSManagedObjectContext+MagicalRecord.m // // Created by Saul Mora on 11/23/09. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #import "CoreData+MagicalRecord.h" #import static NSManagedObjectContext *rootSavingContext = nil; static NSManagedObjectContext *defaultManagedObjectContext_ = nil; static id iCloudSetupNotificationObserver = nil; static NSString * const kMagicalRecordNSManagedObjectContextWorkingName = @"kNSManagedObjectContextWorkingName"; @interface NSManagedObjectContext (MagicalRecordInternal) - (void) MR_mergeChangesFromNotification:(NSNotification *)notification; - (void) MR_mergeChangesOnMainThread:(NSNotification *)notification; + (void) MR_setDefaultContext:(NSManagedObjectContext *)moc; + (void) MR_setRootSavingContext:(NSManagedObjectContext *)context; @end @implementation NSManagedObjectContext (MagicalRecord) + (void) MR_cleanUp; { [self MR_setDefaultContext:nil]; [self MR_setRootSavingContext:nil]; } - (NSString *) MR_description; { NSString *contextLabel = [NSString stringWithFormat:@"*** %@ ***", [self MR_workingName]]; NSString *onMainThread = [NSThread isMainThread] ? @"*** MAIN THREAD ***" : @"*** BACKGROUND THREAD ***"; return [NSString stringWithFormat:@"<%@ (%p): %@> on %@", NSStringFromClass([self class]), self, contextLabel, onMainThread]; } - (NSString *) MR_parentChain; { NSMutableString *familyTree = [@"\n" mutableCopy]; NSManagedObjectContext *currentContext = self; do { [familyTree appendFormat:@"- %@ (%p) %@\n", [currentContext MR_workingName], currentContext, (currentContext == self ? @"(*)" : @"")]; } while ((currentContext = [currentContext parentContext])); return [NSString stringWithString:familyTree]; } + (NSManagedObjectContext *) MR_defaultContext { @synchronized (self) { NSAssert(defaultManagedObjectContext_ != nil, @"Default Context is nil! Did you forget to initialize the Core Data Stack?"); return defaultManagedObjectContext_; } } + (void) MR_setDefaultContext:(NSManagedObjectContext *)moc { if (defaultManagedObjectContext_) { [[NSNotificationCenter defaultCenter] removeObserver:defaultManagedObjectContext_]; } NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_defaultStoreCoordinator]; if (iCloudSetupNotificationObserver) { [[NSNotificationCenter defaultCenter] removeObserver:iCloudSetupNotificationObserver]; iCloudSetupNotificationObserver = nil; } if ([MagicalRecord isICloudEnabled]) { [defaultManagedObjectContext_ MR_stopObservingiCloudChangesInCoordinator:coordinator]; } defaultManagedObjectContext_ = moc; [defaultManagedObjectContext_ MR_setWorkingName:@"DEFAULT"]; if ((defaultManagedObjectContext_ != nil) && ([self MR_rootSavingContext] != nil)) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rootContextChanged:) name:NSManagedObjectContextDidSaveNotification object:[self MR_rootSavingContext]]; } [moc MR_obtainPermanentIDsBeforeSaving]; if ([MagicalRecord isICloudEnabled]) { [defaultManagedObjectContext_ MR_observeiCloudChangesInCoordinator:coordinator]; } else { // If icloud is NOT enabled at the time of this method being called, listen for it to be setup later, and THEN set up observing cloud changes iCloudSetupNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMagicalRecordPSCDidCompleteiCloudSetupNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { [[NSManagedObjectContext MR_defaultContext] MR_observeiCloudChangesInCoordinator:coordinator]; }]; } MRLog(@"Set Default Context: %@", defaultManagedObjectContext_); } + (void)rootContextChanged:(NSNotification *)notification { if ([NSThread isMainThread] == NO) { dispatch_async(dispatch_get_main_queue(), ^{ [self rootContextChanged:notification]; }); return; } [[self MR_defaultContext] mergeChangesFromContextDidSaveNotification:notification]; } + (NSManagedObjectContext *) MR_rootSavingContext; { return rootSavingContext; } + (void) MR_setRootSavingContext:(NSManagedObjectContext *)context; { if (rootSavingContext) { [[NSNotificationCenter defaultCenter] removeObserver:rootSavingContext]; } rootSavingContext = context; [context MR_obtainPermanentIDsBeforeSaving]; [rootSavingContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; [rootSavingContext MR_setWorkingName:@"BACKGROUND SAVING (ROOT)"]; MRLog(@"Set Root Saving Context: %@", rootSavingContext); } + (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator; { if (defaultManagedObjectContext_ == nil) { NSManagedObjectContext *rootContext = [self MR_contextWithStoreCoordinator:coordinator]; [self MR_setRootSavingContext:rootContext]; NSManagedObjectContext *defaultContext = [self MR_newMainQueueContext]; [self MR_setDefaultContext:defaultContext]; [defaultContext setParentContext:rootContext]; } } + (void) MR_resetDefaultContext { void (^resetBlock)(void) = ^{ [[NSManagedObjectContext MR_defaultContext] reset]; }; dispatch_async(dispatch_get_main_queue(), resetBlock); } + (NSManagedObjectContext *) MR_contextWithoutParent; { NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; return context; } + (NSManagedObjectContext *) MR_context; { NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [context setParentContext:[self MR_defaultContext]]; return context; } + (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext; { NSManagedObjectContext *context = [self MR_contextWithoutParent]; [context setParentContext:parentContext]; [context MR_obtainPermanentIDsBeforeSaving]; return context; } + (NSManagedObjectContext *) MR_newMainQueueContext; { NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; MRLog(@"Created Main Queue Context: %@", context); return context; } + (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator; { NSManagedObjectContext *context = nil; if (coordinator != nil) { context = [self MR_contextWithoutParent]; [context performBlockAndWait:^{ [context setPersistentStoreCoordinator:coordinator]; }]; MRLog(@"-> Created Context %@", [context MR_workingName]); } return context; } - (void) MR_obtainPermanentIDsBeforeSaving; { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(MR_contextWillSave:) name:NSManagedObjectContextWillSaveNotification object:self]; } - (void) MR_contextWillSave:(NSNotification *)notification { NSManagedObjectContext *context = [notification object]; NSSet *insertedObjects = [context insertedObjects]; if ([insertedObjects count]) { MRLog(@"Context %@ is about to save. Obtaining permanent IDs for new %lu inserted objects", [context MR_workingName], (unsigned long)[insertedObjects count]); NSError *error = nil; BOOL success = [context obtainPermanentIDsForObjects:[insertedObjects allObjects] error:&error]; if (!success) { [MagicalRecord handleErrors:error]; } } } - (void) MR_setWorkingName:(NSString *)workingName; { [[self userInfo] setObject:workingName forKey:kMagicalRecordNSManagedObjectContextWorkingName]; } - (NSString *) MR_workingName; { NSString *workingName = [[self userInfo] objectForKey:kMagicalRecordNSManagedObjectContextWorkingName]; if (nil == workingName) { workingName = @"UNNAMED"; } return workingName; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.h ================================================ // // NSManagedObjectContext+MagicalSaves.h // Magical Record // // Created by Saul Mora on 3/9/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import typedef NS_OPTIONS(NSUInteger, MRSaveContextOptions) { MRSaveParentContexts = 1, ///< When saving, continue saving parent contexts until the changes are present in the persistent store MRSaveSynchronously = 2 ///< Peform saves synchronously, blocking execution on the current thread until the save is complete }; typedef void (^MRSaveCompletionHandler)(BOOL success, NSError *error); @interface NSManagedObjectContext (MagicalSaves) /// \brief Asynchronously save changes in the current context and it's parent /// \param completion Completion block that is called after the save has completed. The block is passed a success state as a `BOOL` and an `NSError` instance if an error occurs. Always called on the main queue. /// \discussion Executes a save on the current context's dispatch queue asynchronously. This method only saves the current context, and the parent of the current context if one is set. The completion block will always be called on the main queue. - (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion; /// \brief Asynchronously save changes in the current context all the way back to the persistent store /// \param completion Completion block that is called after the save has completed. The block is passed a success state as a `BOOL` and an `NSError` instance if an error occurs. Always called on the main queue. /// \discussion Executes asynchronous saves on the current context, and any ancestors, until the changes have been persisted to the assigned persistent store. The completion block will always be called on the main queue. - (void) MR_saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion; /// \brief Synchronously save changes in the current context and it's parent /// \discussion Executes a save on the current context's dispatch queue. This method only saves the current context, and the parent of the current context if one is set. The method will not return until the save is complete. - (void) MR_saveOnlySelfAndWait; /// \brief Synchronously save changes in the current context all the way back to the persistent store /// \discussion Executes saves on the current context, and any ancestors, until the changes have been persisted to the assigned persistent store. The method will not return until the save is complete. - (void) MR_saveToPersistentStoreAndWait; /// \brief Save the current context with options /// \param mask bitmasked options for the save process /// \param completion Completion block that is called after the save has completed. The block is passed a success state as a `BOOL` and an `NSError` instance if an error occurs. Always called on the main queue. /// \discussion All other save methods are conveniences to this method. - (void) MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion; /* DEPRECATION NOTICE: * The following methods are deprecated, but remain in place for backwards compatibility until the next major version (3.x) */ /// \brief Synchronously save changes in the current context all the way back to the persistent store /// \discussion Replaced by \MR_saveToPersistentStoreAndWait /// \deprecated - (void) MR_save __attribute__((deprecated)); /// \brief Synchronously save changes in the current context all the way back to the persistent store /// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread. /// \deprecated - (void) MR_saveWithErrorCallback:(void(^)(NSError *error))errorCallback __attribute__((deprecated)); /// \brief Asynchronously save changes in the current context and it's parent /// \param completion Completion block that is called after the save has completed. Always called on the main queue. /// \deprecated - (void) MR_saveInBackgroundCompletion:(void (^)(void))completion __attribute__((deprecated)); /// \brief Asynchronously save changes in the current context and it's parent /// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread. /// \deprecated - (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated)); /// \brief Asynchronously save changes in the current context and it's parent /// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread. /// \param completion Completion block that is called after the save has completed. Always called on the main queue. /// \deprecated - (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated)); /// \brief Asynchronously save changes in the current context all the way back to the persistent store /// \discussion Replaced by \MR_saveToPersistentStoreWithCompletion: /// \deprecated - (void) MR_saveNestedContexts __attribute__((deprecated)); /// \brief Asynchronously save changes in the current context all the way back to the persistent store /// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread. /// \discussion Replaced by \MR_saveToPersistentStoreWithCompletion: /// \deprecated - (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated)); /// \brief Asynchronously save changes in the current context all the way back to the persistent store /// \param errorCallback Block that is called if an error is encountered while saving. Always called on the main thread. /// \param completion Completion block that is called after the save has completed. Always called on the main queue. /// \discussion Replaced by \MR_saveToPersistentStoreWithCompletion: /// \deprecated - (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated)); @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalSaves.m ================================================ // // NSManagedObjectContext+MagicalSaves.m // Magical Record // // Created by Saul Mora on 3/9/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "NSManagedObjectContext+MagicalSaves.h" #import "MagicalRecord+ErrorHandling.h" #import "NSManagedObjectContext+MagicalRecord.h" #import "MagicalRecord.h" @implementation NSManagedObjectContext (MagicalSaves) - (void)MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion; { [self MR_saveWithOptions:0 completion:completion]; } - (void)MR_saveOnlySelfAndWait; { [self MR_saveWithOptions:MRSaveSynchronously completion:nil]; } - (void) MR_saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion; { [self MR_saveWithOptions:MRSaveParentContexts completion:completion]; } - (void) MR_saveToPersistentStoreAndWait; { [self MR_saveWithOptions:MRSaveParentContexts | MRSaveSynchronously completion:nil]; } - (void)MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion; { BOOL syncSave = ((mask & MRSaveSynchronously) == MRSaveSynchronously); BOOL saveParentContexts = ((mask & MRSaveParentContexts) == MRSaveParentContexts); if (![self hasChanges]) { MRLog(@"NO CHANGES IN ** %@ ** CONTEXT - NOT SAVING", [self MR_workingName]); if (completion) { dispatch_async(dispatch_get_main_queue(), ^{ completion(NO, nil); }); } return; } MRLog(@"→ Saving %@", [self MR_description]); MRLog(@"→ Save Parents? %@", @(saveParentContexts)); MRLog(@"→ Save Synchronously? %@", @(syncSave)); id saveBlock = ^{ NSError *error = nil; BOOL saved = NO; @try { saved = [self save:&error]; } @catch(NSException *exception) { MRLog(@"Unable to perform save: %@", (id)[exception userInfo] ? : (id)[exception reason]); } @finally { if (!saved) { [MagicalRecord handleErrors:error]; if (completion) { dispatch_async(dispatch_get_main_queue(), ^{ completion(saved, error); }); } } else { // If we're the default context, save to disk too (the user expects it to persist) BOOL isDefaultContext = (self == [[self class] MR_defaultContext]); BOOL shouldSaveParentContext = ((YES == saveParentContexts) || isDefaultContext); if (shouldSaveParentContext && [self parentContext]) { [[self parentContext] MR_saveWithOptions:mask completion:completion]; } // If we should not save the parent context, or there is not a parent context to save (root context), call the completion block else { MRLog(@"→ Finished saving: %@", [self MR_description]); if (completion) { dispatch_async(dispatch_get_main_queue(), ^{ completion(saved, error); }); } } } } }; if (YES == syncSave) { [self performBlockAndWait:saveBlock]; } else { [self performBlock:saveBlock]; } } #pragma mark - Deprecated methods // These methods will be removed in MagicalRecord 3.0 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-implementations" - (void)MR_save; { [self MR_saveToPersistentStoreAndWait]; } - (void)MR_saveWithErrorCallback:(void (^)(NSError *error))errorCallback; { [self MR_saveWithOptions:MRSaveSynchronously|MRSaveParentContexts completion:^(BOOL success, NSError *error) { if (!success) { if (errorCallback) { errorCallback(error); } } }]; } - (void)MR_saveInBackgroundCompletion:(void (^)(void))completion; { [self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) { if (success) { if (completion) { completion(); } } }]; } - (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback; { [self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) { if (!success) { if (errorCallback) { errorCallback(error); } } }]; } - (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion; { [self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) { if (success) { if (completion) { completion(); } } else { if (errorCallback) { errorCallback(error); } } }]; } - (void)MR_saveNestedContexts; { [self MR_saveToPersistentStoreWithCompletion:nil]; } - (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback; { [self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) { if (!success) { if (errorCallback) { errorCallback(error); } } }]; } - (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion; { [self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) { if (success) { if (completion) { completion(); } } else { if (errorCallback) { errorCallback(error); } } }]; } #pragma clang diagnostic pop // ignored "-Wdeprecated-implementations" @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.h ================================================ // // NSManagedObjectContext+MagicalThreading.h // Magical Record // // Created by Saul Mora on 3/9/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import @interface NSManagedObjectContext (MagicalThreading) + (NSManagedObjectContext *) MR_contextForCurrentThread; + (void) MR_resetContextForCurrentThread; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectContext/NSManagedObjectContext+MagicalThreading.m ================================================ // // NSManagedObjectContext+MagicalThreading.m // Magical Record // // Created by Saul Mora on 3/9/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "NSManagedObjectContext+MagicalThreading.h" #import "NSManagedObject+MagicalRecord.h" #import "NSManagedObjectContext+MagicalRecord.h" static NSString const * kMagicalRecordManagedObjectContextKey = @"MagicalRecord_NSManagedObjectContextForThreadKey"; @implementation NSManagedObjectContext (MagicalThreading) + (void)MR_resetContextForCurrentThread { [[NSManagedObjectContext MR_contextForCurrentThread] reset]; } + (NSManagedObjectContext *) MR_contextForCurrentThread; { if ([NSThread isMainThread]) { return [self MR_defaultContext]; } else { NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary]; NSManagedObjectContext *threadContext = [threadDict objectForKey:kMagicalRecordManagedObjectContextKey]; if (threadContext == nil) { threadContext = [self MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]]; [threadDict setObject:threadContext forKey:kMagicalRecordManagedObjectContextKey]; } return threadContext; } } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.h ================================================ // // NSManagedObjectModel+MagicalRecord.h // // Created by Saul Mora on 3/11/10. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #import #import "MagicalRecord.h" @interface NSManagedObjectModel (MagicalRecord) + (NSManagedObjectModel *) MR_defaultManagedObjectModel; + (void) MR_setDefaultManagedObjectModel:(NSManagedObjectModel *)newDefaultModel; + (NSManagedObjectModel *) MR_mergedObjectModelFromMainBundle; + (NSManagedObjectModel *) MR_newManagedObjectModelNamed:(NSString *)modelFileName NS_RETURNS_RETAINED; + (NSManagedObjectModel *) MR_managedObjectModelNamed:(NSString *)modelFileName; + (NSManagedObjectModel *) MR_newModelNamed:(NSString *) modelName inBundleNamed:(NSString *) bundleName NS_RETURNS_RETAINED; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSManagedObjectModel+MagicalRecord.m ================================================ // // NSManagedObjectModel+MagicalRecord.m // // Created by Saul Mora on 3/11/10. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // //#import "NSManagedObjectModel+MagicalRecord.h" #import "CoreData+MagicalRecord.h" static NSManagedObjectModel *defaultManagedObjectModel_ = nil; @implementation NSManagedObjectModel (MagicalRecord) + (NSManagedObjectModel *) MR_defaultManagedObjectModel { if (defaultManagedObjectModel_ == nil && [MagicalRecord shouldAutoCreateManagedObjectModel]) { [self MR_setDefaultManagedObjectModel:[self MR_mergedObjectModelFromMainBundle]]; } return defaultManagedObjectModel_; } + (void) MR_setDefaultManagedObjectModel:(NSManagedObjectModel *)newDefaultModel { defaultManagedObjectModel_ = newDefaultModel; } + (NSManagedObjectModel *) MR_mergedObjectModelFromMainBundle; { return [self mergedModelFromBundles:nil]; } + (NSManagedObjectModel *) MR_newModelNamed:(NSString *) modelName inBundleNamed:(NSString *) bundleName { NSString *path = [[NSBundle mainBundle] pathForResource:[modelName stringByDeletingPathExtension] ofType:[modelName pathExtension] inDirectory:bundleName]; NSURL *modelUrl = [NSURL fileURLWithPath:path]; NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl]; return mom; } + (NSManagedObjectModel *) MR_newManagedObjectModelNamed:(NSString *)modelFileName { NSString *path = [[NSBundle mainBundle] pathForResource:[modelFileName stringByDeletingPathExtension] ofType:[modelFileName pathExtension]]; NSURL *momURL = [NSURL fileURLWithPath:path]; NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; return model; } + (NSManagedObjectModel *) MR_managedObjectModelNamed:(NSString *)modelFileName { NSManagedObjectModel *model = [self MR_newManagedObjectModelNamed:modelFileName]; return model; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.h ================================================ // // NSPersistentStore+MagicalRecord.h // // Created by Saul Mora on 3/11/10. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #import "MagicalRecord.h" // option to autodelete store if it already exists extern NSString * const kMagicalRecordDefaultStoreFileName; @interface NSPersistentStore (MagicalRecord) + (NSURL *) MR_defaultLocalStoreUrl; + (NSPersistentStore *) MR_defaultPersistentStore; + (void) MR_setDefaultPersistentStore:(NSPersistentStore *) store; + (NSURL *) MR_urlForStoreName:(NSString *)storeFileName; + (NSURL *) MR_cloudURLForUbiqutiousContainer:(NSString *)bucketName; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSPersistentStore+MagicalRecord.m ================================================ // // NSPersistentStore+MagicalRecord.m // // Created by Saul Mora on 3/11/10. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // //#import "NSPersistentStore+MagicalRecord.h" #import "CoreData+MagicalRecord.h" NSString * const kMagicalRecordDefaultStoreFileName = @"CoreDataStore.sqlite"; static NSPersistentStore *defaultPersistentStore_ = nil; @implementation NSPersistentStore (MagicalRecord) + (NSPersistentStore *) MR_defaultPersistentStore { return defaultPersistentStore_; } + (void) MR_setDefaultPersistentStore:(NSPersistentStore *) store { defaultPersistentStore_ = store; } + (NSString *) MR_directory:(int) type { return [NSSearchPathForDirectoriesInDomains(type, NSUserDomainMask, YES) lastObject]; } + (NSString *)MR_applicationDocumentsDirectory { return [self MR_directory:NSDocumentDirectory]; } + (NSString *)MR_applicationStorageDirectory { NSString *applicationName = [[[NSBundle mainBundle] infoDictionary] valueForKey:(NSString *)kCFBundleNameKey]; return [[self MR_directory:NSApplicationSupportDirectory] stringByAppendingPathComponent:applicationName]; } + (NSURL *) MR_urlForStoreName:(NSString *)storeFileName { NSArray *paths = [NSArray arrayWithObjects:[self MR_applicationDocumentsDirectory], [self MR_applicationStorageDirectory], nil]; NSFileManager *fm = [[NSFileManager alloc] init]; for (NSString *path in paths) { NSString *filepath = [path stringByAppendingPathComponent:storeFileName]; if ([fm fileExistsAtPath:filepath]) { return [NSURL fileURLWithPath:filepath]; } } //set default url return [NSURL fileURLWithPath:[[self MR_applicationStorageDirectory] stringByAppendingPathComponent:storeFileName]]; } + (NSURL *) MR_cloudURLForUbiqutiousContainer:(NSString *)bucketName; { NSFileManager *fileManager = [[NSFileManager alloc] init]; NSURL *cloudURL = nil; if ([fileManager respondsToSelector:@selector(URLForUbiquityContainerIdentifier:)]) { cloudURL = [fileManager URLForUbiquityContainerIdentifier:bucketName]; } return cloudURL; } + (NSURL *) MR_defaultLocalStoreUrl { return [self MR_urlForStoreName:kMagicalRecordDefaultStoreFileName]; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.h ================================================ // // NSPersistentStoreCoordinator+MagicalRecord.h // // Created by Saul Mora on 3/11/10. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #import "MagicalRecord.h" #import "NSPersistentStore+MagicalRecord.h" extern NSString * const kMagicalRecordPSCDidCompleteiCloudSetupNotification; @interface NSPersistentStoreCoordinator (MagicalRecord) + (NSPersistentStoreCoordinator *) MR_defaultStoreCoordinator; + (void) MR_setDefaultStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator; + (NSPersistentStoreCoordinator *) MR_coordinatorWithInMemoryStore; + (NSPersistentStoreCoordinator *) MR_newPersistentStoreCoordinator NS_RETURNS_RETAINED; + (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreNamed:(NSString *)storeFileName; + (NSPersistentStoreCoordinator *) MR_coordinatorWithAutoMigratingSqliteStoreNamed:(NSString *)storeFileName; + (NSPersistentStoreCoordinator *) MR_coordinatorWithPersistentStore:(NSPersistentStore *)persistentStore; + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionHandler; - (NSPersistentStore *) MR_addInMemoryStore; - (NSPersistentStore *) MR_addAutoMigratingSqliteStoreNamed:(NSString *) storeFileName; - (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__autoreleasing NSDictionary *)options; - (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; - (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Categories/NSPersistentStoreCoordinator+MagicalRecord.m ================================================ // // NSPersistentStoreCoordinator+MagicalRecord.m // // Created by Saul Mora on 3/11/10. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #import "CoreData+MagicalRecord.h" static NSPersistentStoreCoordinator *defaultCoordinator_ = nil; NSString * const kMagicalRecordPSCDidCompleteiCloudSetupNotification = @"kMagicalRecordPSCDidCompleteiCloudSetupNotification"; @interface NSDictionary (MagicalRecordMerging) - (NSMutableDictionary*) MR_dictionaryByMergingDictionary:(NSDictionary*)d; @end @interface MagicalRecord (iCloudPrivate) + (void) setICloudEnabled:(BOOL)enabled; @end @implementation NSPersistentStoreCoordinator (MagicalRecord) + (NSPersistentStoreCoordinator *) MR_defaultStoreCoordinator { if (defaultCoordinator_ == nil && [MagicalRecord shouldAutoCreateDefaultPersistentStoreCoordinator]) { [self MR_setDefaultStoreCoordinator:[self MR_newPersistentStoreCoordinator]]; } return defaultCoordinator_; } + (void) MR_setDefaultStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator { defaultCoordinator_ = coordinator; if (defaultCoordinator_ != nil) { NSArray *persistentStores = [defaultCoordinator_ persistentStores]; if ([persistentStores count] && [NSPersistentStore MR_defaultPersistentStore] == nil) { [NSPersistentStore MR_setDefaultPersistentStore:[persistentStores objectAtIndex:0]]; } } } - (void) MR_createPathToStoreFileIfNeccessary:(NSURL *)urlForStore { NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *pathToStore = [urlForStore URLByDeletingLastPathComponent]; NSError *error = nil; BOOL pathWasCreated = [fileManager createDirectoryAtPath:[pathToStore path] withIntermediateDirectories:YES attributes:nil error:&error]; if (!pathWasCreated) { [MagicalRecord handleErrors:error]; } } - (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName withOptions:(__autoreleasing NSDictionary *)options { NSURL *url = [storeFileName isKindOfClass:[NSURL class]] ? storeFileName : [NSPersistentStore MR_urlForStoreName:storeFileName]; NSError *error = nil; [self MR_createPathToStoreFileIfNeccessary:url]; NSPersistentStore *store = [self addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:options error:&error]; if (!store && [MagicalRecord shouldDeleteStoreOnModelMismatch]) { BOOL isMigrationError = [error code] == NSPersistentStoreIncompatibleVersionHashError || [error code] == NSMigrationMissingSourceModelError; if ([[error domain] isEqualToString:NSCocoaErrorDomain] && isMigrationError) { // Could not open the database, so... kill it! [[NSFileManager defaultManager] removeItemAtURL:url error:nil]; MRLog(@"Removed incompatible model version: %@", [url lastPathComponent]); // Try one more time to create the store store = [self addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:options error:&error]; if (store) { // If we successfully added a store, remove the error that was initially created error = nil; } } [MagicalRecord handleErrors:error]; } return store; } #pragma mark - Public Instance Methods - (NSPersistentStore *) MR_addInMemoryStore { NSError *error = nil; NSPersistentStore *store = [self addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:&error]; if (!store) { [MagicalRecord handleErrors:error]; } return store; } + (NSDictionary *) MR_autoMigrationOptions; { // Adding the journalling mode recommended by apple NSMutableDictionary *sqliteOptions = [NSMutableDictionary dictionary]; [sqliteOptions setObject:@"WAL" forKey:@"journal_mode"]; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, sqliteOptions, NSSQLitePragmasOption, nil]; return options; } - (NSPersistentStore *) MR_addAutoMigratingSqliteStoreNamed:(NSString *) storeFileName; { NSDictionary *options = [[self class] MR_autoMigrationOptions]; return [self MR_addSqliteStoreNamed:storeFileName withOptions:options]; } #pragma mark - Public Class Methods + (NSPersistentStoreCoordinator *) MR_coordinatorWithAutoMigratingSqliteStoreNamed:(NSString *) storeFileName { NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; [coordinator MR_addAutoMigratingSqliteStoreNamed:storeFileName]; //HACK: lame solution to fix automigration error "Migration failed after first pass" if ([[coordinator persistentStores] count] == 0) { [coordinator performSelector:@selector(MR_addAutoMigratingSqliteStoreNamed:) withObject:storeFileName afterDelay:0.5]; } return coordinator; } + (NSPersistentStoreCoordinator *) MR_coordinatorWithInMemoryStore { NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; [coordinator MR_addInMemoryStore]; return coordinator; } + (NSPersistentStoreCoordinator *) MR_newPersistentStoreCoordinator { NSPersistentStoreCoordinator *coordinator = [self MR_coordinatorWithSqliteStoreNamed:[MagicalRecord defaultStoreName]]; return coordinator; } - (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; { [self MR_addiCloudContainerID:containerID contentNameKey:contentNameKey localStoreNamed:localStoreName cloudStorePathComponent:subPathComponent completion:nil]; } - (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock; { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSURL *cloudURL = [NSPersistentStore MR_cloudURLForUbiqutiousContainer:containerID]; if (subPathComponent) { cloudURL = [cloudURL URLByAppendingPathComponent:subPathComponent]; } [MagicalRecord setICloudEnabled:cloudURL != nil]; NSDictionary *options = [[self class] MR_autoMigrationOptions]; if (cloudURL) //iCloud is available { NSDictionary *iCloudOptions = [NSDictionary dictionaryWithObjectsAndKeys: contentNameKey, NSPersistentStoreUbiquitousContentNameKey, cloudURL, NSPersistentStoreUbiquitousContentURLKey, nil]; options = [options MR_dictionaryByMergingDictionary:iCloudOptions]; } else { MRLog(@"iCloud is not enabled"); } [self lock]; [self MR_addSqliteStoreNamed:localStoreName withOptions:options]; [self unlock]; dispatch_async(dispatch_get_main_queue(), ^{ if ([NSPersistentStore MR_defaultPersistentStore] == nil) { [NSPersistentStore MR_setDefaultPersistentStore:[[self persistentStores] objectAtIndex:0]]; } if (completionBlock) { completionBlock(); } NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter postNotificationName:kMagicalRecordPSCDidCompleteiCloudSetupNotification object:nil]; }); }); } + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; { return [self MR_coordinatorWithiCloudContainerID:containerID contentNameKey:contentNameKey localStoreNamed:localStoreName cloudStorePathComponent:subPathComponent completion:nil]; } + (NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionHandler; { NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; [psc MR_addiCloudContainerID:containerID contentNameKey:contentNameKey localStoreNamed:localStoreName cloudStorePathComponent:subPathComponent completion:completionHandler]; return psc; } + (NSPersistentStoreCoordinator *) MR_coordinatorWithPersistentStore:(NSPersistentStore *)persistentStore; { NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; [psc MR_addSqliteStoreNamed:[persistentStore URL] withOptions:nil]; return psc; } + (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreNamed:(NSString *)storeFileName withOptions:(NSDictionary *)options { NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel]; NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; [psc MR_addSqliteStoreNamed:storeFileName withOptions:options]; return psc; } + (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreNamed:(NSString *)storeFileName { return [self MR_coordinatorWithSqliteStoreNamed:storeFileName withOptions:nil]; } @end @implementation NSDictionary (Merging) - (NSMutableDictionary *) MR_dictionaryByMergingDictionary:(NSDictionary *)d; { NSMutableDictionary *mutDict = [self mutableCopy]; [mutDict addEntriesFromDictionary:d]; return mutDict; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+Actions.h ================================================ // // MagicalRecord+Actions.h // // Created by Saul Mora on 2/24/11. // Copyright 2011 Magical Panda Software. All rights reserved. // #import #import "NSManagedObjectContext+MagicalRecord.h" #import "NSManagedObjectContext+MagicalSaves.h" @interface MagicalRecord (Actions) /* For all background saving operations. These calls will be sent to a different thread/queue. */ + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block; + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; /* For saving on the current thread as the caller, only with a seperate context. Useful when you're managing your own threads/queues and need a serial call to create or change data */ + (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block; /* If you want to reuse the context on the current thread, use these methods. */ + (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; + (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block; /* DEPRECATION NOTICE: * The following methods are deprecated, but remain in place for backwards compatibility until the next major version (3.x) */ /* For all background saving operations. These calls will be sent to a different thread/queue. */ + (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block __attribute__((deprecated)); + (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion __attribute__((deprecated)); /* If you want to reuse the context on the current thread, use this method. */ + (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler __attribute__((deprecated)); @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+Actions.m ================================================ // // MagicalRecord+Actions.m // // Created by Saul Mora on 2/24/11. // Copyright 2011 Magical Panda Software. All rights reserved. // #import "CoreData+MagicalRecord.h" #import "NSManagedObjectContext+MagicalRecord.h" @implementation MagicalRecord (Actions) #pragma mark - Asynchronous saving + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block; { [self saveWithBlock:block completion:nil]; } + (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; { NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_rootSavingContext]; NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:mainContext]; [localContext performBlock:^{ if (block) { block(localContext); } [localContext MR_saveWithOptions:MRSaveParentContexts completion:completion]; }]; } + (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion; { NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread]; [localContext performBlock:^{ if (block) { block(localContext); } [localContext MR_saveWithOptions:MRSaveParentContexts completion:completion]; }]; } #pragma mark - Synchronous saving + (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block; { NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_rootSavingContext]; NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:mainContext]; [localContext performBlockAndWait:^{ if (block) { block(localContext); } [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil]; }]; } + (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block; { NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread]; [localContext performBlockAndWait:^{ if (block) { block(localContext); } [localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil]; }]; } #pragma mark - Deprecated methods #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-implementations" + (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block { [[self class] saveWithBlock:block completion:nil]; } + (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion { NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_defaultContext]; NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:mainContext]; [localContext performBlock:^{ if (block) { block(localContext); } [localContext MR_saveToPersistentStoreAndWait]; if (completion) { completion(); } }]; } + (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler; { NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread]; [localContext performBlock:^{ if (block) { block(localContext); } [localContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) { if (success) { if (completion) { completion(); } } else { if (errorHandler) { errorHandler(error); } } }]; }]; } #pragma clang diagnostic pop // ignored "-Wdeprecated-implementations" @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+ErrorHandling.h ================================================ // // MagicalRecord+ErrorHandling.h // Magical Record // // Created by Saul Mora on 3/6/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord.h" @interface MagicalRecord (ErrorHandling) + (void) handleErrors:(NSError *)error; - (void) handleErrors:(NSError *)error; + (void) setErrorHandlerTarget:(id)target action:(SEL)action; + (SEL) errorHandlerAction; + (id) errorHandlerTarget; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+ErrorHandling.m ================================================ // // MagicalRecord+ErrorHandling.m // Magical Record // // Created by Saul Mora on 3/6/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord+ErrorHandling.h" static id errorHandlerTarget = nil; static SEL errorHandlerAction = nil; @implementation MagicalRecord (ErrorHandling) + (void) cleanUpErrorHanding; { errorHandlerTarget = nil; errorHandlerAction = nil; } + (void) defaultErrorHandler:(NSError *)error { NSDictionary *userInfo = [error userInfo]; for (NSArray *detailedError in [userInfo allValues]) { if ([detailedError isKindOfClass:[NSArray class]]) { for (NSError *e in detailedError) { if ([e respondsToSelector:@selector(userInfo)]) { MRLog(@"Error Details: %@", [e userInfo]); } else { MRLog(@"Error Details: %@", e); } } } else { MRLog(@"Error: %@", detailedError); } } MRLog(@"Error Message: %@", [error localizedDescription]); MRLog(@"Error Domain: %@", [error domain]); MRLog(@"Recovery Suggestion: %@", [error localizedRecoverySuggestion]); } + (void) handleErrors:(NSError *)error { if (error) { // If a custom error handler is set, call that if (errorHandlerTarget != nil && errorHandlerAction != nil) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [errorHandlerTarget performSelector:errorHandlerAction withObject:error]; #pragma clang diagnostic pop } else { // Otherwise, fall back to the default error handling [self defaultErrorHandler:error]; } } } + (id) errorHandlerTarget { return errorHandlerTarget; } + (SEL) errorHandlerAction { return errorHandlerAction; } + (void) setErrorHandlerTarget:(id)target action:(SEL)action { errorHandlerTarget = target; /* Deliberately don't retain to avoid potential retain cycles */ errorHandlerAction = action; } - (void) handleErrors:(NSError *)error { [[self class] handleErrors:error]; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+Options.h ================================================ // // MagicalRecord+Options.h // Magical Record // // Created by Saul Mora on 3/6/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord.h" @interface MagicalRecord (Options) //global options // enable/disable logging // add logging provider // autocreate new PSC per Store // autoassign new instances to default store + (BOOL) shouldAutoCreateManagedObjectModel; + (void) setShouldAutoCreateManagedObjectModel:(BOOL)shouldAutoCreate; + (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator; + (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)shouldAutoCreate; + (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDeleteStoreOnModelMismatch; /*! @method shouldDeleteStoreOnModelMistmatch @abstract If true, when configuring the persistant store coordinator, and Magical Record encounters a store that does not match the model, it will attempt to remove it and re-create a new store. This is extremely useful during development where every model change could potentially require a delete/reinstall of the app. */ + (BOOL) shouldDeleteStoreOnModelMismatch; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+Options.m ================================================ // // MagicalRecord+Options.m // Magical Record // // Created by Saul Mora on 3/6/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord+Options.h" static BOOL shouldAutoCreateManagedObjectModel_; static BOOL shouldAutoCreateDefaultPersistentStoreCoordinator_; static BOOL shouldDeleteStoreOnModelMismatch_; @implementation MagicalRecord (Options) #pragma mark - Options + (BOOL) shouldAutoCreateManagedObjectModel; { return shouldAutoCreateManagedObjectModel_; } + (void) setShouldAutoCreateManagedObjectModel:(BOOL)shouldAutoCreate; { shouldAutoCreateManagedObjectModel_ = shouldAutoCreate; } + (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator; { return shouldAutoCreateDefaultPersistentStoreCoordinator_; } + (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)shouldAutoCreate; { shouldAutoCreateDefaultPersistentStoreCoordinator_ = shouldAutoCreate; } + (BOOL) shouldDeleteStoreOnModelMismatch; { return shouldDeleteStoreOnModelMismatch_; } + (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDeleteStoreOnModelMismatch { shouldDeleteStoreOnModelMismatch_ = shouldDeleteStoreOnModelMismatch; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+Setup.h ================================================ // // MagicalRecord+Setup.h // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord.h" @interface MagicalRecord (Setup) + (void) setupCoreDataStack; + (void) setupCoreDataStackWithInMemoryStore; + (void) setupAutoMigratingCoreDataStack; + (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName; + (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+Setup.m ================================================ // // MagicalRecord+Setup.m // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord+Setup.h" #import "NSManagedObject+MagicalRecord.h" #import "NSPersistentStoreCoordinator+MagicalRecord.h" #import "NSManagedObjectContext+MagicalRecord.h" @implementation MagicalRecord (Setup) + (void) setupCoreDataStack { [self setupCoreDataStackWithStoreNamed:[self defaultStoreName]]; } + (void) setupAutoMigratingCoreDataStack { [self setupCoreDataStackWithAutoMigratingSqliteStoreNamed:[self defaultStoreName]]; } + (void) setupCoreDataStackWithStoreNamed:(NSString *)storeName { if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return; NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreNamed:storeName]; [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator]; [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; } + (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName { if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return; NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithAutoMigratingSqliteStoreNamed:storeName]; [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator]; [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; } + (void) setupCoreDataStackWithInMemoryStore; { if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return; NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithInMemoryStore]; [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator]; [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+ShorthandSupport.h ================================================ // // MagicalRecord+ShorthandSupport.h // Magical Record // // Created by Saul Mora on 3/6/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord.h" @interface MagicalRecord (ShorthandSupport) #ifdef MR_SHORTHAND + (void) swizzleShorthandMethods; #endif @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+ShorthandSupport.m ================================================ // // MagicalRecord+ShorthandSupport.m // Magical Record // // Created by Saul Mora on 3/6/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord+ShorthandSupport.h" #import static NSString * const kMagicalRecordCategoryPrefix = @"MR_"; #ifdef MR_SHORTHAND static BOOL methodsHaveBeenSwizzled = NO; #endif //Dynamic shorthand method helpers BOOL addMagicalRecordShortHandMethodToPrefixedClassMethod(Class class, SEL selector); BOOL addMagicalRecordShorthandMethodToPrefixedInstanceMethod(Class klass, SEL originalSelector); void swizzleInstanceMethods(Class originalClass, SEL originalSelector, Class targetClass, SEL newSelector); void replaceSelectorForTargetWithSourceImpAndSwizzle(Class originalClass, SEL originalSelector, Class newClass, SEL newSelector); @implementation MagicalRecord (ShorthandSupport) #pragma mark - Support methods for shorthand methods #ifdef MR_SHORTHAND + (BOOL) MR_resolveClassMethod:(SEL)originalSelector { BOOL resolvedClassMethod = [self MR_resolveClassMethod:originalSelector]; if (!resolvedClassMethod) { resolvedClassMethod = addMagicalRecordShortHandMethodToPrefixedClassMethod(self, originalSelector); } return resolvedClassMethod; } + (BOOL) MR_resolveInstanceMethod:(SEL)originalSelector { BOOL resolvedClassMethod = [self MR_resolveInstanceMethod:originalSelector]; if (!resolvedClassMethod) { resolvedClassMethod = addMagicalRecordShorthandMethodToPrefixedInstanceMethod(self, originalSelector); } return resolvedClassMethod; } //In order to add support for non-prefixed AND prefixed methods, we need to swap the existing resolveClassMethod: and resolveInstanceMethod: implementations with the one in this class. + (void) updateResolveMethodsForClass:(Class)klass { replaceSelectorForTargetWithSourceImpAndSwizzle(self, @selector(MR_resolveClassMethod:), klass, @selector(resolveClassMethod:)); replaceSelectorForTargetWithSourceImpAndSwizzle(self, @selector(MR_resolveInstanceMethod:), klass, @selector(resolveInstanceMethod:)); } + (void) swizzleShorthandMethods; { if (methodsHaveBeenSwizzled) return; NSArray *classes = [NSArray arrayWithObjects: [NSManagedObject class], [NSManagedObjectContext class], [NSManagedObjectModel class], [NSPersistentStore class], [NSPersistentStoreCoordinator class], nil]; [classes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { Class klass = (Class)obj; [self updateResolveMethodsForClass:klass]; }]; methodsHaveBeenSwizzled = YES; } #endif @end #pragma mark - Support functions for runtime shorthand Method calling void replaceSelectorForTargetWithSourceImpAndSwizzle(Class sourceClass, SEL sourceSelector, Class targetClass, SEL targetSelector) { Method sourceClassMethod = class_getClassMethod(sourceClass, sourceSelector); Method targetClassMethod = class_getClassMethod(targetClass, targetSelector); Class targetMetaClass = objc_getMetaClass([NSStringFromClass(targetClass) cStringUsingEncoding:NSUTF8StringEncoding]); BOOL methodWasAdded = class_addMethod(targetMetaClass, sourceSelector, method_getImplementation(targetClassMethod), method_getTypeEncoding(targetClassMethod)); if (methodWasAdded) { class_replaceMethod(targetMetaClass, targetSelector, method_getImplementation(sourceClassMethod), method_getTypeEncoding(sourceClassMethod)); } } BOOL addMagicalRecordShorthandMethodToPrefixedInstanceMethod(Class klass, SEL originalSelector) { NSString *originalSelectorString = NSStringFromSelector(originalSelector); if ([originalSelectorString hasPrefix:@"_"] || [originalSelectorString hasPrefix:@"init"]) return NO; if (![originalSelectorString hasPrefix:kMagicalRecordCategoryPrefix]) { NSString *prefixedSelector = [kMagicalRecordCategoryPrefix stringByAppendingString:originalSelectorString]; Method existingMethod = class_getInstanceMethod(klass, NSSelectorFromString(prefixedSelector)); if (existingMethod) { BOOL methodWasAdded = class_addMethod(klass, originalSelector, method_getImplementation(existingMethod), method_getTypeEncoding(existingMethod)); return methodWasAdded; } } return NO; } BOOL addMagicalRecordShortHandMethodToPrefixedClassMethod(Class klass, SEL originalSelector) { NSString *originalSelectorString = NSStringFromSelector(originalSelector); if (![originalSelectorString hasPrefix:kMagicalRecordCategoryPrefix]) { NSString *prefixedSelector = [kMagicalRecordCategoryPrefix stringByAppendingString:originalSelectorString]; Method existingMethod = class_getClassMethod(klass, NSSelectorFromString(prefixedSelector)); if (existingMethod) { Class metaClass = objc_getMetaClass([NSStringFromClass(klass) cStringUsingEncoding:NSUTF8StringEncoding]); BOOL methodWasAdded = class_addMethod(metaClass, originalSelector, method_getImplementation(existingMethod), method_getTypeEncoding(existingMethod)); return methodWasAdded; } } return NO; } ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+iCloud.h ================================================ // // MagicalRecord+iCloud.h // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord.h" @interface MagicalRecord (iCloud) + (BOOL) isICloudEnabled; + (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore; + (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent; + (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void(^)(void))completion; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord+iCloud.m ================================================ // // MagicalRecord+iCloud.m // Magical Record // // Created by Saul Mora on 3/7/12. // Copyright (c) 2012 Magical Panda Software LLC. All rights reserved. // #import "MagicalRecord+iCloud.h" #import "NSPersistentStoreCoordinator+MagicalRecord.h" #import "NSManagedObjectContext+MagicalRecord.h" static BOOL _iCloudEnabled = NO; @implementation MagicalRecord (iCloud) #pragma mark - iCloud Methods + (BOOL) isICloudEnabled; { return _iCloudEnabled; } + (void) setICloudEnabled:(BOOL)enabled; { @synchronized(self) { _iCloudEnabled = enabled; } } + (void) setupCoreDataStackWithiCloudContainer:(NSString *)icloudBucket localStoreNamed:(NSString *)localStore; { NSString *contentNameKey = [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleIdentifierKey]; [self setupCoreDataStackWithiCloudContainer:icloudBucket contentNameKey:contentNameKey localStoreNamed:localStore cloudStorePathComponent:nil]; } + (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent; { [self setupCoreDataStackWithiCloudContainer:containerID contentNameKey:contentNameKey localStoreNamed:localStoreName cloudStorePathComponent:pathSubcomponent completion:nil]; } + (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void(^)(void))completion; { NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithiCloudContainerID:containerID contentNameKey:contentNameKey localStoreNamed:localStoreName cloudStorePathComponent:pathSubcomponent completion:completion]; [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator]; [NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator]; } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord.h ================================================ // // MagicalRecord.h // // Created by Saul Mora on 3/11/10. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #if TARGET_OS_IPHONE == 0 #define MAC_PLATFORM_ONLY YES #endif // enable to use caches for the fetchedResultsControllers (iOS only) // #define STORE_USE_CACHE #ifndef MR_ENABLE_ACTIVE_RECORD_LOGGING /* #ifdef DEBUG #define MR_ENABLE_ACTIVE_RECORD_LOGGING 1 #else #define MR_ENABLE_ACTIVE_RECORD_LOGGING 0 #endif */ //Micle Mark Debug #define MR_ENABLE_ACTIVE_RECORD_LOGGING 0 #endif #if MR_ENABLE_ACTIVE_RECORD_LOGGING != 0 // First, check if we can use Cocoalumberjack for logging #ifdef LOG_VERBOSE // extern int ddLogLevel; #define MRLog(...) DDLogVerbose(__VA_ARGS__) #else #define MRLog(...) NSLog(@"%s(%p) %@", __PRETTY_FUNCTION__, self, [NSString stringWithFormat:__VA_ARGS__]) #endif #else #define MRLog(...) ((void)0) #endif #ifdef NS_BLOCKS_AVAILABLE @class NSManagedObjectContext; typedef void (^CoreDataBlock)(NSManagedObjectContext *context); #endif @interface MagicalRecord : NSObject + (NSString *) currentStack; + (void) cleanUp; + (void) setDefaultModelFromClass:(Class)klass; + (void) setDefaultModelNamed:(NSString *)modelName; + (NSString *) defaultStoreName; @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecord.m ================================================ // // MagicalRecord.m // // Created by Saul Mora on 3/11/10. // Copyright 2010 Magical Panda Software, LLC All rights reserved. // #import "CoreData+MagicalRecord.h" @interface MagicalRecord (Internal) + (void) cleanUpStack; + (void) cleanUpErrorHanding; @end @interface NSManagedObjectContext (MagicalRecordInternal) + (void) MR_cleanUp; @end @implementation MagicalRecord + (void) cleanUp { [self cleanUpErrorHanding]; [self cleanUpStack]; } + (void) cleanUpStack; { [NSManagedObjectContext MR_cleanUp]; [NSManagedObjectModel MR_setDefaultManagedObjectModel:nil]; [NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:nil]; [NSPersistentStore MR_setDefaultPersistentStore:nil]; } + (NSString *) currentStack { NSMutableString *status = [NSMutableString stringWithString:@"Current Default Core Data Stack: ---- \n"]; [status appendFormat:@"Model: %@\n", [[NSManagedObjectModel MR_defaultManagedObjectModel] entityVersionHashesByName]]; [status appendFormat:@"Coordinator: %@\n", [NSPersistentStoreCoordinator MR_defaultStoreCoordinator]]; [status appendFormat:@"Store: %@\n", [NSPersistentStore MR_defaultPersistentStore]]; [status appendFormat:@"Default Context: %@\n", [[NSManagedObjectContext MR_defaultContext] MR_description]]; [status appendFormat:@"Context Chain: \n%@\n", [[NSManagedObjectContext MR_defaultContext] MR_parentChain]]; return status; } + (void) setDefaultModelNamed:(NSString *)modelName; { NSManagedObjectModel *model = [NSManagedObjectModel MR_managedObjectModelNamed:modelName]; [NSManagedObjectModel MR_setDefaultManagedObjectModel:model]; } + (void) setDefaultModelFromClass:(Class)klass; { NSBundle *bundle = [NSBundle bundleForClass:klass]; NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:bundle]]; [NSManagedObjectModel MR_setDefaultManagedObjectModel:model]; } + (NSString *) defaultStoreName; { NSString *defaultName = [[[NSBundle mainBundle] infoDictionary] valueForKey:(id)kCFBundleNameKey]; if (defaultName == nil) { defaultName = kMagicalRecordDefaultStoreFileName; } if (![defaultName hasSuffix:@"sqlite"]) { defaultName = [defaultName stringByAppendingPathExtension:@"sqlite"]; } return defaultName; } #pragma mark - initialize + (void) initialize; { if (self == [MagicalRecord class]) { #ifdef MR_SHORTHAND [self swizzleShorthandMethods]; #endif [self setShouldAutoCreateManagedObjectModel:YES]; [self setShouldAutoCreateDefaultPersistentStoreCoordinator:NO]; #ifdef DEBUG [self setShouldDeleteStoreOnModelMismatch:YES]; #else [self setShouldDeleteStoreOnModelMismatch:NO]; #endif } } @end ================================================ FILE: shakefun/shakefun/MagicalRecord/Core/MagicalRecordShorthand.h ================================================ #ifdef MR_SHORTHAND @interface NSManagedObject (MagicalAggregationShortHand) + (NSNumber *) numberOfEntities; + (NSNumber *) numberOfEntitiesWithContext:(NSManagedObjectContext *)context; + (NSNumber *) numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm; + (NSNumber *) numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (NSUInteger) countOfEntities; + (NSUInteger) countOfEntitiesWithContext:(NSManagedObjectContext *)context; + (NSUInteger) countOfEntitiesWithPredicate:(NSPredicate *)searchFilter; + (NSUInteger) countOfEntitiesWithPredicate:(NSPredicate *)searchFilter inContext:(NSManagedObjectContext *)context; + (BOOL) hasAtLeastOneEntity; + (BOOL) hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context; + (NSNumber *)aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; + (NSNumber *)aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate; - (id) objectWithMinValueFor:(NSString *)property; - (id) objectWithMinValueFor:(NSString *)property inContext:(NSManagedObjectContext *)context; @end @interface NSManagedObject (MagicalRecord_DataImportShortHand) - (BOOL) importValuesForKeysWithObject:(id)objectData; + (id) importFromObject:(id)data; + (id) importFromObject:(id)data inContext:(NSManagedObjectContext *)context; + (NSArray *) importFromArray:(NSArray *)listOfObjectData; + (NSArray *) importFromArray:(NSArray *)listOfObjectData inContext:(NSManagedObjectContext *)context; @end @interface NSManagedObject (MagicalFindersShortHand) + (NSArray *) findAll; + (NSArray *) findAllInContext:(NSManagedObjectContext *)context; + (NSArray *) findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending; + (NSArray *) findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (NSArray *) findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm; + (NSArray *) findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (NSArray *) findAllWithPredicate:(NSPredicate *)searchTerm; + (NSArray *) findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (id) findFirst; + (id) findFirstInContext:(NSManagedObjectContext *)context; + (id) findFirstWithPredicate:(NSPredicate *)searchTerm; + (id) findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (id) findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending; + (id) findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (id) findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes; + (id) findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context; + (id) findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ...; + (id) findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ...; + (id) findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; + (id) findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; + (id) findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending; + (id) findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (NSArray *) findByAttribute:(NSString *)attribute withValue:(id)searchValue; + (NSArray *) findByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; + (NSArray *) findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending; + (NSArray *) findByAttribute:(NSString *)attribute withValue:(id)searchValue andOrderBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + (NSFetchedResultsController *) fetchAllWithDelegate:(id)delegate; + (NSFetchedResultsController *) fetchAllWithDelegate:(id)delegate inContext:(NSManagedObjectContext *)context; + (NSFetchedResultsController *) fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate; + (NSFetchedResultsController *) fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id)delegate inContext:(NSManagedObjectContext *)context; + (NSFetchedResultsController *) fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending; + (NSFetchedResultsController *) fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (NSFetchedResultsController *) fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate; + (NSFetchedResultsController *) fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending delegate:(id)delegate inContext:(NSManagedObjectContext *)context; #endif @end @interface NSManagedObject (MagicalRecordShortHand) + (NSUInteger) defaultBatchSize; + (void) setDefaultBatchSize:(NSUInteger)newBatchSize; + (NSArray *) executeFetchRequest:(NSFetchRequest *)request; + (NSArray *) executeFetchRequest:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context; + (id) executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request; + (id) executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context; #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + (void) performFetch:(NSFetchedResultsController *)controller; #endif + (NSEntityDescription *) entityDescription; + (NSEntityDescription *) entityDescriptionInContext:(NSManagedObjectContext *)context; + (NSArray *) propertiesNamed:(NSArray *)properties; + (id) createEntity; + (id) createInContext:(NSManagedObjectContext *)context; - (BOOL) deleteEntity; - (BOOL) deleteInContext:(NSManagedObjectContext *)context; + (BOOL) deleteAllMatchingPredicate:(NSPredicate *)predicate; + (BOOL) deleteAllMatchingPredicate:(NSPredicate *)predicate inContext:(NSManagedObjectContext *)context; + (BOOL) truncateAll; + (BOOL) truncateAllInContext:(NSManagedObjectContext *)context; + (NSArray *) ascendingSortDescriptors:(NSArray *)attributesToSortBy; + (NSArray *) descendingSortDescriptors:(NSArray *)attributesToSortBy; - (id) inContext:(NSManagedObjectContext *)otherContext; - (id) inThreadContext; @end @interface NSManagedObject (MagicalRequestsShortHand) + (NSFetchRequest *) createFetchRequest; + (NSFetchRequest *) createFetchRequestInContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) requestAll; + (NSFetchRequest *) requestAllInContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) requestAllWithPredicate:(NSPredicate *)searchTerm; + (NSFetchRequest *) requestAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) requestAllWhere:(NSString *)property isEqualTo:(id)value; + (NSFetchRequest *) requestAllWhere:(NSString *)property isEqualTo:(id)value inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) requestFirstWithPredicate:(NSPredicate *)searchTerm; + (NSFetchRequest *) requestFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue; + (NSFetchRequest *) requestFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending; + (NSFetchRequest *) requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context; + (NSFetchRequest *) requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm; + (NSFetchRequest *) requestAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context; @end @interface NSManagedObjectContext (MagicalObservingShortHand) - (void) observeContext:(NSManagedObjectContext *)otherContext; - (void) stopObservingContext:(NSManagedObjectContext *)otherContext; - (void) observeContextOnMainThread:(NSManagedObjectContext *)otherContext; - (void) observeiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; - (void) stopObservingiCloudChangesInCoordinator:(NSPersistentStoreCoordinator *)coordinator; @end @interface NSManagedObjectContext (MagicalRecordShortHand) + (void) initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator; + (NSManagedObjectContext *) context NS_RETURNS_RETAINED; + (NSManagedObjectContext *) contextWithParent:(NSManagedObjectContext *)parentContext NS_RETURNS_RETAINED; + (NSManagedObjectContext *) newMainQueueContext NS_RETURNS_RETAINED; + (NSManagedObjectContext *) contextThatPushesChangesToDefaultContext NS_RETURNS_RETAINED; + (NSManagedObjectContext *) contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator NS_RETURNS_RETAINED; + (void) resetDefaultContext; + (NSManagedObjectContext *) rootSavingContext; + (NSManagedObjectContext *) defaultContext; + (void) cleanUp; - (NSString *) description; @end #import "NSManagedObjectContext+MagicalSaves.h" @interface NSManagedObjectContext (MagicalSavesShortHand) - (void) saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion; - (void) saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion; - (void) saveOnlySelfAndWait; - (void) saveToPersistentStoreAndWait; - (void) saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion; - (void) save __attribute__((deprecated)); - (void) saveWithErrorCallback:(void(^)(NSError *error))errorCallback __attribute__((deprecated)); - (void) saveInBackgroundCompletion:(void (^)(void))completion __attribute__((deprecated)); - (void) saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated)); - (void) saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated)); - (void) saveNestedContexts __attribute__((deprecated)); - (void) saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated)); - (void) saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated)); @end @interface NSManagedObjectContext (MagicalThreadingShortHand) + (NSManagedObjectContext *) contextForCurrentThread; + (NSManagedObjectContext *) contextThatNotifiesDefaultContextOnMainThread; + (NSManagedObjectContext *) contextThatNotifiesDefaultContextOnMainThreadWithCoordinator:(NSPersistentStoreCoordinator *)coordinator; + (void) resetContextForCurrentThread; @end @interface NSManagedObjectModel (MagicalRecordShortHand) + (NSManagedObjectModel *) defaultManagedObjectModel; + (void) setDefaultManagedObjectModel:(NSManagedObjectModel *)newDefaultModel; + (NSManagedObjectModel *) mergedObjectModelFromMainBundle; + (NSManagedObjectModel *) newManagedObjectModelNamed:(NSString *)modelFileName NS_RETURNS_RETAINED; + (NSManagedObjectModel *) managedObjectModelNamed:(NSString *)modelFileName; + (NSManagedObjectModel *) newModelNamed:(NSString *) modelName inBundleNamed:(NSString *) bundleName NS_RETURNS_RETAINED; @end @interface NSPersistentStore (MagicalRecordShortHand) + (NSURL *) defaultLocalStoreUrl; + (NSPersistentStore *) defaultPersistentStore; + (void) setDefaultPersistentStore:(NSPersistentStore *) store; + (NSURL *) urlForStoreName:(NSString *)storeFileName; + (NSURL *) cloudURLForUbiqutiousContainer:(NSString *)bucketName; @end @interface NSPersistentStoreCoordinator (MagicalRecordShortHand) + (NSPersistentStoreCoordinator *) defaultStoreCoordinator; + (void) setDefaultStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator; + (NSPersistentStoreCoordinator *) coordinatorWithInMemoryStore; + (NSPersistentStoreCoordinator *) newPersistentStoreCoordinator NS_RETURNS_RETAINED; + (NSPersistentStoreCoordinator *) coordinatorWithSqliteStoreNamed:(NSString *)storeFileName; + (NSPersistentStoreCoordinator *) coordinatorWithAutoMigratingSqliteStoreNamed:(NSString *)storeFileName; + (NSPersistentStoreCoordinator *) coordinatorWithPersistentStore:(NSPersistentStore *)persistentStore; + (NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; + (NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionHandler; - (NSPersistentStore *) addInMemoryStore; - (NSPersistentStore *) addAutoMigratingSqliteStoreNamed:(NSString *) storeFileName; - (NSPersistentStore *) addSqliteStoreNamed:(id)storeFileName withOptions:(__autoreleasing NSDictionary *)options; - (void) addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent; - (void) addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock; @end #endif ================================================ FILE: shakefun/shakefun/MagicalRecord/CoreData+MagicalRecord.h ================================================ #ifndef NS_BLOCKS_AVAILABLE #warning MagicalRecord requires blocks #endif #ifdef __OBJC__ // #if !( __has_feature(objc_arc) && __has_feature(objc_arc_weak) ) // #error MagicalRecord now requires ARC to be enabled // #endif #import #import #ifdef MR_SHORTHAND #import "MagicalRecordShorthand.h" #endif #import "MagicalRecord.h" #import "MagicalRecord+Actions.h" #import "MagicalRecord+ErrorHandling.h" #import "MagicalRecord+Options.h" #import "MagicalRecord+ShorthandSupport.h" #import "MagicalRecord+Setup.h" #import "MagicalRecord+iCloud.h" #import "NSManagedObject+MagicalRecord.h" #import "NSManagedObject+MagicalRequests.h" #import "NSManagedObject+MagicalFinders.h" #import "NSManagedObject+MagicalAggregation.h" #import "NSManagedObjectContext+MagicalRecord.h" #import "NSManagedObjectContext+MagicalObserving.h" #import "NSManagedObjectContext+MagicalSaves.h" #import "NSManagedObjectContext+MagicalThreading.h" #import "NSPersistentStoreCoordinator+MagicalRecord.h" #import "NSManagedObjectModel+MagicalRecord.h" #import "NSPersistentStore+MagicalRecord.h" #import "MagicalImportFunctions.h" #import "NSManagedObject+MagicalDataImport.h" #import "NSNumber+MagicalDataImport.h" #import "NSObject+MagicalDataImport.h" #import "NSString+MagicalDataImport.h" #import "NSAttributeDescription+MagicalDataImport.h" #import "NSRelationshipDescription+MagicalDataImport.h" #import "NSEntityDescription+MagicalDataImport.h" #endif // @see https://github.com/ccgus/fmdb/commit/aef763eeb64e6fa654e7d121f1df4c16a98d9f4f #define MRDispatchQueueRelease(q) (dispatch_release(q)) #if TARGET_OS_IPHONE #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 #undef MRDispatchQueueRelease #define MRDispatchQueueRelease(q) #endif #else #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 #undef MRDispatchQueueRelease #define MRDispatchQueueRelease(q) #endif #endif ================================================ FILE: shakefun/shakefun/PrefixHeader.pch ================================================ // // PrefixHeader.pch // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #ifndef shakefun_PrefixHeader_pch #define shakefun_PrefixHeader_pch // Include any system framework and library headers here that should be included in all compilation units. // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. #ifdef __OBJC__ #import #import #import "CoreData+MagicalRecord.h" #endif #endif ================================================ FILE: shakefun/shakefun/SVProgressHUD/SVProgressHUD.h ================================================ // // SVProgressHUD.h // // Created by Sam Vermette on 27.03.11. // Copyright 2011 Sam Vermette. All rights reserved. // // https://github.com/samvermette/SVProgressHUD // #import #import enum { SVProgressHUDMaskTypeNone = 1, // allow user interactions while HUD is displayed SVProgressHUDMaskTypeClear, // don't allow SVProgressHUDMaskTypeBlack, // don't allow and dim the UI in the back of the HUD SVProgressHUDMaskTypeGradient // don't allow and dim the UI with a a-la-alert-view bg gradient }; typedef NSUInteger SVProgressHUDMaskType; @interface SVProgressHUD : UIView + (void)show; + (void)showWithStatus:(NSString*)status; + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType; + (void)showWithMaskType:(SVProgressHUDMaskType)maskType; + (void)showSuccessWithStatus:(NSString*)string; + (void)showSuccessWithStatus:(NSString *)string duration:(NSTimeInterval)duration; + (void)showErrorWithStatus:(NSString *)string; + (void)showErrorWithStatus:(NSString *)string duration:(NSTimeInterval)duration; + (void)setStatus:(NSString*)string; // change the HUD loading status while it's showing + (void)dismiss; // simply dismiss the HUD with a fade+scale out animation + (void)dismissWithSuccess:(NSString*)successString; // also displays the success icon image + (void)dismissWithSuccess:(NSString*)successString afterDelay:(NSTimeInterval)seconds; + (void)dismissWithError:(NSString*)errorString; // also displays the error icon image + (void)dismissWithError:(NSString*)errorString afterDelay:(NSTimeInterval)seconds; + (BOOL)isVisible; @end ================================================ FILE: shakefun/shakefun/SVProgressHUD/SVProgressHUD.m ================================================ // // SVProgressHUD.m // // Created by Sam Vermette on 27.03.11. // Copyright 2011 Sam Vermette. All rights reserved. // // https://github.com/samvermette/SVProgressHUD // #import "SVProgressHUD.h" #import @interface SVProgressHUD () @property (nonatomic, readwrite) SVProgressHUDMaskType maskType; @property (nonatomic, strong, readonly) NSTimer *fadeOutTimer; @property (nonatomic, strong, readonly) UIWindow *overlayWindow; @property (nonatomic, strong, readonly) UIView *hudView; @property (nonatomic, strong, readonly) UILabel *stringLabel; @property (nonatomic, strong, readonly) UIImageView *imageView; @property (nonatomic, strong, readonly) UIActivityIndicatorView *spinnerView; @property (nonatomic, readonly) CGFloat visibleKeyboardHeight; - (void)showWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType networkIndicator:(BOOL)show; - (void)setStatus:(NSString*)string; - (void)registerNotifications; - (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle; - (void)positionHUD:(NSNotification*)notification; - (void)dismiss; - (void)dismissWithStatus:(NSString*)string error:(BOOL)error; - (void)dismissWithStatus:(NSString*)string error:(BOOL)error afterDelay:(NSTimeInterval)seconds; @end @implementation SVProgressHUD @synthesize overlayWindow, hudView, maskType, fadeOutTimer, stringLabel, imageView, spinnerView, visibleKeyboardHeight; - (void)dealloc { self.fadeOutTimer = nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; } + (SVProgressHUD*)sharedView { static dispatch_once_t once; static SVProgressHUD *sharedView; dispatch_once(&once, ^ { sharedView = [[SVProgressHUD alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; }); return sharedView; } + (void)setStatus:(NSString *)string { [[SVProgressHUD sharedView] setStatus:string]; } #pragma mark - Show Methods + (void)show { [[SVProgressHUD sharedView] showWithStatus:nil maskType:SVProgressHUDMaskTypeNone networkIndicator:NO]; } + (void)showWithStatus:(NSString *)status { [[SVProgressHUD sharedView] showWithStatus:status maskType:SVProgressHUDMaskTypeNone networkIndicator:NO]; } + (void)showWithMaskType:(SVProgressHUDMaskType)maskType { [[SVProgressHUD sharedView] showWithStatus:nil maskType:maskType networkIndicator:NO]; } + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { [[SVProgressHUD sharedView] showWithStatus:status maskType:maskType networkIndicator:NO]; } + (void)showSuccessWithStatus:(NSString *)string { [SVProgressHUD showSuccessWithStatus:string duration:1]; } + (void)showSuccessWithStatus:(NSString *)string duration:(NSTimeInterval)duration { [SVProgressHUD show]; [SVProgressHUD dismissWithSuccess:string afterDelay:duration]; } + (void)showErrorWithStatus:(NSString *)string { [SVProgressHUD showErrorWithStatus:string duration:1]; } + (void)showErrorWithStatus:(NSString *)string duration:(NSTimeInterval)duration { [SVProgressHUD show]; [SVProgressHUD dismissWithError:string afterDelay:duration]; } #pragma mark - Dismiss Methods + (void)dismiss { [[SVProgressHUD sharedView] dismiss]; } + (void)dismissWithSuccess:(NSString*)successString { [[SVProgressHUD sharedView] dismissWithStatus:successString error:NO]; } + (void)dismissWithSuccess:(NSString *)successString afterDelay:(NSTimeInterval)seconds { [[SVProgressHUD sharedView] dismissWithStatus:successString error:NO afterDelay:seconds]; } + (void)dismissWithError:(NSString*)errorString { [[SVProgressHUD sharedView] dismissWithStatus:errorString error:YES]; } + (void)dismissWithError:(NSString *)errorString afterDelay:(NSTimeInterval)seconds { [[SVProgressHUD sharedView] dismissWithStatus:errorString error:YES afterDelay:seconds]; } #pragma mark - Instance Methods - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { self.userInteractionEnabled = NO; self.backgroundColor = [UIColor clearColor]; self.alpha = 0; self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; } return self; } - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); switch (self.maskType) { case SVProgressHUDMaskTypeBlack: { [[UIColor colorWithWhite:0 alpha:0.5] set]; CGContextFillRect(context, self.bounds); break; } case SVProgressHUDMaskTypeGradient: { size_t locationsCount = 2; CGFloat locations[2] = {0.0f, 1.0f}; CGFloat colors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.75f}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount); CGColorSpaceRelease(colorSpace); CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); float radius = MIN(self.bounds.size.width , self.bounds.size.height) ; CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation); CGGradientRelease(gradient); break; } } } - (void)setStatus:(NSString *)string { CGFloat hudWidth = 100; CGFloat hudHeight = 100; CGFloat stringWidth = 0; CGFloat stringHeight = 0; CGRect labelRect = CGRectZero; if(string) { CGSize stringSize = [string sizeWithFont:self.stringLabel.font constrainedToSize:CGSizeMake(200, 300)]; stringWidth = stringSize.width; stringHeight = stringSize.height; hudHeight = 80+stringHeight; if(stringWidth > hudWidth) hudWidth = ceil(stringWidth/2)*2; if(hudHeight > 100) { labelRect = CGRectMake(12, 66, hudWidth, stringHeight); hudWidth+=24; } else { hudWidth+=24; labelRect = CGRectMake(0, 66, hudWidth, stringHeight); } } self.hudView.bounds = CGRectMake(0, 0, hudWidth, hudHeight); if(string) self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, 36); else self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, CGRectGetHeight(self.hudView.bounds)/2); self.stringLabel.hidden = NO; self.stringLabel.text = string; self.stringLabel.frame = labelRect; if(string) self.spinnerView.center = CGPointMake(ceil(CGRectGetWidth(self.hudView.bounds)/2)+0.5, 40.5); else self.spinnerView.center = CGPointMake(ceil(CGRectGetWidth(self.hudView.bounds)/2)+0.5, ceil(self.hudView.bounds.size.height/2)+0.5); } - (void)setFadeOutTimer:(NSTimer *)newTimer { if(fadeOutTimer) [fadeOutTimer invalidate], fadeOutTimer = nil; if(newTimer) fadeOutTimer = newTimer; } - (void)registerNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(positionHUD:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(positionHUD:) name:UIKeyboardWillHideNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(positionHUD:) name:UIKeyboardDidHideNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(positionHUD:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(positionHUD:) name:UIKeyboardDidShowNotification object:nil]; } - (void)positionHUD:(NSNotification*)notification { CGFloat keyboardHeight; double animationDuration; UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; if(notification) { NSDictionary* keyboardInfo = [notification userInfo]; CGRect keyboardFrame = [[keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; animationDuration = [[keyboardInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; if(notification.name == UIKeyboardWillShowNotification || notification.name == UIKeyboardDidShowNotification) { if(UIInterfaceOrientationIsPortrait(orientation)) keyboardHeight = keyboardFrame.size.height; else keyboardHeight = keyboardFrame.size.width; } else keyboardHeight = 0; } else { keyboardHeight = self.visibleKeyboardHeight; } CGRect orientationFrame = [UIScreen mainScreen].bounds; CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; if(UIInterfaceOrientationIsLandscape(orientation)) { float temp = orientationFrame.size.width; orientationFrame.size.width = orientationFrame.size.height; orientationFrame.size.height = temp; temp = statusBarFrame.size.width; statusBarFrame.size.width = statusBarFrame.size.height; statusBarFrame.size.height = temp; } CGFloat activeHeight = orientationFrame.size.height; if(keyboardHeight > 0) activeHeight += statusBarFrame.size.height*2; activeHeight -= keyboardHeight; CGFloat posY = floor(activeHeight*0.45); CGFloat posX = orientationFrame.size.width/2; CGPoint newCenter; CGFloat rotateAngle; switch (orientation) { case UIInterfaceOrientationPortraitUpsideDown: rotateAngle = M_PI; newCenter = CGPointMake(posX, orientationFrame.size.height-posY); break; case UIInterfaceOrientationLandscapeLeft: rotateAngle = -M_PI/2.0f; newCenter = CGPointMake(posY, posX); break; case UIInterfaceOrientationLandscapeRight: rotateAngle = M_PI/2.0f; newCenter = CGPointMake(orientationFrame.size.height-posY, posX); break; default: // as UIInterfaceOrientationPortrait rotateAngle = 0.0; newCenter = CGPointMake(posX, posY); break; } if(notification) { [UIView animateWithDuration:animationDuration delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ [self moveToPoint:newCenter rotateAngle:rotateAngle]; } completion:NULL]; } else { [self moveToPoint:newCenter rotateAngle:rotateAngle]; } } - (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle { self.hudView.transform = CGAffineTransformMakeRotation(angle); self.hudView.center = newCenter; } #pragma mark - Master show/dismiss methods - (void)showWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType networkIndicator:(BOOL)show { dispatch_async(dispatch_get_main_queue(), ^{ if(!self.superview) [self.overlayWindow addSubview:self]; self.fadeOutTimer = nil; self.imageView.hidden = YES; self.maskType = hudMaskType; [self setStatus:string]; [self.spinnerView startAnimating]; if(self.maskType != SVProgressHUDMaskTypeNone) { self.overlayWindow.userInteractionEnabled = YES; } else { self.overlayWindow.userInteractionEnabled = NO; } [self.overlayWindow makeKeyAndVisible]; [self positionHUD:nil]; if(self.alpha != 1) { [self registerNotifications]; self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1.3, 1.3); [UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState animations:^{ self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1/1.3, 1/1.3); self.alpha = 1; } completion:NULL]; } [self setNeedsDisplay]; }); } - (void)dismissWithStatus:(NSString*)string error:(BOOL)error { [self dismissWithStatus:string error:error afterDelay:0.9]; } - (void)dismissWithStatus:(NSString *)string error:(BOOL)error afterDelay:(NSTimeInterval)seconds { dispatch_async(dispatch_get_main_queue(), ^{ if(self.alpha != 1) return; if(error) self.imageView.image = [UIImage imageNamed:@"SVProgressHUD.bundle/error.png"]; else self.imageView.image = [UIImage imageNamed:@"SVProgressHUD.bundle/success.png"]; self.imageView.hidden = NO; [self setStatus:string]; [self.spinnerView stopAnimating]; self.fadeOutTimer = [NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(dismiss) userInfo:nil repeats:NO]; }); } - (void)dismiss { dispatch_async(dispatch_get_main_queue(), ^{ [UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction animations:^{ self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 0.8, 0.8); self.alpha = 0; } completion:^(BOOL finished){ if(self.alpha == 0) { [[NSNotificationCenter defaultCenter] removeObserver:self]; [hudView removeFromSuperview]; hudView = nil; // Make sure to remove the overlay window from the list of windows // before trying to find the key window in that same list NSMutableArray *windows = [[NSMutableArray alloc] initWithArray:[UIApplication sharedApplication].windows]; [windows removeObject:overlayWindow]; overlayWindow = nil; [windows enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(UIWindow *window, NSUInteger idx, BOOL *stop) { if([window isKindOfClass:[UIWindow class]] && window.windowLevel == UIWindowLevelNormal) { [window makeKeyWindow]; *stop = YES; } }]; // uncomment to make sure UIWindow is gone from app.windows //NSLog(@"%@", [UIApplication sharedApplication].windows); //NSLog(@"keyWindow = %@", [UIApplication sharedApplication].keyWindow); } }]; }); } #pragma mark - Utilities + (BOOL)isVisible { return ([SVProgressHUD sharedView].alpha == 1); } #pragma mark - Getters - (UIWindow *)overlayWindow { if(!overlayWindow) { overlayWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; overlayWindow.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; overlayWindow.backgroundColor = [UIColor clearColor]; overlayWindow.userInteractionEnabled = NO; } return overlayWindow; } - (UIView *)hudView { if(!hudView) { hudView = [[UIView alloc] initWithFrame:CGRectZero]; hudView.layer.cornerRadius = 10; hudView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8]; hudView.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin); [self addSubview:hudView]; } return hudView; } - (UILabel *)stringLabel { if (stringLabel == nil) { stringLabel = [[UILabel alloc] initWithFrame:CGRectZero]; stringLabel.textColor = [UIColor whiteColor]; stringLabel.backgroundColor = [UIColor clearColor]; stringLabel.adjustsFontSizeToFitWidth = YES; stringLabel.textAlignment = UITextAlignmentCenter; stringLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; stringLabel.font = [UIFont boldSystemFontOfSize:16]; stringLabel.shadowColor = [UIColor blackColor]; stringLabel.shadowOffset = CGSizeMake(0, -1); stringLabel.numberOfLines = 0; } if(!stringLabel.superview) [self.hudView addSubview:stringLabel]; return stringLabel; } - (UIImageView *)imageView { if (imageView == nil) imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 28, 28)]; if(!imageView.superview) [self.hudView addSubview:imageView]; return imageView; } - (UIActivityIndicatorView *)spinnerView { if (spinnerView == nil) { spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; spinnerView.hidesWhenStopped = YES; spinnerView.bounds = CGRectMake(0, 0, 37, 37); } if(!spinnerView.superview) [self.hudView addSubview:spinnerView]; return spinnerView; } - (CGFloat)visibleKeyboardHeight { UIWindow *keyboardWindow = nil; for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { if(![[testWindow class] isEqual:[UIWindow class]]) { keyboardWindow = testWindow; break; } } // Locate UIKeyboard. UIView *foundKeyboard = nil; for (__strong UIView *possibleKeyboard in [keyboardWindow subviews]) { // iOS 4 sticks the UIKeyboard inside a UIPeripheralHostView. if ([[possibleKeyboard description] hasPrefix:@" 100) return foundKeyboard.bounds.size.height; return 0; } @end ================================================ FILE: shakefun/shakefun/URLEntity.h ================================================ // // URLEntity.h // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #import #import @interface URLEntity : NSManagedObject @property (nonatomic, retain) NSString * fullurl; @property (nonatomic, retain) NSString * filename; @end ================================================ FILE: shakefun/shakefun/URLEntity.m ================================================ // // URLEntity.m // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #import "URLEntity.h" @implementation URLEntity @dynamic fullurl; @dynamic filename; @end ================================================ FILE: shakefun/shakefun/ViewController.h ================================================ // // ViewController.h // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #import @interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UIWebView *webViewBrowser; - (IBAction)buttonNextToggle:(id)sender; - (IBAction)buttonCollectToggle:(id)sender; @end @interface NSString (TMNSStringExtensionMethods) - (NSArray *)componentsSeparatedFromString:(NSString *)fromString toString:(NSString *)toString; @end ================================================ FILE: shakefun/shakefun/ViewController.m ================================================ // // ViewController.m // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #import "ViewController.h" #import "AFNetworking.h" #import "CollectViewController.h" #import "URLEntity.h" #import "SVProgressHUD.h" @interface ViewController () @end @implementation ViewController { AFURLSessionManager *downloadManager; NSURLSessionDownloadTask *downloadTask; NSMutableArray *sources; int currentIndex; } -(void)viewDidAppear:(BOOL)animated { [self.navigationController setNavigationBarHidden:YES animated:YES]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. sources = [[NSMutableArray alloc]init]; [[UIApplication sharedApplication] setApplicationSupportsShakeToEdit:YES]; [self becomeFirstResponder]; if (!downloadManager) { NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[NSString stringWithFormat:@"shakefun_downloadidentifier_%d", 1]]; [configuration setAllowsCellularAccess:NO];//禁止使用蜂窝网络 downloadManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; [downloadManager.reachabilityManager startMonitoring]; } [self reloadSources]; if (sources.count == 0) { currentIndex = 0; } else { currentIndex = arc4random() % sources.count; } //[self.webViewBrowser setScalesPageToFit:YES]; self.automaticallyAdjustsScrollViewInsets = NO;//去除顶部20像素空白条 //self.webViewBrowser.opaque = NO; // CGRect rt = self.webViewBrowser.frame; // rt.size.width = self.view.frame.size.width; [self.webViewBrowser loadHTMLString:@"
Wellcom to ShakeFun! ^_!
" baseURL:nil]; self.webViewBrowser.backgroundColor = [UIColor lightGrayColor]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processNofitications:) name:@"shakefun_reload_urls" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processNofitications:) name:UIDeviceOrientationDidChangeNotification object:nil]; } -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:@"shakefun_reload_urls"]; [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:UIDeviceOrientationDidChangeNotification]; } -(void)reloadSources { [sources removeAllObjects]; NSArray* allurls = [URLEntity MR_findAll]; for (URLEntity *url in allurls) { [sources addObject:url.fullurl]; } } -(void)processNofitications:(NSNotification *)notification { NSLog(@"receive notification:%@", notification.name); if ([notification.name isEqualToString:@"shakefun_reload_urls"]) { [self reloadSources]; } else if ([notification.name isEqualToString:UIDeviceOrientationDidChangeNotification]) { [self buttonNextToggleWithIndex:currentIndex]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)buttonNextToggle:(id)sender { if (sources.count <= 0) { UIAlertView *view = [[UIAlertView alloc] initWithTitle:@"提示" message:@"请先采集数据->[Collect]" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [view show]; } else { currentIndex = arc4random() % sources.count; [self buttonNextToggleWithIndex:currentIndex]; } } - (IBAction)buttonCollectToggle:(id)sender { UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; CollectViewController* view = [sb instantiateViewControllerWithIdentifier:@"CollectViewController"]; [self.navigationController pushViewController:view animated:YES]; } - (void)buttonNextToggleWithIndex:(NSInteger)index { NSString* docPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *fileUrl = [sources objectAtIndex:index]; NSString* file = [NSString stringWithFormat:@"%@/%@", docPath, [fileUrl lastPathComponent]]; NSURL* url = [NSURL fileURLWithPath:file]; if ([[NSFileManager defaultManager] fileExistsAtPath:file]) { fileUrl = [url absoluteString]; //获取宽高 UIImage *img = [UIImage imageWithContentsOfFile:file]; //按webview窗口比例缩放 CGRect rt = self.webViewBrowser.frame; //取小的宽度 CGFloat w = rt.size.width > img.size.width ? img.size.width : rt.size.width; w = w - 20; CGFloat wh = w / img.size.width; NSString *content = [NSString stringWithFormat:@"
", img.size.width * wh, img.size.height * wh, fileUrl]; [self.webViewBrowser loadHTMLString:content baseURL:nil]; //self.webViewBrowser. } else { //显示正在更新 [self startDownload:index]; } } #pragma shake action - (void) motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { //检测到摇动 NSLog(@"Go:%s", __FUNCTION__); } - (void) motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event { //摇动取消 NSLog(@"Go:%s", __FUNCTION__); } - (void) motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { NSLog(@"Go:%s", __FUNCTION__); //摇动结束 if (event.subtype == UIEventSubtypeMotionShake) { //something happens [self buttonNextToggle:nil]; } } #pragma network -(void)startDownload:(NSInteger)index { static bool bFirst = YES; if (bFirst) { NSOperationQueue * operationQueue = downloadManager.operationQueue;//avoid retain cycle [downloadManager.reachabilityManager setReachabilityStatusChangeBlock :^ (AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusReachableViaWiFi: NSLog(@"DownloadManager AFNetworkReachabilityStatusReachableViaWiFi"); [operationQueue setSuspended:NO]; break ; case AFNetworkReachabilityStatusReachableViaWWAN: case AFNetworkReachabilityStatusNotReachable: default: //suspud [operationQueue setSuspended:YES]; NSLog(@"DownloadManager AFNetworkReachabilityStatusNotReachable"); break ; } }]; bFirst = NO; } //下载文件保存位置 NSString* docPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *fileUrl = [sources objectAtIndex:index]; NSString* file = [NSString stringWithFormat:@"%@/%@", docPath, [fileUrl lastPathComponent]]; NSLog(@"download file name is %@", file); if ([[NSFileManager defaultManager] fileExistsAtPath:file]) { return; } NSURL *downurl = [NSURL URLWithString:fileUrl]; NSURLRequest *request = [NSURLRequest requestWithURL:downurl]; //监控下载进度,调试用 NSProgress* progress = [[NSProgress alloc]init]; //创建下载任务 [SVProgressHUD showWithStatus:@"摇到一个大家伙,稍等片刻^_!"]; downloadTask = [downloadManager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { NSLog(@"destination:path=%@ targetPath:%@", file, targetPath); return [NSURL fileURLWithPath:file]; } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { NSLog(@"File downloaded to: %@ error:%@", filePath, error); if (!error) { downloadTask = nil; } [SVProgressHUD dismiss]; dispatch_async(dispatch_get_main_queue(), ^{ [self buttonNextToggleWithIndex:index]; }); }]; //开始下载 [downloadTask resume]; // Observe fractionCompleted using KVO [progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:nil]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) { NSProgress *progress = (NSProgress *)object; NSLog(@"download progress is %f", progress.fractionCompleted); if (progress.fractionCompleted >= 1.0f) { //下载完成后,移除观察者 [progress removeObserver:self forKeyPath:@"fractionCompleted"]; } } } @end @implementation NSString (TMNSStringExtensionMethods) - (NSArray *)componentsSeparatedFromString:(NSString *)fromString toString:(NSString *)toString { if (!fromString || !toString || fromString.length == 0 || toString.length == 0) { return nil; } NSMutableArray *subStringsArray = [[NSMutableArray alloc] init]; NSString *tempString = self; NSRange range = [tempString rangeOfString:fromString]; while (range.location != NSNotFound) { tempString = [tempString substringFromIndex:(range.location + range.length)]; range = [tempString rangeOfString:toString]; if (range.location != NSNotFound) { [subStringsArray addObject:[tempString substringToIndex:range.location]]; range = [tempString rangeOfString:fromString]; } else { break; } } return subStringsArray; } @end ================================================ FILE: shakefun/shakefun/main.m ================================================ // // main.m // shakefun // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: shakefun/shakefun/shakefun.xcdatamodeld/.xccurrentversion ================================================ _XCCurrentVersionName shakefun.xcdatamodel ================================================ FILE: shakefun/shakefun/shakefun.xcdatamodeld/shakefun.xcdatamodel/contents ================================================ ================================================ FILE: shakefun/shakefun.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 985474351B9FD35F00A892C8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474341B9FD35F00A892C8 /* main.m */; }; 985474381B9FD35F00A892C8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474371B9FD35F00A892C8 /* AppDelegate.m */; }; 9854743B1B9FD35F00A892C8 /* shakefun.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 985474391B9FD35F00A892C8 /* shakefun.xcdatamodeld */; }; 9854743E1B9FD35F00A892C8 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854743D1B9FD35F00A892C8 /* ViewController.m */; }; 985474411B9FD35F00A892C8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9854743F1B9FD35F00A892C8 /* Main.storyboard */; }; 985474431B9FD35F00A892C8 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 985474421B9FD35F00A892C8 /* Images.xcassets */; }; 985474461B9FD35F00A892C8 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 985474441B9FD35F00A892C8 /* LaunchScreen.xib */; }; 985474521B9FD35F00A892C8 /* shakefunTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474511B9FD35F00A892C8 /* shakefunTests.m */; }; 9854746F1B9FF45300A892C8 /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854745D1B9FF45300A892C8 /* AFHTTPRequestOperation.m */; }; 985474701B9FF45300A892C8 /* AFHTTPRequestOperationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854745F1B9FF45300A892C8 /* AFHTTPRequestOperationManager.m */; }; 985474711B9FF45300A892C8 /* AFHTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474611B9FF45300A892C8 /* AFHTTPSessionManager.m */; }; 985474721B9FF45300A892C8 /* AFNetworkReachabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474641B9FF45300A892C8 /* AFNetworkReachabilityManager.m */; }; 985474731B9FF45300A892C8 /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474661B9FF45300A892C8 /* AFSecurityPolicy.m */; }; 985474741B9FF45300A892C8 /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474681B9FF45300A892C8 /* AFURLConnectionOperation.m */; }; 985474751B9FF45300A892C8 /* AFURLRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854746A1B9FF45300A892C8 /* AFURLRequestSerialization.m */; }; 985474761B9FF45300A892C8 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854746C1B9FF45300A892C8 /* AFURLResponseSerialization.m */; }; 985474771B9FF45300A892C8 /* AFURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854746E1B9FF45300A892C8 /* AFURLSessionManager.m */; }; 9854747A1BA00B5600A892C8 /* CollectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474791BA00B5600A892C8 /* CollectViewController.m */; }; 9854747D1BA01B5100A892C8 /* URLEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854747C1BA01B5100A892C8 /* URLEntity.m */; }; 985474BA1BA01C7500A892C8 /* MagicalImportFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474821BA01C7500A892C8 /* MagicalImportFunctions.m */; }; 985474BB1BA01C7500A892C8 /* NSAttributeDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474841BA01C7500A892C8 /* NSAttributeDescription+MagicalDataImport.m */; }; 985474BC1BA01C7500A892C8 /* NSEntityDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474861BA01C7500A892C8 /* NSEntityDescription+MagicalDataImport.m */; }; 985474BD1BA01C7500A892C8 /* NSNumber+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474881BA01C7500A892C8 /* NSNumber+MagicalDataImport.m */; }; 985474BE1BA01C7500A892C8 /* NSObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854748A1BA01C7500A892C8 /* NSObject+MagicalDataImport.m */; }; 985474BF1BA01C7500A892C8 /* NSRelationshipDescription+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854748C1BA01C7500A892C8 /* NSRelationshipDescription+MagicalDataImport.m */; }; 985474C01BA01C7500A892C8 /* NSString+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854748E1BA01C7500A892C8 /* NSString+MagicalDataImport.m */; }; 985474C11BA01C7500A892C8 /* NSManagedObject+MagicalAggregation.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474911BA01C7500A892C8 /* NSManagedObject+MagicalAggregation.m */; }; 985474C21BA01C7500A892C8 /* NSManagedObject+MagicalDataImport.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474931BA01C7500A892C8 /* NSManagedObject+MagicalDataImport.m */; }; 985474C31BA01C7500A892C8 /* NSManagedObject+MagicalFinders.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474951BA01C7500A892C8 /* NSManagedObject+MagicalFinders.m */; }; 985474C41BA01C7500A892C8 /* NSManagedObject+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474971BA01C7500A892C8 /* NSManagedObject+MagicalRecord.m */; }; 985474C51BA01C7500A892C8 /* NSManagedObject+MagicalRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474991BA01C7500A892C8 /* NSManagedObject+MagicalRequests.m */; }; 985474C61BA01C7500A892C8 /* NSManagedObjectContext+MagicalObserving.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854749C1BA01C7500A892C8 /* NSManagedObjectContext+MagicalObserving.m */; }; 985474C71BA01C7500A892C8 /* NSManagedObjectContext+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 9854749E1BA01C7500A892C8 /* NSManagedObjectContext+MagicalRecord.m */; }; 985474C81BA01C7500A892C8 /* NSManagedObjectContext+MagicalSaves.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474A01BA01C7500A892C8 /* NSManagedObjectContext+MagicalSaves.m */; }; 985474C91BA01C7500A892C8 /* NSManagedObjectContext+MagicalThreading.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474A21BA01C7500A892C8 /* NSManagedObjectContext+MagicalThreading.m */; }; 985474CA1BA01C7500A892C8 /* NSManagedObjectModel+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474A41BA01C7500A892C8 /* NSManagedObjectModel+MagicalRecord.m */; }; 985474CB1BA01C7500A892C8 /* NSPersistentStore+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474A61BA01C7500A892C8 /* NSPersistentStore+MagicalRecord.m */; }; 985474CC1BA01C7500A892C8 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474A81BA01C7500A892C8 /* NSPersistentStoreCoordinator+MagicalRecord.m */; }; 985474CD1BA01C7500A892C8 /* MagicalRecord+Actions.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474AB1BA01C7500A892C8 /* MagicalRecord+Actions.m */; }; 985474CE1BA01C7500A892C8 /* MagicalRecord+ErrorHandling.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474AD1BA01C7500A892C8 /* MagicalRecord+ErrorHandling.m */; }; 985474CF1BA01C7500A892C8 /* MagicalRecord+iCloud.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474AF1BA01C7500A892C8 /* MagicalRecord+iCloud.m */; }; 985474D01BA01C7500A892C8 /* MagicalRecord+Options.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474B11BA01C7500A892C8 /* MagicalRecord+Options.m */; }; 985474D11BA01C7500A892C8 /* MagicalRecord+Setup.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474B31BA01C7500A892C8 /* MagicalRecord+Setup.m */; }; 985474D21BA01C7500A892C8 /* MagicalRecord+ShorthandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474B51BA01C7500A892C8 /* MagicalRecord+ShorthandSupport.m */; }; 985474D31BA01C7500A892C8 /* MagicalRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474B71BA01C7500A892C8 /* MagicalRecord.m */; }; 985474D51BA01CF500A892C8 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 985474D41BA01CF500A892C8 /* CoreData.framework */; }; 985474DB1BA169CE00A892C8 /* SVProgressHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 985474D81BA169CE00A892C8 /* SVProgressHUD.bundle */; }; 985474DC1BA169CE00A892C8 /* SVProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474DA1BA169CE00A892C8 /* SVProgressHUD.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 9854744C1B9FD35F00A892C8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 985474271B9FD35F00A892C8 /* Project object */; proxyType = 1; remoteGlobalIDString = 9854742E1B9FD35F00A892C8; remoteInfo = shakefun; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 9854742F1B9FD35F00A892C8 /* shakefun.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = shakefun.app; sourceTree = BUILT_PRODUCTS_DIR; }; 985474331B9FD35F00A892C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 985474341B9FD35F00A892C8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 985474361B9FD35F00A892C8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 985474371B9FD35F00A892C8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 9854743A1B9FD35F00A892C8 /* shakefun.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = shakefun.xcdatamodel; sourceTree = ""; }; 9854743C1B9FD35F00A892C8 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 9854743D1B9FD35F00A892C8 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 985474401B9FD35F00A892C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 985474421B9FD35F00A892C8 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 985474451B9FD35F00A892C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 9854744B1B9FD35F00A892C8 /* shakefunTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = shakefunTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 985474501B9FD35F00A892C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 985474511B9FD35F00A892C8 /* shakefunTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = shakefunTests.m; sourceTree = ""; }; 9854745C1B9FF45300A892C8 /* AFHTTPRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperation.h; sourceTree = ""; }; 9854745D1B9FF45300A892C8 /* AFHTTPRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPRequestOperation.m; sourceTree = ""; }; 9854745E1B9FF45300A892C8 /* AFHTTPRequestOperationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPRequestOperationManager.h; sourceTree = ""; }; 9854745F1B9FF45300A892C8 /* AFHTTPRequestOperationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPRequestOperationManager.m; sourceTree = ""; }; 985474601B9FF45300A892C8 /* AFHTTPSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFHTTPSessionManager.h; sourceTree = ""; }; 985474611B9FF45300A892C8 /* AFHTTPSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFHTTPSessionManager.m; sourceTree = ""; }; 985474621B9FF45300A892C8 /* AFNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworking.h; sourceTree = ""; }; 985474631B9FF45300A892C8 /* AFNetworkReachabilityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFNetworkReachabilityManager.h; sourceTree = ""; }; 985474641B9FF45300A892C8 /* AFNetworkReachabilityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFNetworkReachabilityManager.m; sourceTree = ""; }; 985474651B9FF45300A892C8 /* AFSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSecurityPolicy.h; sourceTree = ""; }; 985474661B9FF45300A892C8 /* AFSecurityPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSecurityPolicy.m; sourceTree = ""; }; 985474671B9FF45300A892C8 /* AFURLConnectionOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLConnectionOperation.h; sourceTree = ""; }; 985474681B9FF45300A892C8 /* AFURLConnectionOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLConnectionOperation.m; sourceTree = ""; }; 985474691B9FF45300A892C8 /* AFURLRequestSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLRequestSerialization.h; sourceTree = ""; }; 9854746A1B9FF45300A892C8 /* AFURLRequestSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLRequestSerialization.m; sourceTree = ""; }; 9854746B1B9FF45300A892C8 /* AFURLResponseSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLResponseSerialization.h; sourceTree = ""; }; 9854746C1B9FF45300A892C8 /* AFURLResponseSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLResponseSerialization.m; sourceTree = ""; }; 9854746D1B9FF45300A892C8 /* AFURLSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLSessionManager.h; sourceTree = ""; }; 9854746E1B9FF45300A892C8 /* AFURLSessionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLSessionManager.m; sourceTree = ""; }; 985474781BA00B4E00A892C8 /* CollectViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CollectViewController.h; sourceTree = ""; }; 985474791BA00B5600A892C8 /* CollectViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CollectViewController.m; sourceTree = ""; }; 9854747B1BA01B5100A892C8 /* URLEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLEntity.h; sourceTree = ""; }; 9854747C1BA01B5100A892C8 /* URLEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = URLEntity.m; sourceTree = ""; }; 985474811BA01C7500A892C8 /* MagicalImportFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalImportFunctions.h; sourceTree = ""; }; 985474821BA01C7500A892C8 /* MagicalImportFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalImportFunctions.m; sourceTree = ""; }; 985474831BA01C7500A892C8 /* NSAttributeDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributeDescription+MagicalDataImport.h"; sourceTree = ""; }; 985474841BA01C7500A892C8 /* NSAttributeDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributeDescription+MagicalDataImport.m"; sourceTree = ""; }; 985474851BA01C7500A892C8 /* NSEntityDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEntityDescription+MagicalDataImport.h"; sourceTree = ""; }; 985474861BA01C7500A892C8 /* NSEntityDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEntityDescription+MagicalDataImport.m"; sourceTree = ""; }; 985474871BA01C7500A892C8 /* NSNumber+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+MagicalDataImport.h"; sourceTree = ""; }; 985474881BA01C7500A892C8 /* NSNumber+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNumber+MagicalDataImport.m"; sourceTree = ""; }; 985474891BA01C7500A892C8 /* NSObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MagicalDataImport.h"; sourceTree = ""; }; 9854748A1BA01C7500A892C8 /* NSObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+MagicalDataImport.m"; sourceTree = ""; }; 9854748B1BA01C7500A892C8 /* NSRelationshipDescription+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSRelationshipDescription+MagicalDataImport.h"; sourceTree = ""; }; 9854748C1BA01C7500A892C8 /* NSRelationshipDescription+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSRelationshipDescription+MagicalDataImport.m"; sourceTree = ""; }; 9854748D1BA01C7500A892C8 /* NSString+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MagicalDataImport.h"; sourceTree = ""; }; 9854748E1BA01C7500A892C8 /* NSString+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MagicalDataImport.m"; sourceTree = ""; }; 985474901BA01C7500A892C8 /* NSManagedObject+MagicalAggregation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalAggregation.h"; sourceTree = ""; }; 985474911BA01C7500A892C8 /* NSManagedObject+MagicalAggregation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalAggregation.m"; sourceTree = ""; }; 985474921BA01C7500A892C8 /* NSManagedObject+MagicalDataImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalDataImport.h"; sourceTree = ""; }; 985474931BA01C7500A892C8 /* NSManagedObject+MagicalDataImport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalDataImport.m"; sourceTree = ""; }; 985474941BA01C7500A892C8 /* NSManagedObject+MagicalFinders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalFinders.h"; sourceTree = ""; }; 985474951BA01C7500A892C8 /* NSManagedObject+MagicalFinders.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalFinders.m"; sourceTree = ""; }; 985474961BA01C7500A892C8 /* NSManagedObject+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRecord.h"; sourceTree = ""; }; 985474971BA01C7500A892C8 /* NSManagedObject+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRecord.m"; sourceTree = ""; }; 985474981BA01C7500A892C8 /* NSManagedObject+MagicalRequests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObject+MagicalRequests.h"; sourceTree = ""; }; 985474991BA01C7500A892C8 /* NSManagedObject+MagicalRequests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObject+MagicalRequests.m"; sourceTree = ""; }; 9854749B1BA01C7500A892C8 /* NSManagedObjectContext+MagicalObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalObserving.h"; sourceTree = ""; }; 9854749C1BA01C7500A892C8 /* NSManagedObjectContext+MagicalObserving.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalObserving.m"; sourceTree = ""; }; 9854749D1BA01C7500A892C8 /* NSManagedObjectContext+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalRecord.h"; sourceTree = ""; }; 9854749E1BA01C7500A892C8 /* NSManagedObjectContext+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalRecord.m"; sourceTree = ""; }; 9854749F1BA01C7500A892C8 /* NSManagedObjectContext+MagicalSaves.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalSaves.h"; sourceTree = ""; }; 985474A01BA01C7500A892C8 /* NSManagedObjectContext+MagicalSaves.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalSaves.m"; sourceTree = ""; }; 985474A11BA01C7500A892C8 /* NSManagedObjectContext+MagicalThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectContext+MagicalThreading.h"; sourceTree = ""; }; 985474A21BA01C7500A892C8 /* NSManagedObjectContext+MagicalThreading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectContext+MagicalThreading.m"; sourceTree = ""; }; 985474A31BA01C7500A892C8 /* NSManagedObjectModel+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectModel+MagicalRecord.h"; sourceTree = ""; }; 985474A41BA01C7500A892C8 /* NSManagedObjectModel+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectModel+MagicalRecord.m"; sourceTree = ""; }; 985474A51BA01C7500A892C8 /* NSPersistentStore+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+MagicalRecord.h"; sourceTree = ""; }; 985474A61BA01C7500A892C8 /* NSPersistentStore+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStore+MagicalRecord.m"; sourceTree = ""; }; 985474A71BA01C7500A892C8 /* NSPersistentStoreCoordinator+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStoreCoordinator+MagicalRecord.h"; sourceTree = ""; }; 985474A81BA01C7500A892C8 /* NSPersistentStoreCoordinator+MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStoreCoordinator+MagicalRecord.m"; sourceTree = ""; }; 985474AA1BA01C7500A892C8 /* MagicalRecord+Actions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Actions.h"; sourceTree = ""; }; 985474AB1BA01C7500A892C8 /* MagicalRecord+Actions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Actions.m"; sourceTree = ""; }; 985474AC1BA01C7500A892C8 /* MagicalRecord+ErrorHandling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ErrorHandling.h"; sourceTree = ""; }; 985474AD1BA01C7500A892C8 /* MagicalRecord+ErrorHandling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ErrorHandling.m"; sourceTree = ""; }; 985474AE1BA01C7500A892C8 /* MagicalRecord+iCloud.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+iCloud.h"; sourceTree = ""; }; 985474AF1BA01C7500A892C8 /* MagicalRecord+iCloud.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+iCloud.m"; sourceTree = ""; }; 985474B01BA01C7500A892C8 /* MagicalRecord+Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Options.h"; sourceTree = ""; }; 985474B11BA01C7500A892C8 /* MagicalRecord+Options.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Options.m"; sourceTree = ""; }; 985474B21BA01C7500A892C8 /* MagicalRecord+Setup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+Setup.h"; sourceTree = ""; }; 985474B31BA01C7500A892C8 /* MagicalRecord+Setup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+Setup.m"; sourceTree = ""; }; 985474B41BA01C7500A892C8 /* MagicalRecord+ShorthandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MagicalRecord+ShorthandSupport.h"; sourceTree = ""; }; 985474B51BA01C7500A892C8 /* MagicalRecord+ShorthandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MagicalRecord+ShorthandSupport.m"; sourceTree = ""; }; 985474B61BA01C7500A892C8 /* MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecord.h; sourceTree = ""; }; 985474B71BA01C7500A892C8 /* MagicalRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MagicalRecord.m; sourceTree = ""; }; 985474B81BA01C7500A892C8 /* MagicalRecordShorthand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MagicalRecordShorthand.h; sourceTree = ""; }; 985474B91BA01C7500A892C8 /* CoreData+MagicalRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CoreData+MagicalRecord.h"; sourceTree = ""; }; 985474D41BA01CF500A892C8 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 985474D61BA0217100A892C8 /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PrefixHeader.pch; path = shakefun/PrefixHeader.pch; sourceTree = ""; }; 985474D81BA169CE00A892C8 /* SVProgressHUD.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SVProgressHUD.bundle; sourceTree = ""; }; 985474D91BA169CE00A892C8 /* SVProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVProgressHUD.h; sourceTree = ""; }; 985474DA1BA169CE00A892C8 /* SVProgressHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVProgressHUD.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 9854742C1B9FD35F00A892C8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 985474D51BA01CF500A892C8 /* CoreData.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 985474481B9FD35F00A892C8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 985474261B9FD35F00A892C8 = { isa = PBXGroup; children = ( 985474D61BA0217100A892C8 /* PrefixHeader.pch */, 985474D41BA01CF500A892C8 /* CoreData.framework */, 985474311B9FD35F00A892C8 /* shakefun */, 9854744E1B9FD35F00A892C8 /* shakefunTests */, 985474301B9FD35F00A892C8 /* Products */, ); sourceTree = ""; }; 985474301B9FD35F00A892C8 /* Products */ = { isa = PBXGroup; children = ( 9854742F1B9FD35F00A892C8 /* shakefun.app */, 9854744B1B9FD35F00A892C8 /* shakefunTests.xctest */, ); name = Products; sourceTree = ""; }; 985474311B9FD35F00A892C8 /* shakefun */ = { isa = PBXGroup; children = ( 985474D71BA169CE00A892C8 /* SVProgressHUD */, 9854747E1BA01C7500A892C8 /* MagicalRecord */, 9854745B1B9FF45300A892C8 /* AFNetworking */, 985474361B9FD35F00A892C8 /* AppDelegate.h */, 985474371B9FD35F00A892C8 /* AppDelegate.m */, 9854743C1B9FD35F00A892C8 /* ViewController.h */, 9854743D1B9FD35F00A892C8 /* ViewController.m */, 985474781BA00B4E00A892C8 /* CollectViewController.h */, 985474791BA00B5600A892C8 /* CollectViewController.m */, 9854743F1B9FD35F00A892C8 /* Main.storyboard */, 985474421B9FD35F00A892C8 /* Images.xcassets */, 985474441B9FD35F00A892C8 /* LaunchScreen.xib */, 985474391B9FD35F00A892C8 /* shakefun.xcdatamodeld */, 985474321B9FD35F00A892C8 /* Supporting Files */, 9854747B1BA01B5100A892C8 /* URLEntity.h */, 9854747C1BA01B5100A892C8 /* URLEntity.m */, ); path = shakefun; sourceTree = ""; }; 985474321B9FD35F00A892C8 /* Supporting Files */ = { isa = PBXGroup; children = ( 985474331B9FD35F00A892C8 /* Info.plist */, 985474341B9FD35F00A892C8 /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; 9854744E1B9FD35F00A892C8 /* shakefunTests */ = { isa = PBXGroup; children = ( 985474511B9FD35F00A892C8 /* shakefunTests.m */, 9854744F1B9FD35F00A892C8 /* Supporting Files */, ); path = shakefunTests; sourceTree = ""; }; 9854744F1B9FD35F00A892C8 /* Supporting Files */ = { isa = PBXGroup; children = ( 985474501B9FD35F00A892C8 /* Info.plist */, ); name = "Supporting Files"; sourceTree = ""; }; 9854745B1B9FF45300A892C8 /* AFNetworking */ = { isa = PBXGroup; children = ( 9854745C1B9FF45300A892C8 /* AFHTTPRequestOperation.h */, 9854745D1B9FF45300A892C8 /* AFHTTPRequestOperation.m */, 9854745E1B9FF45300A892C8 /* AFHTTPRequestOperationManager.h */, 9854745F1B9FF45300A892C8 /* AFHTTPRequestOperationManager.m */, 985474601B9FF45300A892C8 /* AFHTTPSessionManager.h */, 985474611B9FF45300A892C8 /* AFHTTPSessionManager.m */, 985474621B9FF45300A892C8 /* AFNetworking.h */, 985474631B9FF45300A892C8 /* AFNetworkReachabilityManager.h */, 985474641B9FF45300A892C8 /* AFNetworkReachabilityManager.m */, 985474651B9FF45300A892C8 /* AFSecurityPolicy.h */, 985474661B9FF45300A892C8 /* AFSecurityPolicy.m */, 985474671B9FF45300A892C8 /* AFURLConnectionOperation.h */, 985474681B9FF45300A892C8 /* AFURLConnectionOperation.m */, 985474691B9FF45300A892C8 /* AFURLRequestSerialization.h */, 9854746A1B9FF45300A892C8 /* AFURLRequestSerialization.m */, 9854746B1B9FF45300A892C8 /* AFURLResponseSerialization.h */, 9854746C1B9FF45300A892C8 /* AFURLResponseSerialization.m */, 9854746D1B9FF45300A892C8 /* AFURLSessionManager.h */, 9854746E1B9FF45300A892C8 /* AFURLSessionManager.m */, ); path = AFNetworking; sourceTree = ""; }; 9854747E1BA01C7500A892C8 /* MagicalRecord */ = { isa = PBXGroup; children = ( 9854747F1BA01C7500A892C8 /* Categories */, 985474A91BA01C7500A892C8 /* Core */, 985474B91BA01C7500A892C8 /* CoreData+MagicalRecord.h */, ); path = MagicalRecord; sourceTree = ""; }; 9854747F1BA01C7500A892C8 /* Categories */ = { isa = PBXGroup; children = ( 985474801BA01C7500A892C8 /* DataImport */, 9854748F1BA01C7500A892C8 /* NSManagedObject */, 9854749A1BA01C7500A892C8 /* NSManagedObjectContext */, 985474A31BA01C7500A892C8 /* NSManagedObjectModel+MagicalRecord.h */, 985474A41BA01C7500A892C8 /* NSManagedObjectModel+MagicalRecord.m */, 985474A51BA01C7500A892C8 /* NSPersistentStore+MagicalRecord.h */, 985474A61BA01C7500A892C8 /* NSPersistentStore+MagicalRecord.m */, 985474A71BA01C7500A892C8 /* NSPersistentStoreCoordinator+MagicalRecord.h */, 985474A81BA01C7500A892C8 /* NSPersistentStoreCoordinator+MagicalRecord.m */, ); path = Categories; sourceTree = ""; }; 985474801BA01C7500A892C8 /* DataImport */ = { isa = PBXGroup; children = ( 985474811BA01C7500A892C8 /* MagicalImportFunctions.h */, 985474821BA01C7500A892C8 /* MagicalImportFunctions.m */, 985474831BA01C7500A892C8 /* NSAttributeDescription+MagicalDataImport.h */, 985474841BA01C7500A892C8 /* NSAttributeDescription+MagicalDataImport.m */, 985474851BA01C7500A892C8 /* NSEntityDescription+MagicalDataImport.h */, 985474861BA01C7500A892C8 /* NSEntityDescription+MagicalDataImport.m */, 985474871BA01C7500A892C8 /* NSNumber+MagicalDataImport.h */, 985474881BA01C7500A892C8 /* NSNumber+MagicalDataImport.m */, 985474891BA01C7500A892C8 /* NSObject+MagicalDataImport.h */, 9854748A1BA01C7500A892C8 /* NSObject+MagicalDataImport.m */, 9854748B1BA01C7500A892C8 /* NSRelationshipDescription+MagicalDataImport.h */, 9854748C1BA01C7500A892C8 /* NSRelationshipDescription+MagicalDataImport.m */, 9854748D1BA01C7500A892C8 /* NSString+MagicalDataImport.h */, 9854748E1BA01C7500A892C8 /* NSString+MagicalDataImport.m */, ); path = DataImport; sourceTree = ""; }; 9854748F1BA01C7500A892C8 /* NSManagedObject */ = { isa = PBXGroup; children = ( 985474901BA01C7500A892C8 /* NSManagedObject+MagicalAggregation.h */, 985474911BA01C7500A892C8 /* NSManagedObject+MagicalAggregation.m */, 985474921BA01C7500A892C8 /* NSManagedObject+MagicalDataImport.h */, 985474931BA01C7500A892C8 /* NSManagedObject+MagicalDataImport.m */, 985474941BA01C7500A892C8 /* NSManagedObject+MagicalFinders.h */, 985474951BA01C7500A892C8 /* NSManagedObject+MagicalFinders.m */, 985474961BA01C7500A892C8 /* NSManagedObject+MagicalRecord.h */, 985474971BA01C7500A892C8 /* NSManagedObject+MagicalRecord.m */, 985474981BA01C7500A892C8 /* NSManagedObject+MagicalRequests.h */, 985474991BA01C7500A892C8 /* NSManagedObject+MagicalRequests.m */, ); path = NSManagedObject; sourceTree = ""; }; 9854749A1BA01C7500A892C8 /* NSManagedObjectContext */ = { isa = PBXGroup; children = ( 9854749B1BA01C7500A892C8 /* NSManagedObjectContext+MagicalObserving.h */, 9854749C1BA01C7500A892C8 /* NSManagedObjectContext+MagicalObserving.m */, 9854749D1BA01C7500A892C8 /* NSManagedObjectContext+MagicalRecord.h */, 9854749E1BA01C7500A892C8 /* NSManagedObjectContext+MagicalRecord.m */, 9854749F1BA01C7500A892C8 /* NSManagedObjectContext+MagicalSaves.h */, 985474A01BA01C7500A892C8 /* NSManagedObjectContext+MagicalSaves.m */, 985474A11BA01C7500A892C8 /* NSManagedObjectContext+MagicalThreading.h */, 985474A21BA01C7500A892C8 /* NSManagedObjectContext+MagicalThreading.m */, ); path = NSManagedObjectContext; sourceTree = ""; }; 985474A91BA01C7500A892C8 /* Core */ = { isa = PBXGroup; children = ( 985474AA1BA01C7500A892C8 /* MagicalRecord+Actions.h */, 985474AB1BA01C7500A892C8 /* MagicalRecord+Actions.m */, 985474AC1BA01C7500A892C8 /* MagicalRecord+ErrorHandling.h */, 985474AD1BA01C7500A892C8 /* MagicalRecord+ErrorHandling.m */, 985474AE1BA01C7500A892C8 /* MagicalRecord+iCloud.h */, 985474AF1BA01C7500A892C8 /* MagicalRecord+iCloud.m */, 985474B01BA01C7500A892C8 /* MagicalRecord+Options.h */, 985474B11BA01C7500A892C8 /* MagicalRecord+Options.m */, 985474B21BA01C7500A892C8 /* MagicalRecord+Setup.h */, 985474B31BA01C7500A892C8 /* MagicalRecord+Setup.m */, 985474B41BA01C7500A892C8 /* MagicalRecord+ShorthandSupport.h */, 985474B51BA01C7500A892C8 /* MagicalRecord+ShorthandSupport.m */, 985474B61BA01C7500A892C8 /* MagicalRecord.h */, 985474B71BA01C7500A892C8 /* MagicalRecord.m */, 985474B81BA01C7500A892C8 /* MagicalRecordShorthand.h */, ); path = Core; sourceTree = ""; }; 985474D71BA169CE00A892C8 /* SVProgressHUD */ = { isa = PBXGroup; children = ( 985474D81BA169CE00A892C8 /* SVProgressHUD.bundle */, 985474D91BA169CE00A892C8 /* SVProgressHUD.h */, 985474DA1BA169CE00A892C8 /* SVProgressHUD.m */, ); path = SVProgressHUD; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 9854742E1B9FD35F00A892C8 /* shakefun */ = { isa = PBXNativeTarget; buildConfigurationList = 985474551B9FD35F00A892C8 /* Build configuration list for PBXNativeTarget "shakefun" */; buildPhases = ( 9854742B1B9FD35F00A892C8 /* Sources */, 9854742C1B9FD35F00A892C8 /* Frameworks */, 9854742D1B9FD35F00A892C8 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = shakefun; productName = shakefun; productReference = 9854742F1B9FD35F00A892C8 /* shakefun.app */; productType = "com.apple.product-type.application"; }; 9854744A1B9FD35F00A892C8 /* shakefunTests */ = { isa = PBXNativeTarget; buildConfigurationList = 985474581B9FD35F00A892C8 /* Build configuration list for PBXNativeTarget "shakefunTests" */; buildPhases = ( 985474471B9FD35F00A892C8 /* Sources */, 985474481B9FD35F00A892C8 /* Frameworks */, 985474491B9FD35F00A892C8 /* Resources */, ); buildRules = ( ); dependencies = ( 9854744D1B9FD35F00A892C8 /* PBXTargetDependency */, ); name = shakefunTests; productName = shakefunTests; productReference = 9854744B1B9FD35F00A892C8 /* shakefunTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 985474271B9FD35F00A892C8 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0640; ORGANIZATIONNAME = zhangmin; TargetAttributes = { 9854742E1B9FD35F00A892C8 = { CreatedOnToolsVersion = 6.4; }; 9854744A1B9FD35F00A892C8 = { CreatedOnToolsVersion = 6.4; TestTargetID = 9854742E1B9FD35F00A892C8; }; }; }; buildConfigurationList = 9854742A1B9FD35F00A892C8 /* Build configuration list for PBXProject "shakefun" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 985474261B9FD35F00A892C8; productRefGroup = 985474301B9FD35F00A892C8 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 9854742E1B9FD35F00A892C8 /* shakefun */, 9854744A1B9FD35F00A892C8 /* shakefunTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 9854742D1B9FD35F00A892C8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 985474411B9FD35F00A892C8 /* Main.storyboard in Resources */, 985474461B9FD35F00A892C8 /* LaunchScreen.xib in Resources */, 985474431B9FD35F00A892C8 /* Images.xcassets in Resources */, 985474DB1BA169CE00A892C8 /* SVProgressHUD.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 985474491B9FD35F00A892C8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 9854742B1B9FD35F00A892C8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 985474C71BA01C7500A892C8 /* NSManagedObjectContext+MagicalRecord.m in Sources */, 985474381B9FD35F00A892C8 /* AppDelegate.m in Sources */, 985474731B9FF45300A892C8 /* AFSecurityPolicy.m in Sources */, 985474D11BA01C7500A892C8 /* MagicalRecord+Setup.m in Sources */, 985474C81BA01C7500A892C8 /* NSManagedObjectContext+MagicalSaves.m in Sources */, 9854747D1BA01B5100A892C8 /* URLEntity.m in Sources */, 985474C31BA01C7500A892C8 /* NSManagedObject+MagicalFinders.m in Sources */, 985474BD1BA01C7500A892C8 /* NSNumber+MagicalDataImport.m in Sources */, 9854743B1B9FD35F00A892C8 /* shakefun.xcdatamodeld in Sources */, 985474701B9FF45300A892C8 /* AFHTTPRequestOperationManager.m in Sources */, 985474C41BA01C7500A892C8 /* NSManagedObject+MagicalRecord.m in Sources */, 985474BA1BA01C7500A892C8 /* MagicalImportFunctions.m in Sources */, 985474CB1BA01C7500A892C8 /* NSPersistentStore+MagicalRecord.m in Sources */, 985474C01BA01C7500A892C8 /* NSString+MagicalDataImport.m in Sources */, 985474D21BA01C7500A892C8 /* MagicalRecord+ShorthandSupport.m in Sources */, 985474BB1BA01C7500A892C8 /* NSAttributeDescription+MagicalDataImport.m in Sources */, 985474C21BA01C7500A892C8 /* NSManagedObject+MagicalDataImport.m in Sources */, 985474DC1BA169CE00A892C8 /* SVProgressHUD.m in Sources */, 985474741B9FF45300A892C8 /* AFURLConnectionOperation.m in Sources */, 985474BE1BA01C7500A892C8 /* NSObject+MagicalDataImport.m in Sources */, 9854746F1B9FF45300A892C8 /* AFHTTPRequestOperation.m in Sources */, 9854743E1B9FD35F00A892C8 /* ViewController.m in Sources */, 985474BF1BA01C7500A892C8 /* NSRelationshipDescription+MagicalDataImport.m in Sources */, 985474BC1BA01C7500A892C8 /* NSEntityDescription+MagicalDataImport.m in Sources */, 985474751B9FF45300A892C8 /* AFURLRequestSerialization.m in Sources */, 985474711B9FF45300A892C8 /* AFHTTPSessionManager.m in Sources */, 985474721B9FF45300A892C8 /* AFNetworkReachabilityManager.m in Sources */, 985474CD1BA01C7500A892C8 /* MagicalRecord+Actions.m in Sources */, 985474761B9FF45300A892C8 /* AFURLResponseSerialization.m in Sources */, 985474C11BA01C7500A892C8 /* NSManagedObject+MagicalAggregation.m in Sources */, 9854747A1BA00B5600A892C8 /* CollectViewController.m in Sources */, 985474771B9FF45300A892C8 /* AFURLSessionManager.m in Sources */, 985474C51BA01C7500A892C8 /* NSManagedObject+MagicalRequests.m in Sources */, 985474C91BA01C7500A892C8 /* NSManagedObjectContext+MagicalThreading.m in Sources */, 985474CF1BA01C7500A892C8 /* MagicalRecord+iCloud.m in Sources */, 985474CC1BA01C7500A892C8 /* NSPersistentStoreCoordinator+MagicalRecord.m in Sources */, 985474CA1BA01C7500A892C8 /* NSManagedObjectModel+MagicalRecord.m in Sources */, 985474D01BA01C7500A892C8 /* MagicalRecord+Options.m in Sources */, 985474D31BA01C7500A892C8 /* MagicalRecord.m in Sources */, 985474C61BA01C7500A892C8 /* NSManagedObjectContext+MagicalObserving.m in Sources */, 985474351B9FD35F00A892C8 /* main.m in Sources */, 985474CE1BA01C7500A892C8 /* MagicalRecord+ErrorHandling.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 985474471B9FD35F00A892C8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 985474521B9FD35F00A892C8 /* shakefunTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 9854744D1B9FD35F00A892C8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 9854742E1B9FD35F00A892C8 /* shakefun */; targetProxy = 9854744C1B9FD35F00A892C8 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ 9854743F1B9FD35F00A892C8 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 985474401B9FD35F00A892C8 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 985474441B9FD35F00A892C8 /* LaunchScreen.xib */ = { isa = PBXVariantGroup; children = ( 985474451B9FD35F00A892C8 /* Base */, ); name = LaunchScreen.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 985474531B9FD35F00A892C8 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IBC_FLATTEN_NIBS = YES; IBSC_FLATTEN_NIBS = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.4; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; }; 985474541B9FD35F00A892C8 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IBC_FLATTEN_NIBS = YES; IBSC_FLATTEN_NIBS = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.4; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; name = Release; }; 985474561B9FD35F00A892C8 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; GCC_PREFIX_HEADER = shakefun/PrefixHeader.pch; IBC_FLATTEN_NIBS = YES; IBSC_FLATTEN_NIBS = YES; INFOPLIST_FILE = shakefun/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 985474571B9FD35F00A892C8 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; GCC_PREFIX_HEADER = shakefun/PrefixHeader.pch; IBC_FLATTEN_NIBS = YES; IBSC_FLATTEN_NIBS = YES; INFOPLIST_FILE = shakefun/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; 985474591B9FD35F00A892C8 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); INFOPLIST_FILE = shakefunTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/shakefun.app/shakefun"; }; name = Debug; }; 9854745A1B9FD35F00A892C8 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); INFOPLIST_FILE = shakefunTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/shakefun.app/shakefun"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 9854742A1B9FD35F00A892C8 /* Build configuration list for PBXProject "shakefun" */ = { isa = XCConfigurationList; buildConfigurations = ( 985474531B9FD35F00A892C8 /* Debug */, 985474541B9FD35F00A892C8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 985474551B9FD35F00A892C8 /* Build configuration list for PBXNativeTarget "shakefun" */ = { isa = XCConfigurationList; buildConfigurations = ( 985474561B9FD35F00A892C8 /* Debug */, 985474571B9FD35F00A892C8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 985474581B9FD35F00A892C8 /* Build configuration list for PBXNativeTarget "shakefunTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 985474591B9FD35F00A892C8 /* Debug */, 9854745A1B9FD35F00A892C8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ 985474391B9FD35F00A892C8 /* shakefun.xcdatamodeld */ = { isa = XCVersionGroup; children = ( 9854743A1B9FD35F00A892C8 /* shakefun.xcdatamodel */, ); currentVersion = 9854743A1B9FD35F00A892C8 /* shakefun.xcdatamodel */; path = shakefun.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; }; /* End XCVersionGroup section */ }; rootObject = 985474271B9FD35F00A892C8 /* Project object */; } ================================================ FILE: shakefun/shakefun.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: shakefun/shakefunTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier zm.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: shakefun/shakefunTests/shakefunTests.m ================================================ // // shakefunTests.m // shakefunTests // // Created by zm on 15/9/9. // Copyright (c) 2015年 zm. All rights reserved. // #import #import @interface shakefunTests : XCTestCase @end @implementation shakefunTests - (void)setUp { [super setUp]; // Put setup code here. This method is called before the invocation of each test method in the class. } - (void)tearDown { // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; } - (void)testExample { // This is an example of a functional test case. XCTAssert(YES, @"Pass"); } - (void)testPerformanceExample { // This is an example of a performance test case. [self measureBlock:^{ // Put the code you want to measure the time of here. }]; } @end ================================================ FILE: zmconfuse.sh ================================================ #!/bin/bash echo "#########################################" echo "File Name:zmconfuse.sh" echo "Copyright (c) 2015 ZMConfuse" echo "Email:zm53373581@163.com" echo "QQGroup:175070221" echo "Create:2015.10.14" echo "#######################################" echo "用户修改区-开始" #要替换的源代码所在的根目录,该脚本文件与根目录处于同级文件夹 ROOTFOLDER="shakefun" #要排除的文件夹,例如demo中用到的第三方库AFNetworking等 EXCLUDE_DIR="--exclude-dir=SVProgressHUD --exclude-dir=AFNetworking --exclude-dir=MagicalRecord --exclude-dir=Images.xcassets" echo "用户修改区-结束" #自定义的保留关键字,相当与白名单,添加到该文件中,一行一个,加入该文件的关键字将不被混淆;如工程中自定义的文件夹名称 RESCUSTOM="resCustom.txt" #保留关键字文件不可删除 RESERVEDKEYWORDS="./reskeys.txt" #最终的保留关键字=保留关键字+文件名 RESKEYSALL="./reskeysall.txt" #提取的所有关键字 SOURCECODEKEYWORDS="./srckeys.txt" #过滤后,最终要替换的关键字,混淆结束后,不删除,用于bug分析 REPLACEKEYWORDS="./replacekeys.txt" #删除已经存在的临时文件 rm -f $SOURCECODEKEYWORDS rm -f $REPLACEKEYWORDS rm -f $RESKEYSALL rm -f temp.res #提取文件名列表 rm -f f.list find $ROOTFOLDER -type f | sed "/\/\./d" >f.list #根据要排除的文件目录,将文件列表分离 #Exclude=$(echo $EXCLUDE_DIR | sed "s/--exclude-dir\=//g" |sed "s/ $//g" | sed "s/[*.]//g" | sed "s/ /\\\|/g") Exclude=$(echo $EXCLUDE_DIR | sed "s/--exclude-dir\=//g" |sed "s/ $//g" | sed "s/ /\\\|/g") #保留文件列表 rm -f f_res.list cat f.list | grep "$Exclude" >f_res.list #混淆文件列表 rm -f f_rep.list cat f.list | grep -v "$Exclude" >f_rep.list rm -f f.list #提取文件名 rm -f filter_file.txt cat f_rep.list | awk -F/ '{print $NF;}'| awk -F. '{print $1;}' | sed "/^$/d" | sort | uniq >filter_file.txt #从源代码目录中提取要过滤的函数关键字 rm -f filter_fun.txt grep -h -r -I "^[-+]" $ROOTFOLDER $EXCLUDE_DIR --include '*.[mh]' |sed "s/[+-]//g"|sed "s/[();,: *\^\/\{]/ /g"|sed "s/[ ]*filter_fun.txt #从源代码目录中提取要过滤的属性关键字 rm -f filter_property.txt grep -r -h -I ^@property $ROOTFOLDER $EXCLUDE_DIR --include '*.[mh]' | sed "s/(.*)/ /g" | sed "s/<.*>//g" |sed "s/[,*;]/ /g" | sed "s/IBOutlet/ /g" |awk '{split($0,s," ");print s[3];}'|sed "/^$/d" | sort |uniq >filter_property.txt #从源代码目录中提取要过滤的类关键字 rm -f filter_class.txt grep -h -r -I "^@interface" $ROOTFOLDER $EXCLUDE_DIR --include '*.[mh]' | sed "s/[:(]/ /" |awk '{split($0,s," ");print s[2];}'|sort|uniq >filter_class.txt #从源代码目录中提取要过滤的协议关键字 grep -h -r -I "^@protocol" $ROOTFOLDER $EXCLUDE_DIR --include '*.[mh]'| sed "s/[\<,;].*$//g"|awk '{print $2;}' | sort | uniq >>filter_class.txt #合并要过滤的关键字,并重新排序过滤 rm -f $SOURCECODEKEYWORDS cat filter_fun.txt filter_property.txt filter_class.txt filter_file.txt |sed "/^$/d" | sort | uniq >$SOURCECODEKEYWORDS rm -f filter_fun.txt rm -f filter_class.txt rm -f filter_file.txt #自动获取保留字,工程名等 rm -f temp.res cat `cat f_rep.list | grep project.pbxproj` | grep -w productName | sed "s/;//g"|awk '{print $NF;}'>temp.res #提取要保留的文件名 cat f_res.list | awk -F/ '{print $NF;}'| awk -F. '{print $1;}' | sed "/^$/d" | sort | uniq >>temp.res rm -f f_res.list #合并自定义保留字 #判断自定义保留字文件是否存在,不存在即创建一个空的 if [ ! -f "$RESCUSTOM" ]; then touch "$RESCUSTOM" fi cat $RESERVEDKEYWORDS $RESCUSTOM temp.res | sort |uniq >$RESKEYSALL rm -f temp.res #过滤保留字,将需要混淆的关键字加密后写入文件 rm -f $REPLACEKEYWORDS cat $SOURCECODEKEYWORDS | while read line do if grep $line $RESKEYSALL then echo filter1: $line else #使用md5对关键字进行加密 md5 -r -s $line | sed s/\"//g >> $REPLACEKEYWORDS fi done rm -f $SOURCECODEKEYWORDS #开始混淆,替换源代码中的关键字为加密后的,防止开头为数字的情况 cat $REPLACEKEYWORDS | while read line do var1=$(echo "$line"|awk '{print "z"$1"m"}') var2=$(echo "$line"|awk '{print $2}') rm -f rep.tmp if grep -r -n -I -w "[_]\{0,1\}$var2" $ROOTFOLDER $EXCLUDE_DIR --include="*.[mhc]" --include="*.mm" --include="*.pch" --include="*.storyboard" --include="*.xib" --include="*.nib" --include="contents" --include="*.pbxproj" >rep.tmp then cat rep.tmp | while read -r l do #获取文件路径 v1=$(echo "$l"|cut -d: -f 1 ) #获取行号 v2=$(echo "$l"|cut -d: -f 2 ) #获取指定行数据 v3=$(sed -n "$v2"p "$v1") ##sed自带文件文本替换功能,不符合我们的期望,故放弃使用;有无适合的脚本命令,还希望脚本高手予以指点~ #sed -i '' ''"$v2"'s/'"$var2"'/'"$var1"'/g' $v1 #特殊字符转义替换,echo中 输出的变量 一定要加双引号!!! v4=$(echo "$v3" | awk '{gsub(/"/, "\\\"", $0);gsub(//, "\\\>", $0);gsub(/\*/, "\\\*", $0);gsub(/\//, "\\\/", $0);gsub(/\[/, "\\\[", $0);gsub(/\]/, "\\\]", $0);gsub(/\{/, "\\\{", $0);gsub(/\}/, "\\\}", $0);gsub(/\&/, "\\\\\&", $0); print $0;}') #单词替换 var3=$(./zmreplacewords.run "$v4" "$var2" "$var1") #整行替换 sed -i '' "$v2"'s/.*/'"$var3"'/g' "$v1" echo "step2:$l" done else echo "step2:do not find:$var2" fi done rm -f tmp.txt #过滤保留字,用于属性设置函数混淆,将需要混淆的关键字加密后写入文件 rm -f repProperty.txt cat filter_property.txt | while read line do if grep $line $RESKEYSALL then echo filter1: $line else md5 -r -s $line | sed s/\"//g >> repProperty.txt fi done rm -f filter_property.txt #开始混淆,替换属性前带下划线的地方 cat repProperty.txt | while read line do ar=(`echo "$line"|cut -f 1-2 -d " "`) lastFind=`echo _${ar[1]}` lastRep=`echo _z${ar[0]}m` rm -f rep.tmp if grep -r -n -I -w "$lastFind" $ROOTFOLDER $EXCLUDE_DIR --include="*.[mhc]" --include="*.mm" --include="*.storyboard" --include="*.xib" >rep.tmp then cat rep.tmp | while read l do v1=$(echo "$l"|cut -d: -f 1 ) v2=$(echo "$l"|cut -d: -f 2 ) sed -i '' ''"$v2"'s/'"$lastFind"'/'"$lastRep"'/g' $v1 echo "step3:"$l done else echo "step3:do not find:"$lastFind fi done rm -f rep.tmp #开始混淆,替换属性设置函数 cat repProperty.txt | while read line do ar=(`echo "$line"|cut -f 1-2 -d " "`) first=`echo ${ar[1]}|cut -c -1| sed "y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/"` second=`echo ${ar[1]}|cut -c 2-` lastFind=`echo set$first$second` lastRep=`echo setZ${ar[0]}m` rm -f rep.tmp if grep -r -n -I -w "$lastFind" $ROOTFOLDER $EXCLUDE_DIR --include="*.[mhc]" --include="*.mm" --include="*.storyboard" --include="*.xib" >rep.tmp then cat rep.tmp | while read l do v1=$(echo "$l"|cut -d: -f 1 ) v2=$(echo "$l"|cut -d: -f 2 ) sed -i '' ''"$v2"'s/'"$lastFind"'/'"$lastRep"'/g' $v1 echo "step3:"$l done else echo "step3:do not find:"$lastFind fi done rm -f rep.tmp rm -f repProperty.txt cat f_rep.list | while read line do echo "old name:"$line #获取文件名,带后缀 v1=$(echo "$line" | sed "s/\// /g" | awk '{print $NF}') echo "v1="$v1 #获取文件名,不带后缀 v2=$(echo $v1 | sed "s/\./ /g" | awk '{print $1}') echo "v2="$v2 if grep -w $v2 $RESKEYSALL then echo "find." else #获取后缀 v3=$(echo $v1 | sed "s/\./ /g" | awk '{print "."$2}') echo "v3="$v3 #对不带后缀的文件名加密 v4=$(md5 -q -s "$v2" | sed "s/.*/z&m/g") echo "v4="$v4 #获取路径 v5=$(echo "$line" | sed "s/"$v1"//g") echo "v5="$v5 #修改文件名 mv $line $v5$v4$v3 echo "new name:"$v5$v4$v3 fi done rm -f f_rep.list rm -f $RESKEYSALL exit ================================================ FILE: zmreplacewords/zmreplacewords/main.c ================================================ // // main.c // zmreplacewords // // Created by zm on 16/2/15. // Copyright © 2016年 zm. All rights reserved. // #include #include #include char *g_dictWords = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; //单词替换 char *zmWordsReplace(char *src, char *old, char *new); //字符串替换 char *zmStringReplace(char *src, char *old, char *new); int main(int argc, const char * argv[]) { // //打印参数信息 // for (int i = 0; i < argc; ++i) { // printf("%d:%s\n", i + 1, argv[i]); // } if (argc != 4) { printf("Arguments error.For example:./zmreplacewords \"This is test cases.\" is are\n"); return 0; } #if 1 char *rawString = (char *)argv[1]; char *old = (char *)argv[2]; char *new = (char *)argv[3]; #else char *rawString = " 9854747A1BA00B5600A892C8 /* CollectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 985474791BA00B5600A892C8 /* CollectViewController.m */; };"; char *old = "CollectViewController"; char *new = "aaaaaaaaaaaa"; #endif //单词替换 char *newString = zmWordsReplace(rawString, old, new); char *retString = newString; // //特殊字符转义 // //char *specialChar = "<>/*"; // char *specialChar = ""; // char spcialCharArrayOld[2] = {""}; // char spcialCharArrayNew[3] = {"\\*"}; // for (int j = 0; j < strlen(specialChar); ++j) { // spcialCharArrayOld[0] = specialChar[j]; // spcialCharArrayNew[1] = specialChar[j]; // retString = zmStringReplace(newString, spcialCharArrayOld, spcialCharArrayNew); // if (retString != newString) { // if (olds != newString) { // free(newString); // } // newString = retString; // } // } printf("%s\n", retString); if (rawString != retString) { free(retString); } return 0; } //单词替换,如:This is a good news.==>is -> are ==> This are a good news. char *zmWordsReplace(char *src, char *old, char *new) { int iReplaceCount = 0; //char *olds = src; char pre = '\0'; char aft = '\0'; char *pFindChar = NULL; char *pStart = src; char *newString = src; char *newStringTmp = NULL; //step :首先统计要替换的单词数量 char *pFindWord = strstr(pStart, old); while (pFindWord != NULL) { //取出前后字符 if (pFindWord == pStart) { pre = '\0'; } else { pre = *(pFindWord - 1); } aft = *(pFindWord + strlen(old)); pFindChar = strchr(g_dictWords, pre); if (!pFindChar || pre == '\0') { pFindChar = strchr(g_dictWords, aft); if (!pFindChar || aft == '\0') { //printf("i am here: pPre=%c find=%s pAft=%c\n", pre, find, aft); iReplaceCount++; } } //查找位置向前移动 pFindWord = strstr(pFindWord + strlen(old), old); pre = '\0'; aft = '\0'; } if (iReplaceCount > 0) { //step :根据统计大小,为新的字符串申请空间 unsigned long iNewLenght = strlen(src) + (strlen(new) - strlen(old)) * iReplaceCount; //printf("iReplaceCount is %d totol lenth = %lu\n", iReplaceCount, iNewLenght); newString = (char *)calloc(iNewLenght, 1); newStringTmp = newString; //step :根据原始字符串,填充新的字符串 pStart = src; pFindWord = strstr(pStart, old); while (pFindWord != NULL) { //取出前后字符 if (pFindWord == pStart) { pre = '\0'; } else { pre = *(pFindWord - 1); } aft = *(pFindWord + strlen(old)); pFindChar = strchr(g_dictWords, pre); if (!pFindChar || pre == '\0') { pFindChar = strchr(g_dictWords, aft); if (!pFindChar || aft == '\0') { //拷贝找到的字符串之前的字符串 strncpy(newStringTmp, pStart, pFindWord - pStart); //向新自负串中追加替换后的字符串 strcat(newStringTmp, new); //printf("i am here: pPre=%c find=%s pAft=%c newString=%s\n", pre, pFindWord, aft, newStringTmp); //开始位置向前移动 pStart = pFindWord + strlen(old); newStringTmp = newString + strlen(newString); } } //查找位置向前移动 pFindWord = strstr(pFindWord + strlen(old), old); pre = '\0'; aft = '\0'; } //step :追加最后一部分字符串 if (pStart != src) { strcat(newString, pStart); } //printf("last string is :%s\n", newString); //free(newString); } return newString; } //字符串替换,如:This is a good news.==>is -> are ==> Thare are a good news. char *zmStringReplace(char *src, char *old, char *new) { int iReplaceCount = 0; char *pStart = src; char *newString = src; char *newStringTmp = NULL; //step :首先统计要替换的字符串数量 char *pFindWord = strstr(pStart, old); while (pFindWord != NULL) { iReplaceCount++; //查找位置向前移动 pFindWord = strstr(pFindWord + strlen(old), old); } if (iReplaceCount > 0) { //step :根据统计大小,为新的字符串申请空间 unsigned long iNewLenght = strlen(src) + (strlen(new) - strlen(old)) * iReplaceCount; //printf("iReplaceCount is %d totol lenth = %lu\n", iReplaceCount, iNewLenght); newString = (char *)calloc(iNewLenght, 1); newStringTmp = newString; //step :根据原始字符串,填充新的字符串 pStart = src; pFindWord = strstr(pStart, old); while (pFindWord != NULL) { //拷贝找到的字符串之前的字符串 strncpy(newStringTmp, pStart, pFindWord - pStart); //向新自负串中追加替换后的字符串 strcat(newStringTmp, new); //printf("i am here: pPre=%c find=%s pAft=%c newString=%s\n", pre, pFindWord, aft, newStringTmp); //开始位置向前移动 pStart = pFindWord + strlen(old); newStringTmp = newString + strlen(newString); //查找位置向前移动 pFindWord = strstr(pFindWord + strlen(old), old); } //step :追加最后一部分字符串 if (pStart != src) { strcat(newString, pStart); } //printf("last string is :%s\n", newString); //free(newString); } return newString; } ================================================ FILE: zmreplacewords/zmreplacewords.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 985347B81C71C33800AC6ECE /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 985347B71C71C33800AC6ECE /* main.c */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ 985347B21C71C33800AC6ECE /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = /usr/share/man/man1/; dstSubfolderSpec = 0; files = ( ); runOnlyForDeploymentPostprocessing = 1; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 985347B41C71C33800AC6ECE /* zmreplacewords */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = zmreplacewords; sourceTree = BUILT_PRODUCTS_DIR; }; 985347B71C71C33800AC6ECE /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 985347B11C71C33800AC6ECE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 985347AB1C71C33800AC6ECE = { isa = PBXGroup; children = ( 985347B61C71C33800AC6ECE /* zmreplacewords */, 985347B51C71C33800AC6ECE /* Products */, ); sourceTree = ""; }; 985347B51C71C33800AC6ECE /* Products */ = { isa = PBXGroup; children = ( 985347B41C71C33800AC6ECE /* zmreplacewords */, ); name = Products; sourceTree = ""; }; 985347B61C71C33800AC6ECE /* zmreplacewords */ = { isa = PBXGroup; children = ( 985347B71C71C33800AC6ECE /* main.c */, ); path = zmreplacewords; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 985347B31C71C33800AC6ECE /* zmreplacewords */ = { isa = PBXNativeTarget; buildConfigurationList = 985347BB1C71C33800AC6ECE /* Build configuration list for PBXNativeTarget "zmreplacewords" */; buildPhases = ( 985347B01C71C33800AC6ECE /* Sources */, 985347B11C71C33800AC6ECE /* Frameworks */, 985347B21C71C33800AC6ECE /* CopyFiles */, ); buildRules = ( ); dependencies = ( ); name = zmreplacewords; productName = zmreplacewords; productReference = 985347B41C71C33800AC6ECE /* zmreplacewords */; productType = "com.apple.product-type.tool"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 985347AC1C71C33800AC6ECE /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0720; ORGANIZATIONNAME = zm; TargetAttributes = { 985347B31C71C33800AC6ECE = { CreatedOnToolsVersion = 7.2; }; }; }; buildConfigurationList = 985347AF1C71C33800AC6ECE /* Build configuration list for PBXProject "zmreplacewords" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = 985347AB1C71C33800AC6ECE; productRefGroup = 985347B51C71C33800AC6ECE /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 985347B31C71C33800AC6ECE /* zmreplacewords */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ 985347B01C71C33800AC6ECE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 985347B81C71C33800AC6ECE /* main.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 985347B91C71C33800AC6ECE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; name = Debug; }; 985347BA1C71C33800AC6ECE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; name = Release; }; 985347BC1C71C33800AC6ECE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 985347BD1C71C33800AC6ECE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 985347AF1C71C33800AC6ECE /* Build configuration list for PBXProject "zmreplacewords" */ = { isa = XCConfigurationList; buildConfigurations = ( 985347B91C71C33800AC6ECE /* Debug */, 985347BA1C71C33800AC6ECE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 985347BB1C71C33800AC6ECE /* Build configuration list for PBXNativeTarget "zmreplacewords" */ = { isa = XCConfigurationList; buildConfigurations = ( 985347BC1C71C33800AC6ECE /* Debug */, 985347BD1C71C33800AC6ECE /* Release */, ); defaultConfigurationIsVisible = 0; }; /* End XCConfigurationList section */ }; rootObject = 985347AC1C71C33800AC6ECE /* Project object */; } ================================================ FILE: zmreplacewords/zmreplacewords.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================