New Code for : Xcode9 - Swift4 - iOS11 - iPhoneX and

https://nextcloud.com/blog/nextcloud-introducing-native-integrated-end-t
o-end-encryption/
This commit is contained in:
Marino Faggiana 2017-09-27 15:39:51 +02:00
Родитель 138143db11
Коммит 184fe2c5f2
823 изменённых файлов: 39608 добавлений и 294929 удалений

Просмотреть файл

@ -1,37 +0,0 @@
//
// AESCrypt.h
// Gurpartap Singh
//
// Created by Gurpartap Singh on 06/05/12.
// Copyright (c) 2012 Gurpartap Singh
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
@interface AESCrypt : NSObject
+ (NSString *)encrypt:(NSString *)message password:(NSString *)password;
+ (NSString *)decrypt:(NSString *)base64EncodedString password:(NSString *)password;
@end

Просмотреть файл

@ -1,50 +0,0 @@
//
// AESCrypt.m
// Gurpartap Singh
//
// Created by Gurpartap Singh on 06/05/12.
// Copyright (c) 2012 Gurpartap Singh
//
// MIT License
//
// 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 "AESCrypt.h"
#import "NSData+Base64.h"
#import "NSString+Base64.h"
#import "NSData+CommonCrypto.h"
@implementation AESCrypt
+ (NSString *)encrypt:(NSString *)message password:(NSString *)password {
NSData *encryptedData = [[message dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptedDataUsingKey:[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:nil];
NSString *base64EncodedString = [NSString base64StringFromData:encryptedData length:[encryptedData length]];
return base64EncodedString;
}
+ (NSString *)decrypt:(NSString *)base64EncodedString password:(NSString *)password {
NSData *encryptedData = [NSData base64DataFromString:base64EncodedString];
NSData *decryptedData = [encryptedData decryptedAES256DataUsingKey:[[password dataUsingEncoding:NSUTF8StringEncoding] SHA256Hash] error:nil];
return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
}
@end

Просмотреть файл

@ -1,17 +0,0 @@
//
// NSData+Base64.m
// Gurpartap Singh
//
// Created by Gurpartap Singh on 06/05/12.
// Copyright (c) 2012 Gurpartap Singh. All rights reserved.
//
#import <Foundation/Foundation.h>
@class NSString;
@interface NSData (Base64Additions)
+ (NSData *)base64DataFromString:(NSString *)string;
@end

Просмотреть файл

@ -1,110 +0,0 @@
//
// NSData+Base64.h
// Gurpartap Singh
//
// Created by Gurpartap Singh on 06/05/12.
// Copyright (c) 2012 Gurpartap Singh. All rights reserved.
//
#import "NSData+Base64.h"
@implementation NSData (Base64Additions)
+ (NSData *)base64DataFromString:(NSString *)string {
unsigned long ixtext, lentext;
unsigned char ch, inbuf[4], outbuf[3];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil) {
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true) {
if (ixtext >= lentext) {
break;
}
ch = tempcstring [ixtext++];
flignore = false;
if ((ch >= 'A') && (ch <= 'Z')) {
ch = ch - 'A';
}
else if ((ch >= 'a') && (ch <= 'z')) {
ch = ch - 'a' + 26;
}
else if ((ch >= '0') && (ch <= '9')) {
ch = ch - '0' + 52;
}
else if (ch == '+') {
ch = 62;
}
else if (ch == '=') {
flendtext = true;
}
else if (ch == '/') {
ch = 63;
}
else {
flignore = true;
}
if (!flignore) {
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext) {
if (ixinbuf == 0) {
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2)) {
ctcharsinbuf = 1;
}
else {
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4) {
ixinbuf = 0;
outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);
for (i = 0; i < ctcharsinbuf; i++) {
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak) {
break;
}
}
}
return theData;
}
@end

Просмотреть файл

@ -1,112 +0,0 @@
/*
* NSData+CommonCrypto.h
* AQToolkit
*
* Created by Jim Dovey on 31/8/2008.
*
* Copyright (c) 2008-2009, Jim Dovey
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of this project's author nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#import <Foundation/NSData.h>
#import <Foundation/NSError.h>
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonHMAC.h>
extern NSString * const kCommonCryptoErrorDomain;
@interface NSError (CommonCryptoErrorDomain)
+ (NSError *) errorWithCCCryptorStatus: (CCCryptorStatus) status;
@end
@interface NSData (CommonDigest)
- (NSData *) MD2Sum;
- (NSData *) MD4Sum;
- (NSData *) MD5Sum;
- (NSData *) SHA1Hash;
- (NSData *) SHA224Hash;
- (NSData *) SHA256Hash;
- (NSData *) SHA384Hash;
- (NSData *) SHA512Hash;
@end
@interface NSData (CommonCryptor)
- (NSData *) AES256EncryptedDataUsingKey: (id) key error: (NSError **) error;
- (NSData *) decryptedAES256DataUsingKey: (id) key error: (NSError **) error;
- (NSData *) DESEncryptedDataUsingKey: (id) key error: (NSError **) error;
- (NSData *) decryptedDESDataUsingKey: (id) key error: (NSError **) error;
- (NSData *) CASTEncryptedDataUsingKey: (id) key error: (NSError **) error;
- (NSData *) decryptedCASTDataUsingKey: (id) key error: (NSError **) error;
@end
@interface NSData (LowLevelCommonCryptor)
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
error: (CCCryptorStatus *) error;
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error;
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
initializationVector: (id) iv // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error;
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
error: (CCCryptorStatus *) error;
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error;
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
initializationVector: (id) iv // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error;
@end
@interface NSData (CommonHMAC)
- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm;
- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm key: (id) key;
@end

Просмотреть файл

@ -1,546 +0,0 @@
/*
* NSData+CommonCrypto.m
* AQToolkit
*
* Created by Jim Dovey on 31/8/2008.
*
* Copyright (c) 2008-2009, Jim Dovey
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of this project's author nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#import <Foundation/Foundation.h>
#import "NSData+CommonCrypto.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonHMAC.h>
NSString * const kCommonCryptoErrorDomain = @"CommonCryptoErrorDomain";
@implementation NSError (CommonCryptoErrorDomain)
+ (NSError *) errorWithCCCryptorStatus: (CCCryptorStatus) status
{
NSString * description = nil, * reason = nil;
switch ( status )
{
case kCCSuccess:
description = NSLocalizedString(@"Success", @"Error description");
break;
case kCCParamError:
description = NSLocalizedString(@"Parameter Error", @"Error description");
reason = NSLocalizedString(@"Illegal parameter supplied to encryption/decryption algorithm", @"Error reason");
break;
case kCCBufferTooSmall:
description = NSLocalizedString(@"Buffer Too Small", @"Error description");
reason = NSLocalizedString(@"Insufficient buffer provided for specified operation", @"Error reason");
break;
case kCCMemoryFailure:
description = NSLocalizedString(@"Memory Failure", @"Error description");
reason = NSLocalizedString(@"Failed to allocate memory", @"Error reason");
break;
case kCCAlignmentError:
description = NSLocalizedString(@"Alignment Error", @"Error description");
reason = NSLocalizedString(@"Input size to encryption algorithm was not aligned correctly", @"Error reason");
break;
case kCCDecodeError:
description = NSLocalizedString(@"Decode Error", @"Error description");
reason = NSLocalizedString(@"Input data did not decode or decrypt correctly", @"Error reason");
break;
case kCCUnimplemented:
description = NSLocalizedString(@"Unimplemented Function", @"Error description");
reason = NSLocalizedString(@"Function not implemented for the current algorithm", @"Error reason");
break;
default:
description = NSLocalizedString(@"Unknown Error", @"Error description");
break;
}
NSMutableDictionary * userInfo = [[NSMutableDictionary alloc] init];
[userInfo setObject: description forKey: NSLocalizedDescriptionKey];
if ( reason != nil )
[userInfo setObject: reason forKey: NSLocalizedFailureReasonErrorKey];
NSError * result = [NSError errorWithDomain: kCommonCryptoErrorDomain code: status userInfo: userInfo];
#if !__has_feature(objc_arc)
[userInfo release];
#endif
return ( result );
}
@end
#pragma mark -
@implementation NSData (CommonDigest)
- (NSData *) MD2Sum
{
unsigned char hash[CC_MD2_DIGEST_LENGTH];
(void) CC_MD2( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_MD2_DIGEST_LENGTH] );
}
- (NSData *) MD4Sum
{
unsigned char hash[CC_MD4_DIGEST_LENGTH];
(void) CC_MD4( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_MD4_DIGEST_LENGTH] );
}
- (NSData *) MD5Sum
{
unsigned char hash[CC_MD5_DIGEST_LENGTH];
(void) CC_MD5( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_MD5_DIGEST_LENGTH] );
}
- (NSData *) SHA1Hash
{
unsigned char hash[CC_SHA1_DIGEST_LENGTH];
(void) CC_SHA1( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA1_DIGEST_LENGTH] );
}
- (NSData *) SHA224Hash
{
unsigned char hash[CC_SHA224_DIGEST_LENGTH];
(void) CC_SHA224( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA224_DIGEST_LENGTH] );
}
- (NSData *) SHA256Hash
{
unsigned char hash[CC_SHA256_DIGEST_LENGTH];
(void) CC_SHA256( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA256_DIGEST_LENGTH] );
}
- (NSData *) SHA384Hash
{
unsigned char hash[CC_SHA384_DIGEST_LENGTH];
(void) CC_SHA384( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA384_DIGEST_LENGTH] );
}
- (NSData *) SHA512Hash
{
unsigned char hash[CC_SHA512_DIGEST_LENGTH];
(void) CC_SHA512( [self bytes], (CC_LONG)[self length], hash );
return ( [NSData dataWithBytes: hash length: CC_SHA512_DIGEST_LENGTH] );
}
@end
@implementation NSData (CommonCryptor)
- (NSData *) AES256EncryptedDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmAES128
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) decryptedAES256DataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmAES128
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) DESEncryptedDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmDES
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) decryptedDESDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmDES
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) CASTEncryptedDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmCAST
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
- (NSData *) decryptedCASTDataUsingKey: (id) key error: (NSError **) error
{
CCCryptorStatus status = kCCSuccess;
NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmCAST
key: key
options: kCCOptionPKCS7Padding
error: &status];
if ( result != nil )
return ( result );
if ( error != NULL )
*error = [NSError errorWithCCCryptorStatus: status];
return ( nil );
}
@end
static void FixKeyLengths( CCAlgorithm algorithm, NSMutableData * keyData, NSMutableData * ivData )
{
NSUInteger keyLength = [keyData length];
switch ( algorithm )
{
case kCCAlgorithmAES128:
{
if ( keyLength < 16 )
{
[keyData setLength: 16];
}
else if ( keyLength < 24 )
{
[keyData setLength: 24];
}
else
{
[keyData setLength: 32];
}
break;
}
case kCCAlgorithmDES:
{
[keyData setLength: 8];
break;
}
case kCCAlgorithm3DES:
{
[keyData setLength: 24];
break;
}
case kCCAlgorithmCAST:
{
if ( keyLength < 5 )
{
[keyData setLength: 5];
}
else if ( keyLength > 16 )
{
[keyData setLength: 16];
}
break;
}
case kCCAlgorithmRC4:
{
if ( keyLength > 512 )
[keyData setLength: 512];
break;
}
default:
break;
}
[ivData setLength: [keyData length]];
}
@implementation NSData (LowLevelCommonCryptor)
- (NSData *) _runCryptor: (CCCryptorRef) cryptor result: (CCCryptorStatus *) status
{
size_t bufsize = CCCryptorGetOutputLength( cryptor, (size_t)[self length], true );
void * buf = malloc( bufsize );
size_t bufused = 0;
size_t bytesTotal = 0;
*status = CCCryptorUpdate( cryptor, [self bytes], (size_t)[self length],
buf, bufsize, &bufused );
if ( *status != kCCSuccess )
{
free( buf );
return ( nil );
}
bytesTotal += bufused;
// From Brent Royal-Gordon (Twitter: architechies):
// Need to update buf ptr past used bytes when calling CCCryptorFinal()
*status = CCCryptorFinal( cryptor, buf + bufused, bufsize - bufused, &bufused );
if ( *status != kCCSuccess )
{
free( buf );
return ( nil );
}
bytesTotal += bufused;
return ( [NSData dataWithBytesNoCopy: buf length: bytesTotal] );
}
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key
error: (CCCryptorStatus *) error
{
return ( [self dataEncryptedUsingAlgorithm: algorithm
key: key
initializationVector: nil
options: 0
error: error] );
}
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key
options: (CCOptions) options
error: (CCCryptorStatus *) error
{
return ( [self dataEncryptedUsingAlgorithm: algorithm
key: key
initializationVector: nil
options: options
error: error] );
}
- (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key
initializationVector: (id) iv
options: (CCOptions) options
error: (CCCryptorStatus *) error
{
CCCryptorRef cryptor = NULL;
CCCryptorStatus status = kCCSuccess;
NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
NSMutableData * keyData, * ivData;
if ( [key isKindOfClass: [NSData class]] )
keyData = (NSMutableData *) [key mutableCopy];
else
keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
if ( [iv isKindOfClass: [NSString class]] )
ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
else
ivData = (NSMutableData *) [iv mutableCopy]; // data or nil
#if !__has_feature(objc_arc)
[keyData autorelease];
[ivData autorelease];
#endif
// ensure correct lengths for key and iv data, based on algorithms
FixKeyLengths( algorithm, keyData, ivData );
status = CCCryptorCreate( kCCEncrypt, algorithm, options,
[keyData bytes], [keyData length], [ivData bytes],
&cryptor );
if ( status != kCCSuccess )
{
if ( error != NULL )
*error = status;
return ( nil );
}
NSData * result = [self _runCryptor: cryptor result: &status];
if ( (result == nil) && (error != NULL) )
*error = status;
CCCryptorRelease( cryptor );
return ( result );
}
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
error: (CCCryptorStatus *) error
{
return ( [self decryptedDataUsingAlgorithm: algorithm
key: key
initializationVector: nil
options: 0
error: error] );
}
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error
{
return ( [self decryptedDataUsingAlgorithm: algorithm
key: key
initializationVector: nil
options: options
error: error] );
}
- (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
key: (id) key // data or string
initializationVector: (id) iv // data or string
options: (CCOptions) options
error: (CCCryptorStatus *) error
{
CCCryptorRef cryptor = NULL;
CCCryptorStatus status = kCCSuccess;
NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
NSMutableData * keyData, * ivData;
if ( [key isKindOfClass: [NSData class]] )
keyData = (NSMutableData *) [key mutableCopy];
else
keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
if ( [iv isKindOfClass: [NSString class]] )
ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
else
ivData = (NSMutableData *) [iv mutableCopy]; // data or nil
#if !__has_feature(objc_arc)
[keyData autorelease];
[ivData autorelease];
#endif
// ensure correct lengths for key and iv data, based on algorithms
FixKeyLengths( algorithm, keyData, ivData );
status = CCCryptorCreate( kCCDecrypt, algorithm, options,
[keyData bytes], [keyData length], [ivData bytes],
&cryptor );
if ( status != kCCSuccess )
{
if ( error != NULL )
*error = status;
return ( nil );
}
NSData * result = [self _runCryptor: cryptor result: &status];
if ( (result == nil) && (error != NULL) )
*error = status;
CCCryptorRelease( cryptor );
return ( result );
}
@end
@implementation NSData (CommonHMAC)
- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm
{
return ( [self HMACWithAlgorithm: algorithm key: nil] );
}
- (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm key: (id) key
{
NSParameterAssert(key == nil || [key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
NSData * keyData = nil;
if ( [key isKindOfClass: [NSString class]] )
keyData = [key dataUsingEncoding: NSUTF8StringEncoding];
else
keyData = (NSData *) key;
// this could be either CC_SHA1_DIGEST_LENGTH or CC_MD5_DIGEST_LENGTH. SHA1 is larger.
unsigned char buf[CC_SHA1_DIGEST_LENGTH];
CCHmac( algorithm, [keyData bytes], [keyData length], [self bytes], [self length], buf );
return ( [NSData dataWithBytes: buf length: (algorithm == kCCHmacAlgMD5 ? CC_MD5_DIGEST_LENGTH : CC_SHA1_DIGEST_LENGTH)] );
}
@end

Просмотреть файл

@ -1,15 +0,0 @@
//
// NSString+Base64.h
// Gurpartap Singh
//
// Created by Gurpartap Singh on 06/05/12.
// Copyright (c) 2012 Gurpartap Singh. All rights reserved.
//
#import <Foundation/NSString.h>
@interface NSString (Base64Additions)
+ (NSString *)base64StringFromData:(NSData *)data length:(NSUInteger)length;
@end

Просмотреть файл

@ -1,83 +0,0 @@
//
// NSStringAdditions.m
// Gurpartap Singh
//
// Created by Gurpartap Singh on 06/05/12.
// Copyright (c) 2012 Gurpartap Singh. All rights reserved.
//
#import "NSString+Base64.h"
#import <Foundation/Foundation.h>
static char base64EncodingTable[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};
@implementation NSString (Base64Additions)
+ (NSString *)base64StringFromData: (NSData *)data length: (NSUInteger)length {
unsigned long ixtext, lentext;
long ctremaining;
unsigned char input[3], output[4];
short i, charsonline = 0, ctcopy;
const unsigned char *raw;
NSMutableString *result;
lentext = [data length];
if (lentext < 1) {
return @"";
}
result = [NSMutableString stringWithCapacity: lentext];
raw = [data bytes];
ixtext = 0;
while (true) {
ctremaining = lentext - ixtext;
if (ctremaining <= 0) {
break;
}
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext) {
input[i] = raw[ix];
}
else {
input[i] = 0;
}
}
output[0] = (input[0] & 0xFC) >> 2;
output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
output[3] = input[2] & 0x3F;
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++) {
[result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
}
for (i = ctcopy; i < 4; i++) {
[result appendString: @"="];
}
ixtext += 3;
charsonline += 4;
if ((length > 0) && (charsonline >= length)) {
charsonline = 0;
}
}
return result;
}
@end

Просмотреть файл

@ -1,38 +0,0 @@
BasedOnStyle: Chromium
AlignTrailingComments: true
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: false
BeforeCatch: true
BeforeElse: true
IndentBraces: false
BreakBeforeBraces: Allman
ColumnLimit: 0
IndentCaseLabels: true
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never

Просмотреть файл

@ -1,12 +0,0 @@
additional_guides:
- https://github.com/magicalpanda/MagicalRecord/wiki/Installing-MagicalRecord
- https://github.com/magicalpanda/MagicalRecord/wiki/Getting-Started
- https://github.com/magicalpanda/MagicalRecord/wiki/Working-with-Managed-Object-Contexts
- https://github.com/magicalpanda/MagicalRecord/wiki/Creating-Entities
- https://github.com/magicalpanda/MagicalRecord/wiki/Deleting-Entities
- https://github.com/magicalpanda/MagicalRecord/wiki/Fetching-Entities
- https://github.com/magicalpanda/MagicalRecord/wiki/Saving
- https://github.com/magicalpanda/MagicalRecord/wiki/Usage-Patterns
- https://github.com/magicalpanda/MagicalRecord/wiki/Importing-Data
- https://github.com/magicalpanda/MagicalRecord/wiki/Logging
- https://github.com/magicalpanda/MagicalRecord/wiki/Upgrading-to-MagicalRecord-2.3

26
Libraries external/MagicalRecord/.gitignore поставляемый
Просмотреть файл

@ -1,26 +0,0 @@
# Finder
.DS_Store
# Xcode
build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
*.xcworkspace
!default.xcworkspace
xcuserdata
profile
*.moved-aside
DerivedData
Carthage/Build
*.gcno
*.gcda
MagicalRecord.framework.zip

Просмотреть файл

@ -1,3 +0,0 @@
[submodule "Carthage/Checkouts/expecta"]
path = Carthage/Checkouts/expecta
url = https://github.com/specta/expecta.git

Просмотреть файл

@ -1,27 +0,0 @@
language: objective-c
osx_image: xcode7.2
script: Support/Scripts/objc-build-scripts/cibuild
env:
global:
- FRAMEWORK_NAME=MagicalRecord
- secure: WIm8vwQHOrBPCkWGmV0YMV+k92Dva6ORd0hfi96UzGRC/FTghzrelvLmTzr5kJXCeStv5ZxCNCUvJZm8q4J4y+6UdMQu5FPnx4+EKoogC4quJV8H1pXlXmoetITQdK7t2ldRH1EOuELdmpx2g5hydinu5Z5KMHb0vgLqtn9PvAc=
# before_script:
# - carthage bootstrap
before_deploy:
- carthage build --no-skip-current
- carthage archive $FRAMEWORK_NAME
deploy:
provider: script
script: ./Support/Scripts/push_podspec.sh
on:
repo: magicalpanda/MagicalRecord
tags: true
deploy:
provider: releases
api_key:
secure: 1exCONwRvGbV+hi1N4n1VSbqJYpOaJW9zloj17Lxx14dQCyv7p2cSwB79A3RVOifJQg9pgC7eeyn4njKaIB9SZiDznhAiUlvFhNcuOdVrwmjqyxiYFByXNr4f0GVa7opIn9s/WDqGW8qQUQSOdoql5U9B/n5Mt86Jt5cws1BoYE=
file: "$FRAMEWORK_NAME.framework.zip"
skip_cleanup: true
on:
repo: magicalpanda/MagicalRecord
tags: true

Просмотреть файл

@ -1,145 +0,0 @@
# Changelog
## Version 2.3.2
This release fixes an issue where the OS X framework was being built with instrumentation data, and included in the binary builds posted to GitHub. It contains no other fixes over MagicalRecord v2.3.1.
## Version 2.3.1
- CocoaPods users who want to use:
- Shorthand method aliases should add `pod 'MagicalRecord/ShorthandMethodAliases'` to their Podfile, and run `pod update`
- CocoaLumberjack should add `pod 'MagicalRecord/CocoaLumberjack'` to their Podfile, and run `pod update`
- Fixed a Core Data multithreading violation when setting a context's working name
- Fixed the check for whether `NSPersistentStoreUbiquitousContentNameKey` is valid when using iCloud containers
- Attempting to delete a `nil` managed object, or a managed object not present in the context will do nothing (previously it crashed)
- Add a fix for CocoaLumberjack reporting duplicate definitions of LOG_MAYBE
- Added error logging when the passed value for `relatedByAttribute` is invalid during a relationship import
- Added more lightweight generics and nullability annotations
## Version 2.3
* Dynamic framework targets are provided for both OS X 10.8+ and iOS 8.0+
* Logging is enabled by default, change the logging level using `+[MagicalRecord setLoggingLevel: MagicalRecordLogLevelOff];` — [see the documentation in the wiki](https://github.com/magicalpanda/MagicalRecord/wiki/Logging)
* CocoaLumberjack 2.0 support
* Enabling shorthand category method names can now be done by importing:
```objective-c
#import <MagicalRecord/MagicalRecord.h>
#import <MagicalRecord/MagicalRecord+ShorthandMethods.h>
#import <MagicalRecord/MagicalRecordShorthandMethodAliases.h>
```
Then calling `+[MagicalRecord enableShorthandMethods]`.
[See the documentation in the wiki](https://github.com/magicalpanda/MagicalRecord/wiki/Installing-MagicalRecord#shorthand-category-methods).
* Support for running with Core Data's concurrency debugging checks enabled
* Many, many, many, many fixes to reported issues
## Version 2.2
* Updated examples and fixed errors in README - [Tony Arnold](mailto:tony@thecocoabots.com)
* Changes block saves to use child context of rootSavingContext so that large saves do not channel through the default context and block the main thread - r-peck
* Using contextDidSave notifications to perform merges - r-peck
* Included CoreDataRecipies sample application updated to use Magical Record - [Saul Mora](mailto:saul@magicalpanda.com)
## Version 2.1.0
* Fixed issue #287 - MR_findByAttribute:withValue:andOrderBy:ascending:inContext does not pass context through `4b97d0e` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Adding changelog `da70884` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Cleanup contextWillSave method Update deleting incompatible store `2eaec27` - [Saul Mora](mailto:saul@magicalpanda.com)
* don't check the error, rely only on the return value of methods to determine success `64a81c6` - [Saul Mora](mailto:saul@magicalpanda.com)
* removed MR_saveErrorHandler, as it and MR_saveWithErrorCallback were essentially duplicates MR_save now only saves the current context (it was essentially doing a MR_saveNestedContexts). If you need to save all the way out to disk, use MR_saveNestedContexts. Removed the action queue, unneccesary since core data introduced it's own queue support `f7c4350` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Separate printing context chain method into its own method change contextWorkingName to property workingName `0fb7d36` - [Saul Mora](mailto:saul@magicalpanda.com)
* Added fetchAllWithDelegate: method for NSFRC `c0a1657` - [Saul Mora](mailto:saul@magicalpanda.com)
* Fixed Issue #294 - MR_requestAllSortedBy:ascending:inContext: did not use correct context `3656e74` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Bumping podspec version `fb81b5b` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Updating changelog `20f02ba` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Re-Added obtaining permanent ids automatically `cfccd40` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Minor formatting updates `1440623` - [Saul Mora](mailto:saul@magicalpanda.com)
* Pass errorCallback through convenience method `5376700` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Implement new save methods `4f35e4e` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update existing save tests to reflect save changes. Also begin adding tests for deprecated methods to ensure consistent behaviour in unmodified code. `c763d4a` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Fix compilation problems under latest Xcode. `af84aff` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update gitignore and remove user specific xcuserdata `d0e771d` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Add Kiwi for saner asynchronous testing and remove existing GHUnit tests for save methods `55af799` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Flesh out tests for MagicalRecord+Actions and the NSManagedObjectContext+MagicalSaves category `a28d421` - [Tony Arnold](mailto:tony@thecocoabots.com)
* The deprecated saveWithBlock: method should do it's work on the current thread `2c66056` - [Tony Arnold](mailto:tony@thecocoabots.com)
* All deprecated and non-deprecated methods have tests to ensure their function `c2fa8c4` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update README with details of the changes in this branch `4316422` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update shorthand methods and import the magical saves category so that MRSaveCompletionHandler resolves `1af1201` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Updated podspec to 2.1.beta.1 `5ed45f6` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Minor text editing. `710d643` - [nerdery-isaac](mailto:isaac.greenspan@nerdery.com)
* Added additional case that will trigger persistant store cleanup `36d1630` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Alter saveWithBlock: so that it runs asynchronously. Fixes #349. `357b62e` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Execute save completion blocks on the main dispatch queue. `065352d` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Fix broken GHUnit tests after recent changes to the save methods `0c83121` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Add Clang-style documentation for the MagicalSaves category. Also add Clang's -Wdocumentation warning to assist in writing in future documentation. `eb8865a` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Remove unused notification constant `5a40bcc` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Finalise documentation for MagicalRecord 2.1.0 `f370cdb` - [Tony Arnold](mailto:tony@thecocoabots.com)
* Update pod spec to MagicalRecord 2.1.0 `46b6004` - [Tony Arnold](mailto:tony@thecocoabots.com)
## Version 2.0.8
* Fixed issue #287 - MR_findByAttribute:withValue:andOrderBy:ascending:inContext does not pass context through `4b97d0e` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Adding changelog `da70884` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Cleanup contextWillSave method Update deleting incompatible store `2eaec27` - [Saul Mora](mailto:saul@magicalpanda.com)
* don't check the error, rely only on the return value of methods to determine success `64a81c6` - [Saul Mora](mailto:saul@magicalpanda.com)
* removed MR_saveErrorHandler, as it and MR_saveWithErrorCallback were essentially duplicates MR_save now only saves the current context (it was essentially do
* Separate printing context chain method into its own method change contextWorkingName to property workingName `0fb7d36` - [Saul Mora](mailto:saul@magicalpanda
* Added fetchAllWithDelegate: method for NSFRC `c0a1657` - [Saul Mora](mailto:saul@magicalpanda.com)
* Fixed Issue #294 - MR_requestAllSortedBy:ascending:inContext: did not use correct context `3656e74` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Bumping podspec version `fb81b5b` - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
## Version 2.0.7
* Fix small error in README with regard to MR_SHORTHAND - [Maik Gosenshuis](mailto:maik@gosenshuis.nl)
* Hide intended private cleanUpErrorHandling method - [Saul Mora](mailto:saul@magicalpanda.com)
* Call completion handler on main thread. - [Brandon Williams](mailto:brandon@opetopic.com)
* Persist changes to disk when using: - [NSManagedObjectContext MR_saveInBackgroundErrorHandler:completion:] methods, AND the context is the default context - [MagicalRecord saveInBackground…] methods - [Saul Mora](mailto:saul@magicalpanda.com)
* [NSManagedObjectContext MR_saveInBackgroundErrorHandler:completion:] - [Jwie](mailto:joey.daman@twoup.eu)
* [NSManagedObjectContext MR_saveInBackgroundErrorHandler:completion:] - [Jwie](mailto:joey.daman@twoup.eu)
* update - [Peter Paulis](mailto:peterpaulis@Admins- acBook-Air-2.local)
* Correct typo - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Update MR_SHORTHAND installation note to match main readme - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Correct typo of "persistent" in method name - m[Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Make all requestAllSortedBy* methods consistent (allows sortTerms with commas) - [vguerci](mailto:vguerci@gmail.com)
* dispatch_release is not needed by the <REDACTED> compiler - [Saul Mora](mailto:saul@magicalpanda.com)
* Don't run completion block if non specified - [Saul Mora](mailto:saul@magicalpanda.com)
* Make platform requirements more explicit - [Saul Mora](mailto:saul@magicalpanda.com)
* Update MagicalRecord/Core/MagicalRecordShorthand.h - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Added automatic store deletion if the store does not match the model - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Missed the configuration - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Updating readme with a short blurb - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Cleanup code is now debug-only - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Clarified the DEBUG only nature of the fix - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Making background save asynchronous and fix the callback not firing - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Added expecta matchers for tests - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Fixing formatting issues to match project style - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Fixed KVC relationship mapping bug. - [Joshua Greene](mailto:jrg.developer@gmail.com)
* Fixed an issue with aggregate actions not being performed in the specified context - [Brian King](mailto:bking@agamatrix.com)
* Adding an observer to check for icloud being setup after default context has been set. Should fix race condition in Issue #241 - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Updated test model to actually build - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Clean up comments - [Saul Mora](mailto:saul@magicalpanda.com)
* Remove compile warnings - [Saul Mora](mailto:saul@magicalpanda.com)
* Cleaning up iCloud setup observer code some - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Removes dispatch_release when iOS >= 6 || OSX >= 1080 - [Rod Wilhelmy](mailto:rwilhelmy@gmail.com)
* Modifiying generateShorthand.rb to use user specified ruby - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Automatically obtain permanent IDs when saving the default context. This should fix several crashes the community is hitting - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Making all relevant contexts obtain a permanent id before saving - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Adding recommended journalling mode - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* fixup compiler warnings in Xcode 4.5 - [Saul Mora](mailto:saul@magicalpanda.com)
* Fix compile warnings once and for all :/ - [Saul Mora](mailto:saul@magicalpanda.com)
* refactor internal method names to match more general objects to traverse fix another compile warning - [Saul Mora](mailto:saul@magicalpanda.com)
* - auto- igration options bug fix - [Alexander Belyavskiy](mailto:diejmon@me.com)
* Don't adjust incoming NSDates for DST - [Saul Mora](mailto:saul@magicalpanda.com)
* fix compile error with pragma option - [Saul Mora](mailto:saul@magicalpanda.com)
* Add findFirstOrderedByAttribute:ascending:context: method for getting min/max values easier - [Saul Mora](mailto:saul@magicalpanda.com)
* Bumping podspec to 2.0.4 - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Added new nestedContextSave method with completion handler - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Bumping podspec with bugfix - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Fixing rookie mistake :/ - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Require ARC in podspec (was compiling with retain/release in pod installations) - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Bump tag to 2.0.6 - [Ryan Maxwell](mailto:ryanm@xwell.co.nz)
* Properly removing existing on-save notificaitons before replacing the default or root contexts - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Fixing potential concurrency issue with creating the actionQueue - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Cherry picking changes that make the context description more... descriptive - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* Rolled back a commit that broke things if cleanup was used. It created the action_queue in a dispatch_once block, and never recreated it after a cleanup - [Stephen Vanterpool](mailto:stephen@vanterpool.net)
* saveWithBlock was not saving parent contexts - [Tony Arnold](mailto:tony@thecocoabots.com)
* Test that the current thread saveWith method actually saves - [Tony Arnold](mailto:tony@thecocoabots.com)
* Bumped podspec to 2.0.7 - [Stephen Vanterpool](mailto:stephen@vanterpool.net)

Просмотреть файл

@ -1,25 +0,0 @@
Thanks for contributing to this project!
To make the process as easy as possible, we've got a few guidelines that we'd appreciate you following:
## Filing Issues
Before you file an issue, please ensure that:
1. **It's a bug or a feature request** — if you're looking for help using MagicalRecord, please ask your question on [Stack Overflow](http://stackoverflow.com/). We monitor the [**MagicalRecord** tag](http://stackoverflow.com/questions/tagged/magicalrecord) so be sure to tag your question so that we see it
1. **Search for an existing issue** — there's a good chance you're not the only one experiencing the problem you've come to tell us about
2. **Include as much information as you can** — if we can't reproduce the problem you've filed, we can't fix it. Include crash logs, exception reports and code if you can.
## We Prefer Pull Requests
If you know exactly how to implement the feature being suggested or fix the bug being reported, please open a pull request instead of an issue. Pull requests are easier than patches or inline code blocks for discussing and merging the changes. Please ensure that you include tests in the Pull Request — we use XCTest with [Expecta](http://github.com/specta/expecta/).
If you can't make the change yourself, please open an issue after making sure that one isn't already logged.
## Contributing Code
Fork this repository, make some great changes (preferably in a branch named for the topic of the changes you're making) and send a pull request!
All code contributions should match our [coding conventions](https://github.com/magicalpanda/MagicalRecord/wiki/Coding-Conventions).
Thanks for reading the guidelines!

Просмотреть файл

@ -1 +0,0 @@
github "specta/expecta" ~> 1.0

Просмотреть файл

@ -1 +0,0 @@
github "specta/expecta" "v1.0.3"

Просмотреть файл

@ -1,13 +0,0 @@
# Creating Entities
To create and insert a new instance of an Entity in the default context, you can use:
```objective-c
Person *myPerson = [Person MR_createEntity];
```
To create and insert an entity into specific context:
```objective-c
Person *myPerson = [Person MR_createEntityInContext:otherContext];
```

Просмотреть файл

@ -1,25 +0,0 @@
# Deleting Entities
To delete a single entity in the default context:
```objective-c
[myPerson MR_deleteEntity];
```
To delete the entity from a specific context:
```objective-c
[myPerson MR_deleteEntityInContext:otherContext];
```
To truncate all entities from the default context:
```objective-c
[Person MR_truncateAll];
```
To truncate all entities in a specific context:
```objective-c
[Person MR_truncateAllInContext:otherContext];
```

Просмотреть файл

@ -1,129 +0,0 @@
# Fetching Entities
#### Basic Finding
Most methods in MagicalRecord return an `NSArray` of results.
As an example, if you have an entity named *Person* related to a *Department* entity (as seen in many of [Apple's Core Data examples](.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdBasics.html#//apple_ref/doc/uid/TP40001650-TP1)), you can retrieve all of the *Person* entities from your persistent store using the following method:
```objective-c
NSArray *people = [Person MR_findAll];
```
To return the same entities sorted by a specific attribute:
```objective-c
NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName"
ascending:YES];
```
To return the entities sorted by multiple attributes:
```objective-c
NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName"
ascending:YES];
```
To return the results sorted by multiple attributes with different values. If you don't provide a value for any attribute, it will default to whatever you've set in your model:
```objective-c
NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName:NO,FirstName"
ascending:YES];
// OR
NSArray *peopleSorted = [Person MR_findAllSortedBy:@"LastName,FirstName:YES"
ascending:NO];
```
If you have a unique way of retrieving a single object from your data store (such as an identifier attribute), you can use the following method:
```objective-c
Person *person = [Person MR_findFirstByAttribute:@"FirstName"
withValue:@"Forrest"];
```
#### Advanced Finding
If you want to be more specific with your search, you can use a predicate:
```objective-c
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", @[dept1, dept2]];
NSArray *people = [Person MR_findAllWithPredicate:peopleFilter];
```
#### Returning an NSFetchRequest
```objective-c
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments];
NSFetchRequest *people = [Person MR_requestAllWithPredicate:peopleFilter];
```
For each of these single line calls, an `NSFetchRequest` and `NSSortDescriptor`s for any sorting criteria are created.
#### Customizing the Request
```objective-c
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments];
NSFetchRequest *peopleRequest = [Person MR_requestAllWithPredicate:peopleFilter];
[peopleRequest setReturnsDistinctResults:NO];
[peopleRequest setReturnPropertiesNamed:@[@"FirstName", @"LastName"]];
NSArray *people = [Person MR_executeFetchRequest:peopleRequest];
```
#### Find the number of entities
You can also perform a count of all entities of a specific type in your persistent store:
```objective-c
NSNumber *count = [Person MR_numberOfEntities];
```
Or, if you're looking for a count of entities based on a predicate or some filter:
```objective-c
NSNumber *count = [Person MR_numberOfEntitiesWithPredicate:...];
```
There are also complementary methods which return `NSUInteger` rather than `NSNumber` instances:
```objective-c
+ (NSUInteger) MR_countOfEntities;
+ (NSUInteger) MR_countOfEntitiesWithContext:(NSManagedObjectContext *)context;
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter;
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter
inContext:(NSManagedObjectContext *)context;
```
#### Aggregate Operations
```objective-c
NSNumber *totalCalories = [CTFoodDiaryEntry MR_aggregateOperation:@"sum:"
onAttribute:@"calories"
withPredicate:predicate];
NSNumber *mostCalories = [CTFoodDiaryEntry MR_aggregateOperation:@"max:"
onAttribute:@"calories"
withPredicate:predicate];
NSArray *caloriesByMonth = [CTFoodDiaryEntry MR_aggregateOperation:@"sum:"
onAttribute:@"calories"
withPredicate:predicate
groupBy:@"month"];
```
#### Finding entities in a specific context
All find, fetch, and request methods have an `inContext:` method parameter that allows you to specify which managed object context you'd like to query:
```objective-c
NSArray *peopleFromAnotherContext = [Person MR_findAllInContext:someOtherContext];
Person *personFromContext = [Person MR_findFirstByAttribute:@"lastName"
withValue:@"Gump"
inContext:someOtherContext];
NSUInteger count = [Person MR_numberOfEntitiesWithContext:someOtherContext];
```

Просмотреть файл

@ -1,84 +0,0 @@
To get started, import the `MagicalRecord.h` header file in your project's pch file. This will allow a global include of all the required headers.
If you're using CocoaPods or MagicalRecord.framework, your import should look like:
```objective-c
// Objective-C
#import <MagicalRecord/MagicalRecord.h>
```
```swift
// Swift
import MagicalRecord
```
Otherwise, if you've added MagicalRecord's source files directly to your Objective-C project, your import should be:
```objective-c
#import "MagicalRecord.h"
```
Next, somewhere in your app delegate, in either the `- applicationDidFinishLaunching: withOptions:` method, or `-awakeFromNib`, use **one** of the following setup calls with the **MagicalRecord** class:
```objective-c
+ (void)setupCoreDataStack;
+ (void)setupAutoMigratingCoreDataStack;
+ (void)setupCoreDataStackWithInMemoryStore;
+ (void)setupCoreDataStackWithStoreNamed:(NSString *)storeName;
+ (void)setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(NSString *)storeName;
+ (void)setupCoreDataStackWithStoreAtURL:(NSURL *)storeURL;
+ (void)setupCoreDataStackWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL;
```
Each call instantiates one of each piece of the Core Data stack, and provides getter and setter methods for these instances. These well known instances to MagicalRecord, and are recognized as "defaults".
When using the default SQLite data store with the `DEBUG` flag set, changing your model without creating a new model version will cause MagicalRecord to delete the old store and create a new one automatically. This can be a huge time saver — no more needing to uninstall and reinstall your app every time you make a change your data model! **Please be sure not to ship your app with `DEBUG` enabled: Deleting your app's data without telling the user about it is really bad form!**
Before your app exits, you should call `+cleanUp` class method:
```objective-c
[MagicalRecord cleanUp];
```
This tidies up after MagicalRecord, tearing down our custom error handling and setting all of the Core Data stack created by MagicalRecord to nil.
## iCloud-enabled Persistent Stores
To take advantage of Apple's iCloud Core Data syncing, use **one** of the following setup methods in place of the standard methods listed in the previous section:
```objective-c
+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
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;
+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
localStoreAtURL:(NSURL *)storeURL;
+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
contentNameKey:(NSString *)contentNameKey
localStoreAtURL:(NSURL *)storeURL
cloudStorePathComponent:(NSString *)pathSubcomponent;
+ (void)setupCoreDataStackWithiCloudContainer:(NSString *)containerID
contentNameKey:(NSString *)contentNameKey
localStoreAtURL:(NSURL *)storeURL
cloudStorePathComponent:(NSString *)pathSubcomponent
completion:(void (^)(void))completion;
```
For further details, please refer to [Apple's "iCloud Programming Guide for Core Data"](https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40013491).
### Notes
If you are managing multiple iCloud-enabled stores, we recommended that you use one of the longer setup methods that allows you to specify your own **contentNameKey**. The shorter setup methods automatically generate the **NSPersistentStoreUbiquitousContentNameKey** based on your app's bundle identifier (`CFBundleIdentifier`):

Просмотреть файл

@ -1,194 +0,0 @@
# Importing Data
> We're working on updating this documentation — thanks for your patience.
> For the moment, please refer to [Importing Data Made Easy](http://www.cimgf.com/2012/05/29/importing-data-made-easy/) at [Cocoa Is My Girlfriend](http://www.cimgf.com/). Much of this document is based upon Saul's work in that original article.
>
> <cite>MagicalRecord Team</cite>
MagicalRecord can help import data from standard NSObject instances such as NSArray and NSDictionary directly into your Core Data store.
It's a two step process to import data from an external source into your persistent store using MagicalRecord:
1. **Define how the data you're importing maps to your store** using your data model (it's pretty much codeless!)
2. **Perform the data import**
## Define Your Import
Data from external sources can be wildly variable in quality and structure, so we've done our best to make MagicalRecord's import processes flexible.
**MagicalRecord can import data from any Key-Value Coding (KVC) compliant object**. We usually find people work with `NSArray` and `NSDictionary` instances, but it works just fine with any KVC compliant `NSObject` subclass.
MagicalRecord makes use of the Xcode data modeling tool's "**User Info**" values to allow configuration of import options and mappings possible without having to edit any code.
<p align="center">
<img src="http://cl.ly/image/1e333E3W2Y3E/datamodeller_userinfogroup.png" alt="Xcode's 'User Info' group in the data modeller" width="324" height="374" style="margin: 0 auto;" />
</p>
> **For reference**: The user info keys and values are held in an NSDictionary that is attached to every entity, attribute and relationship in your data model, and can be accessed via the `userInfo` method on your `NSEntityDescription` instances.
Xcode's data modelling tools give you access to this dictionary via the Data Model Inspector's "User Info" group. When editing a data model, you can open this inspector using Xcode's menus — **View > Utilities > Show Data Model Inspector**, or press <kbd>⌥⌘3</kbd> on your keyboard.
By default, MagicalRecord will automatically try to match attribute and relationship names with the keys in your imported data. **If an attribute or relationship name in your model matches a key in your data, you don't need to do anything — the value attached to the key will be imported automatically**.
For example, if an attribute on an entity has the name 'firstName', MagicalRecord will assume the key in the data to import will also have a key of 'firstName' — if it does, your entity's `firstName` attribute will be set to the value of the `firstName` key in your data.
More often than not, the keys and structure in the data you are importing will not match your entity's attributes and relationships. In this case, you will need to tell MagicalRecord how to map your import data's keys to the correct attribute or relationship in your data model.
Each of the three key objects we deal with in Core Data — Entities, Attributes and Relationships — have options that may need to be specified via user info keys:
### Attributes
| Key | Type | Purpose |
|-----|------|---------|
| **attributeValueClassName** | String | TBD |
| **dateFormat** | String | TBD. Defaults to `yyyy-MM-dd'T'HH:mm:ssz`. |
| **mappedKeyName** | String | Specifies the name of the keypath in your data to import the value from. Supports keypaths, delimited by `.`, eg. `location.latitude` |
| **mappedKeyName.[0-9]** | String | Specifies backup keypath names if the key specified by **mappedKeyName** doesn't exist. Supports the same syntax. |
| **useDefaultValueWhenNotPresent** | Boolean | If this is true, the default value for the attribute will be set on the imported instance if no value is found for any key. |
### Entities
| Key | Type | Purpose |
|-----|------|---------|
| **relatedByAttribute** | String | Specifies the attribute in the target of the relationship that links the two. |
### Relationships
| Key | Type | Purpose |
|-----|------|---------|
| **mappedKeyName** | String | Specifies the name of the keypath in your data to import the value from. Supports keypaths, delimited by `.`, eg. `location.latitude` |
| **mappedKeyName.[0-9]** | String | Specifies backup keypath names if the key specified by **mappedKeyName** doesn't exist. Supports the same syntax. |
| **relatedByAttribute** | String | Specifies the attribute in the target of the relationship that links the two. |
| **type** | String | TBD |
## Importing Objects
To import data into your store using MagicalRecord, you need to know two things:
1. The format of the data you're importing, and how it
The basic idea behind MagicalRecord's importing is that you know the entity the data should be imported into, so you then write a single line of code tying this entity with the data to import. There are a couple of options to kick off the import process.
To automatically create a new instance from the object, you can use the following, shorter approach:
```objective-c
NSDictionary *contactInfo = // Result from JSON parser or some other source
Person *importedPerson = [Person MR_importFromObject:contactInfo];
```
You can also use a two-stage approach:
```objective-c
NSDictionary *contactInfo = // Result from JSON parser or some other source
Person *person = [Person MR_createEntity]; // This doesn't have to be a new entity
[person MR_importValuesForKeysWithObject:contactInfo];
```
The two-stage approach can be helpful if youre looking to update an existing object by overwriting its attributes.
`+MR_importFromObject:` will look for an existing object based on the configured lookup value (see the _relatedByAttribute_ and _attributeNameID_). Also notice how this follows the built in paradigm of importing a list of key-value pairs in Cocoa, as well as following the safe way to import data.
The `+MR_importFromObject:` class method provides a wrapper around creating a new object using the previously mentioned `-MR_importValuesForKeysWithObject:` instance method, and returns the newly created object filled with data.
A key item of note is that both these methods are synchronous. While some imports will take longer than others, its still highly advisable to perform *all imports* in the background so as to not impact user interaction. As previously discussed, MagicalRecord provides a handy API to make using background threads more manageable:
```objective-c
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *)localContext {
Person *importedPerson = [Person MR_importFromObject:personRecord inContext:localContext];
}];
```
## Importing Arrays
Its common for a list of data to be served using a JSON array, or youre importing a large list of a single type of data. The details of importing such a list are taken care of in the `+MR_importFromArray:` class method.
```objective-c
NSArray *arrayOfPeopleData = /// result from JSON parser
NSArray *people = [Person MR_importFromArray:arrayOfPeopleData];
```
This method, like `+MR_importFromObject:` is also synchronous, so for background importing, use the previously mentioned helper method for performing blocks in the background.
If your import data exactly matches your Core Data model, then read no further because the aforementioned methods are all you need to import your data into your Core Data store. However, if your data, like most, has little quirks and minor deviations, then read on, as well walk through some of the features of MagicalRecord that will help you handle several commonly encountered deviations.
## Best Practice
### Handling Bad Data When Importing
APIs can often return data that has inconsistent formatting or values. The best way to handle this is to use the import category methods on your entity classes. There are three provided:
Method | Purpose
--------------------------------|---------
`- (BOOL) shouldImport;` | Called before an data is imported. Use this to cancel importing data on a specific instance of an entity by returning `NO`.
`- (void) willImport:(id)data;` | Called immediately before data is imported.
`- (void) didImport:(id)data;` | Called immediately after data has been imported.
Generally, if your data is bad you'll want to fix what the import did after an attempt has been made to import any values.
A common scenario is importing JSON data where numeric strings can often be misinterpreted as an actual number. If you want to ensure that a value is imported as a string, you could do the following:
```obj-c
@interface MyGreatEntity
@property(readwrite, nonatomic, copy) NSString *identifier;
@end
@implementation MyGreatEntity
@dynamic identifier;
- (void)didImport:(id)data
{
if (NO == [data isKindOfClass:[NSDictionary class]]) {
return;
}
NSDictionary *dataDictionary = (NSDictionary *)data;
id identifierValue = dataDictionary[@"my_identifier"];
if ([identifierValue isKindOfClass:[NSNumber class]]) {
NSNumber *numberValue = (NSNumber *)identifierValue;
self.identifier = [numberValue stringValue];
}
}
@end
```
### Deleting local records on import update
Sometimes you will want to make sure that subsequent import operations not only update but also delete local records that are not included as part of the remote dataset. To do this, fetch all local records not included in this update via their `relatedByAttribute` (`id` in the example below) and remove them immediately before importing the new dataset.
```objective-c
NSArray *arrayOfPeopleData = /// result from JSON parser
NSArray *people = [Person MR_importFromArray:arrayOfPeopleData];
NSArray *idList = [arrayOfPeopleData valueForKey:@"id"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT(id IN %@)", idList];
[Person MR_deleteAllMatchingPredicate:predicate];
```
If you also want to make sure that related records are removed during this update, you can use similar logic as above but implement it in the `willImport:` method of `Person`
```objective-c
@implementation Person
-(void)willImport:(id)data {
NSArray *idList = [data[@"posts"] valueForKey:@"id"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT(id IN %@) AND person.id == %@", idList, self.id];
[Post MR_deleteAllMatchingPredicate:predicate];
}
```
Source: http://stackoverflow.com/a/24252825/401092

Просмотреть файл

@ -1,82 +0,0 @@
# Installing MagicalRecord
**Adding MagicalRecord to your project is simple**: Just choose whichever method you're most comfortable with and follow the instructions below.
## Using Carthage
1. Add the following line to your `Cartfile`:
```yaml
github "MagicalPanda/MagicalRecord"
```
2. Run `carthage update` in your project directory.
3. Drag the appropriate `MagicalRecord.framework` for your platform (located in `Carthage/Build/``) into your applications Xcode project, and add it to the appropriate target(s).
## Using CocoaPods
One of the easiest ways to integrate MagicalRecord in your project is to use [CocoaPods](http://cocoapods.org/):
1. Add the following line to your `Podfile`:
a. Plain
````ruby
pod "MagicalRecord"
````
b. With CocoaLumberjack as Logger
````ruby
pod "MagicalRecord/CocoaLumberjack"
````
2. In your project directory, run `pod update`
3. You should now be able to add `#import <MagicalRecord/MagicalRecord.h>` to any of your target's source files and begin using MagicalRecord!
## Using an Xcode subproject
Xcode sub-projects allow your project to use and build MagicalRecord as an implicit dependency.
1. Add MagicalRecord to your project as a Git submodule:
````
$ cd MyXcodeProjectFolder
$ git submodule add https://github.com/magicalpanda/MagicalRecord.git Vendor/MagicalRecord
$ git commit -m "Add MagicalRecord submodule"
````
2. Drag `Vendor/MagicalRecord/MagicalRecord.xcproj` into your existing Xcode project
3. Navigate to your project's settings, then select the target you wish to add MagicalRecord to
4. Navigate to **Build Phases** and expand the **Link Binary With Libraries** section
5. Click the **+** and find the version of the MagicalRecord framework appropriate to your target's platform
6. You should now be able to add `#import <MagicalRecord/MagicalRecord.h>` to any of your target's source files and begin using MagicalRecord!
> **Note** Please be aware that if you've set Xcode's **Link Frameworks Automatically** to **No** then you may need to add the CoreData.framework to your project on iOS, as UIKit does not include Core Data by default. On OS X, Cocoa includes Core Data.
# Shorthand Category Methods
By default, all of the category methods that MagicalRecord provides are prefixed with `MR_`. This is inline with [Apple's recommendation not to create unadorned category methods to avoid naming clashes](https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210-CH6-SW4).
If you like, you can include the following headers to use shorter, non-prefixed category methods:
```objective-c
#import <MagicalRecord/MagicalRecord.h>
#import <MagicalRecord/MagicalRecord+ShorthandMethods.h>
#import <MagicalRecord/MagicalRecordShorthandMethodAliases.h>
```
If you're using Swift, you'll need to add these imports to your target's Objective-C bridging header.
Once you've included the headers, you should call the `+[MagicalRecord enableShorthandMethods]` class method _before_ you setup/use MagicalRecord:
```objective-c
- (void)theMethodWhereYouSetupMagicalRecord
{
[MagicalRecord enableShorthandMethods];
// Setup MagicalRecord as per usual
}
```
**Please note that we do not offer support for this feature**. If it doesn't work, [please file an issue](https://github.com/magicalpanda/MagicalRecord/issues/new) and we'll fix it when we can.

Просмотреть файл

@ -1,44 +0,0 @@
## Logging
MagicalRecord has logging built in to most of its interactions with Core Data. When errors occur during fetching or saving data, these errors are captured and (if you've enabled them) logged to the console.
Logging is configured to output debugging messages (**MagicalRecordLoggingLevelDebug**) by default in debug builds, and will output error messages (**MagicalRecordLoggingLevelError**) in release builds.
Logging can be configured by calling `[MagicalRecord setLoggingLevel:];` using one of the predefined logging levels:
- **MagicalRecordLogLevelOff**: Don't log anything
- **MagicalRecordLoggingLevelError**: Log all errors
- **MagicalRecordLoggingLevelWarn**: Log warnings and errors
- **MagicalRecordLoggingLevelInfo**: Log informative, warning and error messages
- **MagicalRecordLoggingLevelDebug**: Log all debug, informative, warning and error messages
- **MagicalRecordLoggingLevelVerbose**: Log verbose diagnostic, informative, warning and error messages
The logging level defaults to `MagicalRecordLoggingLevelWarn`.
## CocoaLumberjack
If it's available, MagicalRecord will direct its logs to [CocoaLumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack). All you need to do is make sure you've imported CocoaLumberjack before you import MagicalRecord, like so:
```objective-c
// Objective-C
#import <CocoaLumberjack/CocoaLumberjack.h>
#import <MagicalRecord/MagicalRecord.h>
```
```swift
// Swift
import CocoaLumberjack
import MagicalRecord
```
## Disabling Logging Completely
For most people this should be unnecessary. Setting the logging level to **MagicalRecordLogLevelOff** will ensure that no logs are printed.
Even when using `MagicalRecordLogLevelOff`, a very quick check may be performed whenever a log call is made. If you absolutely need to disable the logging, you will need to define the following when compiling MagicalRecord:
```objective-c
#define MR_LOGGING_DISABLED 1
```
Please note that this will only work if you've added MagicalRecord's source to your own project. You can also add this to the MagicalRecord project's `OTHER_CFLAGS` as `-DMR_LOGGING_DISABLED=1`.

Просмотреть файл

@ -1,9 +0,0 @@
# Resources
The following articles highlight how to install and use aspects of MagicalRecord:
* [How to make Programming with Core Data Pleasant](http://yannickloriot.com/2012/03/magicalrecord-how-to-make-programming-with-core-data-pleasant/)
* [Using Core Data with MagicalRecord](http://ablfx.com/blog/2012/03/using-coredata-magicalrecord/)
* [Super Happy Easy Fetching in Core Data](http://www.cimgf.com/2011/03/13/super-happy-easy-fetching-in-core-data/)
* [Core Data and Threads, without the Headache](http://www.cimgf.com/2011/05/04/core-data-and-threads-without-the-headache/)
* [Unit Testing with Core Data](http://www.cimgf.com/2012/05/15/unit-testing-with-core-data/)

Просмотреть файл

@ -1,148 +0,0 @@
# Saving Entities
## When should I save?
In general, your app should save to it's persistent store(s) when data changes. Some applications choose to save on application termination, however this shouldn't be necessary in most circumstances — in fact, **if you're only saving when your app terminates, you're risking data loss**! What happens if your app crashes? The user will lose all the changes they've made — that's a terrible experience, and easily avoided.
If you find that saving is taking a long time, there are a couple of things you should consider doing:
1. **Save in a background thread**: MagicalRecord provides a simple, clean API for making changes to your entities and subsequently saving them in a background thread — for example:
````objective-c
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
// Do your work to be saved here, against the `localContext` instance
// Everything you do in this block will occur on a background thread
} completion:^(BOOL success, NSError *error) {
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
````
2. **Break the task down into smaller saves**: tasks like importing large amounts of data should always be broken down into smaller chunks. There's no one-size-fits all rule for how much data you should be saving in one go, so you'll need to measure your application's performance using a tool like Apple's Instruments and tune appropriately.
## Handling Long-running Saves
### On iOS
When an application terminates on iOS, it is given a small window of opportunity to tidy up and save any data to disk. If you know that a save operation is likely to take a while, the best approach is to request an extension to your application's expiration, like so:
````objective-c
UIApplication *application = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
// Do your work to be saved here
} completion:^(BOOL success, NSError *error) {
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
````
Be sure to carefully [read the documentation for `beginBackgroundTaskWithExpirationHandler`](https://developer.apple.com/library/iOS/documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/beginBackgroundTaskWithExpirationHandler:), as inappropriately or unnecessarily extending your application's lifetime may earn your app a rejection from the App Store.
### On OS X
On OS X Mavericks (10.9) and later, App Nap can cause your application to act as though it is effectively terminated when it is in the background. If you know that a save operation is likely to take a while, the best approach is to disable automatic and sudden termination temporarily (assuming that your app supports these features):
````objective-c
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
[processInfo disableSuddenTermination];
[processInfo disableAutomaticTermination:@"Application is currently saving to persistent store"];
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
// Do your work to be saved here
} completion:^(BOOL success, NSError *error) {
[processInfo enableSuddenTermination];
[processInfo enableAutomaticTermination:@"Application has finished saving to the persistent store"];
}];
````
As with the iOS approach, be sure to [read the documentation on NSProcessInfo](https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/Classes/NSProcessInfo_Class/Reference/Reference.html) before implementing this approach in your app.
---
## Changes to saving in MagicalRecord 2.3.0
### Context For Current Thread Deprecation
In earlier releases of MagicalRecord, we provided methods to retrieve the managed object context for the thread that the method was called on. Unfortunately, **it's not possible to return the context for the currently executing thread in a reliable manner** anymore. Grand Central Dispatch (GCD) makes no guarantees that a queue will be executed on a single thread, and our approach was based upon the older NSThread API while CoreData has transitioned to use GCD. For more details, please see Saul's post "[Why contextForCurrentThread Doesn't Work in MagicalRecord](http://saulmora.com/2013/09/15/why-contextforcurrentthread-doesn-t-work-in-magicalrecord/)".
In MagicalRecord 2.3.0, we continue to use `+MR_contextForCurrentThread` internally in a few places to maintain compatibility with older releases. These methods are deprecated, and you will be warned if you use them.
In particular, **do not use `+MR_contextForCurrentThread` from within any of the `+[MagicalRecord saveWithBlock:…]` methods — the returned context may not be correct!**
If you'd like to begin preparing for the change now, please use the method variants that accept a "context" parameter, and use the context that's passed to you in the `+[MagicalRecord saveWithBlock:…]` method block. Instead of:
```objective-c
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntity];
// …
}];
```
You should now use:
```objective-c
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntityInContext:localContext];
// …
}];
```
**When MagicalRecord 3.0 is released, the context for current thread methods will be removed entirely**. The methods that do not accept a "context" parameter will move to using the default context of the default stack — please see the MagicalRecord 3.0 release notes for more details.
---
## Changes to saving in MagicalRecord 2.2.0
In MagicalRecord 2.2, the APIs for saving were revised to behave more consistently, and also to follow naming patterns present in Core Data. Extensive work has gone into adding automated tests that ensure the save methods (both new and deprecated) continue to work as expected through future updates.
`MR_save` has been temporarily restored to it's original state of running synchronously on the current thread, and saving to the persistent store. However, the __`MR_save` method is marked as deprecated and will be removed in the next major release of MagicalRecord (version 3.0)__. You should use `MR_saveToPersistentStoreAndWait` if you want the same behaviour in future versions of the library.
### New Methods
The following methods have been added:
#### NSManagedObjectContext+MagicalSaves
- `- (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;`
- `- (void) MR_saveToPersistentStoreWithCompletion:(MRSaveCompletionHandler)completion;`
- `- (void) MR_saveOnlySelfAndWait;`
- `- (void) MR_saveToPersistentStoreAndWait;`
- `- (void) MR_saveWithOptions:(MRSaveContextOptions)mask completion:(MRSaveCompletionHandler)completion;`
#### __MagicalRecord+Actions__
- `+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;`
- `+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;`
- `+ (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block;`
- `+ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;`
- `+ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;`
### Deprecations
The following methods have been deprecated in favour of newer alternatives, and will be removed in MagicalRecord 3.0:
#### NSManagedObjectContext+MagicalSaves
- `- (void) MR_save;`
- `- (void) MR_saveWithErrorCallback:(void(^)(NSError *error))errorCallback;`
- `- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;`
- `- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback;`
- `- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;`
- `- (void) MR_saveNestedContexts;`
- `- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback;`
- `- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;`
### MagicalRecord+Actions
- `+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;`
- `+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block;`
- `+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion;`
- `+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler;`

Просмотреть файл

@ -1,64 +0,0 @@
## Performing Core Data operations on Threads
MagicalRecord also provides some handy methods to set up background context for use with threading. The background saving operations are inspired by the UIView animation block methods, with few minor differences:
* The block in which you add your data saving code will never be on the main thread.
* a single NSManagedObjectContext is provided for your operations.
For example, if we have Person entity, and we need to set the firstName and lastName fields, this is how you would use MagicalRecord to setup a background context for your use:
```objective-c
Person *person; // Retrieve person entity
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
Person *localPerson = [person MR_inContext:localContext];
localPerson.firstName = @"John";
localPerson.lastName = @"Appleseed";
}];
```
In this method, the specified block provides you with the proper context in which to perform your operations, you don't need to worry about setting up the context so that it tells the Default Context that it's done, and should update because changes were performed on another thread.
To perform an action after this save block is completed, you can fill in a completion block:
```objective-c
Person *person; // Retrieve person entity
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
Person *localPerson = [person MR_inContext:localContext];
localPerson.firstName = @"John";
localPerson.lastName = @"Appleseed";
} completion:^(BOOL success, NSError *error) {
self.everyoneInTheDepartment = [Person findAll];
}];
```
This completion block is called on the main thread (queue), so this is also safe for triggering UI updates.
### Perform blocks synchronously
If you want to have your code wait until the save block is done, use `[MagicalRecord saveWithBlockAndWait:]`.
## Creating custom contexts
If you need to create a custom context, you can do so by using `[NSManagedObjectContext MR_context];`. This will return a new context of type `NSPrivateQueueConcurrencyType`, with the root saving context as it's parent.
To perform operations on the context's queue, use `[context performBlock:]` or `[context performBlockAndWait:]`.
To save the context, you can use one of the following:
* `[context MR_saveOnlySelfWithCompletion:]` - Save asynchronously to self and it's parent, but not to the persistent store
* `[context MR_saveToPersistentStoreWithCompletion:]` - Save asynchronously all the way down to the persistent store
* `[context MR_saveOnlySelfAndWait]` - Save synchronously to self and it's parent, but not to the persistent store
* `[context MR_saveToPersistentStoreAndWait]` - Save synchronously all the way down to the persistent store
## Debugging Core Data threading-related issues
You can enable core data threading assertions by adding `-com.apple.CoreData.ConcurrencyDebug 1` to your scheme's launch parameters. This will stop your app and open the debugger every time your app tries to do a context operation on the wrong thread. This is very helpful, especially in finding bugs that are rare and hard to reproduce.
More info on this can be found in the "225 - What's New in Core Data" session from WWDC 2014.

Просмотреть файл

@ -1,85 +0,0 @@
# Working with Managed Object Contexts
## Creating New Contexts
A variety of simple class methods are provided to help you create new contexts:
- `+ [NSManagedObjectContext MR_newContext]`: Sets the default context as it's parent context. Has a concurrency type of **NSPrivateQueueConcurrencyType**.
- `+ [NSManagedObjectContext MR_newMainQueueContext]`: Has a concurrency type of **NSMainQueueConcurrencyType**.
- `+ [NSManagedObjectContext MR_newPrivateQueueContext]`: Has a concurrency type of **NSPrivateQueueConcurrencyType**.
- `+ [NSManagedObjectContext MR_newContextWithParent:…]`: Allows you to specify the parent context that will be set. Has a concurrency type of **NSPrivateQueueConcurrencyType**.
- `+ [NSManagedObjectContext MR_newContextWithStoreCoordinator:…]`: Allows you to specify the persistent store coordinator for the new context. Has a concurrency type of **NSPrivateQueueConcurrencyType**.
## The Default Context
When working with Core Data, you will regularly deal with two main objects: `NSManagedObject` and `NSManagedObjectContext`.
MagicalRecord provides a simple class method to retrieve a default `NSManagedObjectContext` that can be used throughout your app. This context operates on the main thread, and is great for simple, single-threaded apps.
To access the default context, call:
```objective-c
NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext];
```
This context will be used throughout MagicalRecord in any method that uses a context, but does not provde a specific managed object context parameter.
If you need to create a new managed object context for use in non-main threads, use the following method:
```objective-c
NSManagedObjectContext *myNewContext = [NSManagedObjectContext MR_newContext];
```
This will create a new managed object context which has the same object model and persistent store as the default context, but is safe for use on another thread. It automatically sets the default context as it's parent context.
If you'd like to make your `myNewContext` instance the default for all fetch requests, use the following class method:
```objective-c
[NSManagedObjectContext MR_setDefaultContext:myNewContext];
```
> **NOTE:** It is *highly* recommended that the default context is created and set on the main thread using a managed object context with a concurrency type of `NSMainQueueConcurrencyType`.
## Performing Work on Background Threads
MagicalRecord provides methods to set up and work with contexts for use in background threads. The background saving operations are inspired by the UIView animation block methods, with a few minor differences:
* The block in which you make changes to your entities will never be executed on the main thread.
* A single **NSManagedObjectContext** is provided for you within these blocks.
For example, if we have Person entity, and we need to set the firstName and lastName fields, this is how you would use MagicalRecord to setup a background context for your use:
```objective-c
Person *person = ...;
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
Person *localPerson = [person MR_inContext:localContext];
localPerson.firstName = @"John";
localPerson.lastName = @"Appleseed";
}];
```
In this method, the specified block provides you with the proper context in which to perform your operations, you don't need to worry about setting up the context so that it tells the Default Context that it's done, and should update because changes were performed on another thread.
To perform an action after this save block is completed, you can fill in a completion block:
```objective-c
Person *person = ...;
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
Person *localPerson = [person MR_inContext:localContext];
localPerson.firstName = @"John";
localPerson.lastName = @"Appleseed";
} completion:^(BOOL success, NSError *error) {
self.everyoneInTheDepartment = [Person findAll];
}];
```
This completion block is called on the main thread (queue), so this is also safe for triggering UI updates.

Просмотреть файл

@ -1,26 +0,0 @@
Copyright (c) 2010-2015, Magical Panda Software, LLC
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:
* Link to the MagicalRecord Repository at https://github.com/magicalpanda/MagicalRecord in the credits section of your application
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
This software license is in accordance with the standard MIT License.
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.

Просмотреть файл

@ -1,35 +0,0 @@
Pod::Spec.new do |s|
s.default_subspec = 'Core'
s.name = 'MagicalRecord'
s.version = '2.3.3'
s.license = 'MIT'
s.summary = 'Super Awesome Easy Fetching for Core Data 1!!!11!!!!1!.'
s.homepage = 'http://github.com/magicalpanda/MagicalRecord'
s.author = { 'Saul Mora' => 'saul@magicalpanda.com', 'Tony Arnold' => 'tony@thecocoabots.com' }
s.source = { :git => 'https://github.com/magicalpanda/MagicalRecord.git', :tag => "v#{s.version}" }
s.description = 'Handy fetching, threading and data import helpers to make Core Data a little easier to use.'
s.requires_arc = true
s.ios.deployment_target = '6.1'
s.osx.deployment_target = '10.8'
s.subspec 'Core' do |sp|
sp.framework = 'CoreData'
sp.header_dir = 'MagicalRecord'
sp.source_files = 'MagicalRecord/**/*.{h,m}'
sp.exclude_files = '**/MagicalRecordShorthandMethodAliases.h'
sp.prefix_header_contents = <<-EOS
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecord.h>
EOS
end
s.subspec 'ShorthandMethodAliases' do |sp|
sp.source_files = '**/MagicalRecordShorthandMethodAliases.h'
end
s.subspec 'CocoaLumberjack' do |sp|
sp.dependency 'CocoaLumberjack', '~> 2.0'
sp.dependency 'MagicalRecord/Core'
end
end

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,106 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "905D073A1A63DE690076B54E"
BuildableName = "MagicalRecord.framework"
BlueprintName = "MagicalRecord for OS X"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9004F5251A94CBF900A61312"
BuildableName = "MagicalRecord for OS X Tests.xctest"
BlueprintName = "MagicalRecord for OS X Tests"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "905D073A1A63DE690076B54E"
BuildableName = "MagicalRecord.framework"
BlueprintName = "MagicalRecord for OS X"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "905D073A1A63DE690076B54E"
BuildableName = "MagicalRecord.framework"
BlueprintName = "MagicalRecord for OS X"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</MacroExpansion>
<CommandLineArguments>
<CommandLineArgument
argument = "-com.apple.CoreData.ConcurrencyDebug 1"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "905D073A1A63DE690076B54E"
BuildableName = "MagicalRecord.framework"
BlueprintName = "MagicalRecord for OS X"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -1,106 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "905D07171A63DE190076B54E"
BuildableName = "MagicalRecord.framework"
BlueprintName = "MagicalRecord for iOS"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9004F4E01A94CBCF00A61312"
BuildableName = "MagicalRecord for iOS Tests.xctest"
BlueprintName = "MagicalRecord for iOS Tests"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "905D07171A63DE190076B54E"
BuildableName = "MagicalRecord.framework"
BlueprintName = "MagicalRecord for iOS"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "905D07171A63DE190076B54E"
BuildableName = "MagicalRecord.framework"
BlueprintName = "MagicalRecord for iOS"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</MacroExpansion>
<CommandLineArguments>
<CommandLineArgument
argument = "-com.apple.CoreData.ConcurrencyDebug 1"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "905D07171A63DE190076B54E"
BuildableName = "MagicalRecord.framework"
BlueprintName = "MagicalRecord for iOS"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -1,88 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C7CF97BA1749843F008D9D13"
BuildableName = "libMagicalRecord.dylib"
BlueprintName = "libMagicalRecord for OS X"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C7CF9815174984E4008D9D13"
BuildableName = "libMagicalRecord for OS X Tests.xctest"
BlueprintName = "libMagicalRecord for OS X Tests"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C7CF97BA1749843F008D9D13"
BuildableName = "libMagicalRecord.dylib"
BlueprintName = "libMagicalRecord for OS X"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</MacroExpansion>
<CommandLineArguments>
<CommandLineArgument
argument = "-com.apple.CoreData.ConcurrencyDebug 1"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -1,88 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C7CF97AA17498414008D9D13"
BuildableName = "libMagicalRecord.a"
BlueprintName = "libMagicalRecord for iOS"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C7CF97FE174984CA008D9D13"
BuildableName = "libMagicalRecord for iOS Tests.xctest"
BlueprintName = "libMagicalRecord for iOS Tests"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C7CF97AA17498414008D9D13"
BuildableName = "libMagicalRecord.a"
BlueprintName = "libMagicalRecord for iOS"
ReferencedContainer = "container:MagicalRecord.xcodeproj">
</BuildableReference>
</MacroExpansion>
<CommandLineArguments>
<CommandLineArgument
argument = "-com.apple.CoreData.ConcurrencyDebug 1"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -1,27 +0,0 @@
//
// MagicalImportFunctions.h
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
NSDate * __MR_nonnull MR_adjustDateForDST(NSDate *__MR_nonnull date);
NSDate * __MR_nonnull MR_dateFromString(NSString *__MR_nonnull value, NSString *__MR_nonnull format);
NSDate * __MR_nonnull MR_dateFromNumber(NSNumber *__MR_nonnull value, BOOL milliseconds);
NSNumber * __MR_nonnull MR_numberFromString(NSString *__MR_nonnull value);
NSString * __MR_nonnull MR_attributeNameFromString(NSString *__MR_nonnull value);
NSString * __MR_nonnull MR_primaryKeyNameFromString(NSString *__MR_nonnull value);
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
UIColor * __MR_nullable MR_colorFromString(NSString *__MR_nonnull serializedColor);
#else
#import <AppKit/AppKit.h>
NSColor * __MR_nullable MR_colorFromString(NSString *__MR_nonnull serializedColor);
#endif
NSInteger * __MR_nullable MR_newColorComponentsFromString(NSString *__MR_nonnull serializedColor);

Просмотреть файл

@ -1,124 +0,0 @@
//
// 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 * MR_attributeNameFromString(NSString *value)
{
NSString *firstCharacter = [[value substringToIndex:1] capitalizedString];
return [firstCharacter stringByAppendingString:[value substringFromIndex:1]];
}
NSString * MR_primaryKeyNameFromString(NSString *value)
{
NSString *firstCharacter = [[value substringToIndex:1] lowercaseString];
return [firstCharacter stringByAppendingFormat:@"%@ID", [value substringFromIndex:1]];
}
NSDate * MR_adjustDateForDST(NSDate *date)
{
NSTimeInterval dstOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffsetForDate:date];
NSDate *actualDate = [date dateByAddingTimeInterval:dstOffset];
return actualDate;
}
NSDate * MR_dateFromString(NSString *value, NSString *format)
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[formatter setLocale:[NSLocale currentLocale]];
[formatter setDateFormat:format];
NSDate *parsedDate = [formatter dateFromString:value];
return parsedDate;
}
NSDate * MR_dateFromNumber(NSNumber *value, BOOL milliseconds)
{
NSTimeInterval timeInterval = [value doubleValue];
if (milliseconds) {
timeInterval = timeInterval / 1000.00;
}
return [NSDate dateWithTimeIntervalSince1970:timeInterval];
}
NSNumber * MR_numberFromString(NSString *value) {
return [NSNumber numberWithDouble:[value doubleValue]];
}
NSInteger* MR_newColorComponentsFromString(NSString *serializedColor)
{
NSScanner *colorScanner = [NSScanner scannerWithString:serializedColor];
NSString *colorType;
[colorScanner scanUpToString:@"(" intoString:&colorType];
NSInteger *componentValues = malloc(4 * sizeof(NSInteger));
if (componentValues == NULL)
{
return NULL;
}
if ([colorType hasPrefix:@"rgba"])
{
NSCharacterSet *rgbaCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"(,)"];
NSInteger *componentValue = componentValues;
while (![colorScanner isAtEnd])
{
[colorScanner scanCharactersFromSet:rgbaCharacterSet intoString:nil];
[colorScanner scanInteger:componentValue];
componentValue++;
}
}
return componentValues;
}
#if TARGET_OS_IPHONE
UIColor * MR_colorFromString(NSString *serializedColor)
{
NSInteger *componentValues = MR_newColorComponentsFromString(serializedColor);
if (componentValues == NULL)
{
return nil;
}
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;
}
#else
NSColor * MR_colorFromString(NSString *serializedColor)
{
NSInteger *componentValues = MR_newColorComponentsFromString(serializedColor);
if (componentValues == NULL)
{
return nil;
}
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;
}
#endif

Просмотреть файл

@ -1,17 +0,0 @@
//
// NSAttributeDescription+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSAttributeDescription (MagicalRecord_DataImport)
- (MR_nullable NSString *) MR_primaryKey;
- (MR_nullable id) MR_valueForKeyPath:(MR_nonnull NSString *)keyPath fromObjectData:(MR_nonnull id)objectData;
@end

Просмотреть файл

@ -1,73 +0,0 @@
//
// 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] objectForKey:kMagicalRecordImportAttributeValueClassNameKey];
if (desiredAttributeType)
{
if ([desiredAttributeType hasSuffix:@"Color"])
{
value = MR_colorFromString(value);
}
}
else
{
if (attributeType == NSDateAttributeType)
{
if (![value isKindOfClass:[NSDate class]])
{
NSString *dateFormat = [[self userInfo] objectForKey:kMagicalRecordImportCustomDateFormatKey];
if ([value isKindOfClass:[NSNumber class]]) {
value = MR_dateFromNumber(value, [dateFormat isEqualToString:kMagicalRecordImportUnixTimeString]);
}
else {
value = MR_dateFromString([value description], dateFormat ?: kMagicalRecordImportDefaultDateFormatString);
}
}
}
else if (attributeType == NSInteger16AttributeType ||
attributeType == NSInteger32AttributeType ||
attributeType == NSInteger64AttributeType ||
attributeType == NSDecimalAttributeType ||
attributeType == NSDoubleAttributeType ||
attributeType == NSFloatAttributeType) {
if (![value isKindOfClass:[NSNumber class]] && value != [NSNull null]) {
value = MR_numberFromString([value description]);
}
}
else if (attributeType == NSBooleanAttributeType) {
if (![value isKindOfClass:[NSNumber class]] && value != [NSNull null]) {
value = [NSNumber numberWithBool:[value boolValue]];
}
}
else if (attributeType == NSStringAttributeType) {
if (![value isKindOfClass:[NSString class]] && value != [NSNull null]) {
value = [value description];
}
}
}
return value == [NSNull null] ? nil : value;
}
@end

Просмотреть файл

@ -1,28 +0,0 @@
//
// NSEntityDescription+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/5/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSEntityDescription (MagicalRecord_DataImport)
- (MR_nullable NSAttributeDescription *) MR_primaryAttributeToRelateBy;
- (MR_nonnull NSManagedObject *) MR_createInstanceInContext:(MR_nonnull NSManagedObjectContext *)context;
/**
* Safely returns an attribute description for the given name, otherwise returns nil. In certain circumstances, the keys of the dictionary returned by `attributesByName` are not standard NSStrings and won't match using object subscripting or standard `objectForKey:` lookups.
*
* There may be performance implications to using this method if your entity has hundreds or thousands of attributes.
*
* @param name Name of the attribute description in the `attributesByName` dictionary on this instance
*
* @return The attribute description for the given name, otherwise nil
*/
- (MR_nullable NSAttributeDescription *) MR_attributeDescriptionForName:(MR_nonnull NSString *)name;
@end

Просмотреть файл

@ -1,63 +0,0 @@
//
// NSEntityDescription+MagicalDataImport.m
// Magical Record
//
// Created by Saul Mora on 9/5/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import "NSEntityDescription+MagicalDataImport.h"
#import "NSManagedObject+MagicalDataImport.h"
#import "NSManagedObject+MagicalRecord.h"
#import "MagicalImportFunctions.h"
#import "MagicalRecordLogging.h"
@implementation NSEntityDescription (MagicalRecord_DataImport)
- (NSAttributeDescription *) MR_primaryAttributeToRelateBy;
{
NSString *lookupKey = [[self userInfo] objectForKey:kMagicalRecordImportRelationshipLinkedByKey] ?: MR_primaryKeyNameFromString([self name]);
NSAttributeDescription *attributeDescription = [self MR_attributeDescriptionForName:lookupKey];
if (attributeDescription == nil)
{
MRLogError(
@"Invalid value for key '%@' in '%@' entity. Remove this key or add attribute '%@'\n",
kMagicalRecordImportRelationshipLinkedByKey,
self.name,
lookupKey);
}
return attributeDescription;
}
- (NSManagedObject *) MR_createInstanceInContext:(NSManagedObjectContext *)context;
{
Class relatedClass = NSClassFromString([self managedObjectClassName]);
NSManagedObject *newInstance = [relatedClass MR_createEntityInContext:context];
return newInstance;
}
- (NSAttributeDescription *) MR_attributeDescriptionForName:(NSString *)name;
{
__block NSAttributeDescription *attributeDescription;
NSDictionary *attributesByName = [self attributesByName];
if ([attributesByName count] == 0) {
return nil;
}
[attributesByName enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([key isEqualToString:name]) {
attributeDescription = obj;
*stop = YES;
}
}];
return attributeDescription;
}
@end

Просмотреть файл

@ -1,18 +0,0 @@
//
// NSNumber+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSNumber (MagicalRecord_DataImport)
- (MR_nullable NSString *)MR_lookupKeyForAttribute:(MR_nonnull NSAttributeDescription *)attributeInfo;
- (MR_nonnull id)MR_relatedValueForRelationship:(MR_nonnull NSRelationshipDescription *)relationshipInfo;
@end

Просмотреть файл

@ -1,23 +0,0 @@
//
// 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)
- (NSString *)MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo
{
return nil;
}
- (id)MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo
{
return self;
}
@end

Просмотреть файл

@ -1,21 +0,0 @@
//
// NSDictionary+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSObject (MagicalRecord_DataImport)
- (MR_nullable NSString *) MR_lookupKeyForAttribute:(MR_nonnull NSAttributeDescription *)attributeInfo;
- (MR_nullable id) MR_valueForAttribute:(MR_nonnull NSAttributeDescription *)attributeInfo;
- (MR_nullable NSString *) MR_lookupKeyForRelationship:(MR_nonnull NSRelationshipDescription *)relationshipInfo;
- (MR_nullable id) MR_relatedValueForRelationship:(MR_nonnull NSRelationshipDescription *)relationshipInfo;
@end

Просмотреть файл

@ -1,70 +0,0 @@
//
// 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 "NSAttributeDescription+MagicalDataImport.h"
#import "NSEntityDescription+MagicalDataImport.h"
#import "NSManagedObject+MagicalDataImport.h"
#import "NSRelationshipDescription+MagicalDataImport.h"
#import "MagicalRecordLogging.h"
NSUInteger const kMagicalRecordImportMaximumAttributeFailoverDepth = 10;
@implementation NSObject (MagicalRecord_DataImport)
- (NSString *) MR_lookupKeyForAttribute:(NSAttributeDescription *)attributeInfo;
{
NSString *attributeName = [attributeInfo name];
NSString *lookupKey = [[attributeInfo userInfo] objectForKey: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] objectForKey: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)
{
MRLogError(@"Unable to find entity for type '%@'", [self valueForKey:kMagicalRecordImportRelationshipTypeKey]);
return nil;
}
NSString *primaryKeyName = [relationshipInfo MR_primaryKey];
NSAttributeDescription *primaryKeyAttribute = [destinationEntity MR_attributeDescriptionForName:primaryKeyName];
NSString *lookupKey = [self MR_lookupKeyForAttribute:primaryKeyAttribute] ?: [primaryKeyAttribute name];
return lookupKey;
}
- (id) MR_relatedValueForRelationship:(NSRelationshipDescription *)relationshipInfo
{
NSString *lookupKey = [self MR_lookupKeyForRelationship:relationshipInfo];
return lookupKey ? [self valueForKeyPath:lookupKey] : nil;
}
@end

Просмотреть файл

@ -1,16 +0,0 @@
//
// NSRelationshipDescription+MagicalDataImport.h
// Magical Record
//
// Created by Saul Mora on 9/4/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSRelationshipDescription (MagicalRecord_DataImport)
- (MR_nonnull NSString *) MR_primaryKey;
@end

Просмотреть файл

@ -1,23 +0,0 @@
//
// 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"
@implementation NSRelationshipDescription (MagicalRecord_DataImport)
- (NSString *) MR_primaryKey;
{
NSString *primaryKeyName = [[self userInfo] objectForKey:kMagicalRecordImportRelationshipLinkedByKey] ?:
MR_primaryKeyNameFromString([[self destinationEntity] name]);
return primaryKeyName;
}
@end

Просмотреть файл

@ -1,17 +0,0 @@
//
// 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 <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSString (MagicalRecord_DataImport)
- (MR_nonnull NSString *) MR_capitalizedFirstCharacterString;
@end

Просмотреть файл

@ -1,35 +0,0 @@
//
// 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

Просмотреть файл

@ -1,69 +0,0 @@
//
// NSManagedObject+MagicalAggregation.h
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObject (MagicalAggregation)
+ (MR_nonnull NSNumber *) MR_numberOfEntities;
+ (MR_nonnull NSNumber *) MR_numberOfEntitiesWithContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSNumber *) MR_numberOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSNumber *) MR_numberOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (NSUInteger) MR_countOfEntities;
+ (NSUInteger) MR_countOfEntitiesWithContext:(MR_nonnull NSManagedObjectContext *)context;
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchFilter;
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchFilter inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (BOOL) MR_hasAtLeastOneEntity;
+ (BOOL) MR_hasAtLeastOneEntityInContext:(MR_nonnull NSManagedObjectContext *)context;
- (MR_nullable id) MR_minValueFor:(MR_nonnull NSString *)property;
- (MR_nullable id) MR_maxValueFor:(MR_nonnull NSString *)property;
+ (MR_nullable id) MR_aggregateOperation:(MR_nonnull NSString *)function onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable id) MR_aggregateOperation:(MR_nonnull NSString *)function onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate;
/**
* Supports aggregating values using a key-value collection operator that can be grouped by an attribute.
* See https://developer.apple.com/library/ios/documentation/cocoa/conceptual/KeyValueCoding/Articles/CollectionOperators.html for a list of valid collection operators.
*
* @since 2.3.0
*
* @param collectionOperator Collection operator
* @param attributeName Entity attribute to apply the collection operator to
* @param predicate Predicate to filter results
* @param groupingKeyPath Key path to group results by
* @param context Context to perform the request in
*
* @return Results of the collection operator, filtered by the provided predicate and grouped by the provided key path
*/
+ (MR_nullable NSArray *) MR_aggregateOperation:(MR_nonnull NSString *)collectionOperator onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate groupBy:(MR_nullable NSString*)groupingKeyPath inContext:(MR_nonnull NSManagedObjectContext *)context;
/**
* Supports aggregating values using a key-value collection operator that can be grouped by an attribute.
* See https://developer.apple.com/library/ios/documentation/cocoa/conceptual/KeyValueCoding/Articles/CollectionOperators.html for a list of valid collection operators.
*
* This method is run against the default MagicalRecordStack's context.
*
* @since 2.3.0
*
* @param collectionOperator Collection operator
* @param attributeName Entity attribute to apply the collection operator to
* @param predicate Predicate to filter results
* @param groupingKeyPath Key path to group results by
*
* @return Results of the collection operator, filtered by the provided predicate and grouped by the provided key path
*/
+ (MR_nullable NSArray *) MR_aggregateOperation:(MR_nonnull NSString *)collectionOperator onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate groupBy:(MR_nullable NSString*)groupingKeyPath;
- (MR_nullable instancetype) MR_objectWithMinValueFor:(MR_nonnull NSString *)property;
- (MR_nullable instancetype) MR_objectWithMinValueFor:(MR_nonnull NSString *)property inContext:(MR_nonnull NSManagedObjectContext *)context;
@end

Просмотреть файл

@ -1,199 +0,0 @@
//
// 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 "NSEntityDescription+MagicalDataImport.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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_numberOfEntitiesWithContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSNumber *) MR_numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
return [NSNumber numberWithUnsignedInteger:[self MR_countOfEntitiesWithPredicate:searchTerm inContext:context]];
}
+ (NSNumber *) MR_numberOfEntitiesWithPredicate:(NSPredicate *)searchTerm;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_numberOfEntitiesWithPredicate:searchTerm
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSUInteger) MR_countOfEntities;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_countOfEntitiesWithContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSUInteger) MR_countOfEntitiesWithContext:(NSManagedObjectContext *)context;
{
return [self MR_countOfEntitiesWithPredicate:nil inContext:context];
}
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_countOfEntitiesWithPredicate:searchFilter inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSUInteger) MR_countOfEntitiesWithPredicate:(NSPredicate *)searchFilter inContext:(NSManagedObjectContext *)context;
{
NSError *error = nil;
NSFetchRequest *request = [self MR_createFetchRequestInContext:context];
if (searchFilter)
{
[request setPredicate:searchFilter];
}
NSUInteger count = [context countForFetchRequest:request error:&error];
[MagicalRecord handleErrors:error];
return count;
}
+ (BOOL) MR_hasAtLeastOneEntity
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_hasAtLeastOneEntityInContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (BOOL) MR_hasAtLeastOneEntityInContext:(NSManagedObjectContext *)context
{
return [[self MR_numberOfEntitiesWithContext:context] intValue] > 0;
}
- (id) MR_minValueFor:(NSString *)property
{
NSManagedObject *obj = [[self class] MR_findFirstByAttribute:property
withValue:[NSString stringWithFormat:@"min(%@)", property]];
return [obj valueForKey:property];
}
- (id) 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]];
}
+ (id) 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_entityDescriptionInContext:context] MR_attributeDescriptionForName: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];
return [resultsDictionary objectForKey:@"result"];
}
+ (id) MR_aggregateOperation:(NSString *)function onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_aggregateOperation:function
onAttribute:attributeName
withPredicate:predicate
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSArray *) MR_aggregateOperation:(NSString *)collectionOperator onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate groupBy:(NSString *)groupingKeyPath inContext:(NSManagedObjectContext *)context;
{
NSExpression *expression = [NSExpression expressionForFunction:collectionOperator arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:attributeName]]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName:@"result"];
[expressionDescription setExpression:expression];
NSAttributeDescription *attributeDescription = [[[self MR_entityDescriptionInContext:context] attributesByName] objectForKey:attributeName];
[expressionDescription setExpressionResultType:[attributeDescription attributeType]];
NSArray *properties = @[groupingKeyPath, expressionDescription];
NSFetchRequest *fetchRequest = [self MR_requestAllWithPredicate:predicate inContext:context];
[fetchRequest setPropertiesToFetch:properties];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setPropertiesToGroupBy:@[groupingKeyPath]];
NSArray *results = [self MR_executeFetchRequest:fetchRequest inContext:context];
return results;
}
+ (NSArray *) MR_aggregateOperation:(NSString *)collectionOperator onAttribute:(NSString *)attributeName withPredicate:(NSPredicate *)predicate groupBy:(NSString *)groupingKeyPath;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_aggregateOperation:collectionOperator
onAttribute:attributeName
withPredicate:predicate groupBy:groupingKeyPath
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
@end

Просмотреть файл

@ -1,40 +0,0 @@
//
// NSManagedObject+JSONHelpers.h
//
// Created by Saul Mora on 6/28/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportCustomDateFormatKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportDefaultDateFormatString;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportUnixTimeString;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportAttributeKeyMapKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportAttributeValueClassNameKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportRelationshipMapKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportRelationshipLinkedByKey;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordImportRelationshipTypeKey;
@protocol MagicalRecordDataImportProtocol <NSObject>
@optional
- (BOOL) shouldImport:(MR_nonnull id)data;
- (void) willImport:(MR_nonnull id)data;
- (void) didImport:(MR_nonnull id)data;
@end
@interface NSManagedObject (MagicalRecord_DataImport) <MagicalRecordDataImportProtocol>
- (BOOL) MR_importValuesForKeysWithObject:(MR_nonnull id)objectData;
+ (MR_nonnull instancetype) MR_importFromObject:(MR_nonnull id)data;
+ (MR_nonnull instancetype) MR_importFromObject:(MR_nonnull id)data inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull MR_NSArrayOfNSManagedObjects) MR_importFromArray:(MR_nonnull MR_GENERIC(NSArray, NSDictionary *) *)listOfObjectData;
+ (MR_nonnull MR_NSArrayOfNSManagedObjects) MR_importFromArray:(MR_nonnull MR_GENERIC(NSArray, NSDictionary *) *)listOfObjectData inContext:(MR_nonnull NSManagedObjectContext *)context;
@end

Просмотреть файл

@ -1,359 +0,0 @@
//
// NSManagedObject+JSONHelpers.m
//
// Created by Saul Mora on 6/28/11.
// Copyright 2011 Magical Panda Software LLC. All rights reserved.
//
#import "NSObject+MagicalDataImport.h"
#import "NSAttributeDescription+MagicalDataImport.h"
#import "NSEntityDescription+MagicalDataImport.h"
#import "NSManagedObjectContext+MagicalThreading.h"
#import "NSManagedObject+MagicalDataImport.h"
#import "NSManagedObject+MagicalFinders.h"
#import "NSManagedObject+MagicalRecord.h"
#import "NSRelationshipDescription+MagicalDataImport.h"
#import "NSString+MagicalDataImport.h"
#import "MagicalImportFunctions.h"
#import "MagicalRecordLogging.h"
#import <objc/runtime.h>
NSString * const kMagicalRecordImportCustomDateFormatKey = @"dateFormat";
NSString * const kMagicalRecordImportDefaultDateFormatString = @"yyyy-MM-dd'T'HH:mm:ssz";
NSString * const kMagicalRecordImportUnixTimeString = @"UnixTime";
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";
@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])
{
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]];
[invocation setTarget:self];
[invocation setSelector:selector];
[invocation setArgument:&value atIndex:2];
[invocation invoke];
BOOL returnValue = YES;
[invocation getReturnValue:&returnValue];
return returnValue;
}
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;
// if its a primitive class, than handle singleRelatedObjectData as the key for relationship
if ([singleRelatedObjectData isKindOfClass:[NSString class]] ||
[singleRelatedObjectData isKindOfClass:[NSNumber class]])
{
relatedValue = singleRelatedObjectData;
}
else if ([singleRelatedObjectData isKindOfClass:[NSDictionary class]])
{
relatedValue = [singleRelatedObjectData MR_relatedValueForRelationship:relationshipInfo];
}
else
{
relatedValue = singleRelatedObjectData;
}
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] isKindOfEntity:[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"];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
relationshipSource = [self performSelector:NSSelectorFromString(selectorName)];
#pragma clang diagnostic pop
addRelationMessageFormat = @"addObject:";
}
}
NSString *addRelatedObjectToSetMessage = [NSString stringWithFormat:addRelationMessageFormat, MR_attributeNameFromString([relationshipInfo name])];
SEL selector = NSSelectorFromString(addRelatedObjectToSetMessage);
@try
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[relationshipSource performSelector:selector withObject:relatedObject];
#pragma clang diagnostic pop
}
@catch (NSException *exception)
{
MRLogError(@"Adding object for relationship failed: %@\n", relationshipInfo);
MRLogError(@"relatedObject.entity %@", [relatedObject entity]);
MRLogError(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]);
MRLogError(@"Add Relationship Selector: %@", addRelatedObjectToSetMessage);
MRLogError(@"perform selector error: %@", exception);
}
}
- (void)MR_setRelationships:(NSDictionary *)relationships forKeysWithObject:(id)relationshipData withBlock:(void (^)(NSRelationshipDescription *, id))setRelationshipBlock
{
for (NSString *relationshipName in relationships)
{
SEL shouldImportSelector = NSSelectorFromString([NSString stringWithFormat:@"shouldImport%@:", [relationshipName MR_capitalizedFirstCharacterString]]);
BOOL implementsShouldImport = (BOOL)[self respondsToSelector:shouldImportSelector];
NSRelationshipDescription *relationshipInfo = [relationships valueForKey:relationshipName];
NSString *lookupKey = [[relationshipInfo userInfo] objectForKey:kMagicalRecordImportRelationshipMapKey] ?: relationshipName;
id relatedObjectData;
@try
{
relatedObjectData = [relationshipData valueForKeyPath:lookupKey];
}
@catch (NSException *exception)
{
MRLogWarn(@"Looking up a key for relationship failed while importing: %@\n", relationshipInfo);
MRLogWarn(@"lookupKey: %@", lookupKey);
MRLogWarn(@"relationshipInfo.destinationEntity %@", [relationshipInfo destinationEntity]);
MRLogWarn(@"relationshipData: %@", relationshipData);
MRLogWarn(@"Exception:\n%@: %@", [exception name], [exception reason]);
}
@finally
{
if (relatedObjectData == nil || [relatedObjectData isEqual:[NSNull null]])
{
continue;
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored \
"-Warc-performSelector-leaks"
if (implementsShouldImport && !(BOOL)[self performSelector:shouldImportSelector withObject:relatedObjectData])
{
continue;
}
#pragma clang diagnostic pop
// Different values provided to the -shouldImport and -import methods??
if ([self MR_importValue:relationshipData forKey:relationshipName])
{
continue;
}
if ([relationshipInfo isToMany] && [relatedObjectData isKindOfClass:[NSArray class]])
{
for (id singleRelatedObjectData in relatedObjectData)
{
setRelationshipBlock(relationshipInfo, singleRelatedObjectData);
}
}
else
{
setRelationshipBlock(relationshipInfo, relatedObjectData);
}
}
}
- (BOOL) MR_preImport:(id)objectData;
{
if ([self respondsToSelector:@selector(shouldImport:)])
{
BOOL shouldImport = (BOOL)[self shouldImport:objectData];
if (!shouldImport)
{
return NO;
}
}
if ([self respondsToSelector:@selector(willImport:)])
{
[self willImport:objectData];
}
return YES;
}
- (BOOL) MR_postImport:(id)objectData;
{
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
{
__weak 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]];
}
if ([localObjectData isKindOfClass:[NSDictionary class]])
{
[relatedObject MR_importValuesForKeysWithObject:localObjectData];
}
else if (localObjectData)
{
NSString *relatedByAttribute = [relationshipInfo MR_primaryKey];
if (relatedByAttribute)
{
if (![relatedObject MR_importValue:localObjectData forKey:relatedByAttribute])
{
[relatedObject setValue:localObjectData forKey:relatedByAttribute];
}
}
}
[weakself MR_addObject:relatedObject forRelationship:relationshipInfo];
}];
}
+ (id) MR_importFromObject:(id)objectData inContext:(NSManagedObjectContext *)context;
{
__block NSManagedObject *managedObject;
[context performBlockAndWait:^{
NSAttributeDescription *primaryAttribute = [[self MR_entityDescriptionInContext:context] MR_primaryAttributeToRelateBy];
if (primaryAttribute != nil)
{
id value = [objectData MR_valueForAttribute:primaryAttribute];
managedObject = [self MR_findFirstByAttribute:[primaryAttribute name] withValue:value inContext:context];
}
if (managedObject == nil)
{
managedObject = [self MR_createEntityInContext:context];
}
[managedObject MR_importValuesForKeysWithObject:objectData];
}];
return managedObject;
}
+ (id) MR_importFromObject:(id)objectData
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_importFromObject:objectData inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_importFromArray:listOfObjectData inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSArray *) MR_importFromArray:(NSArray *)listOfObjectData inContext:(NSManagedObjectContext *)context
{
NSMutableArray *dataObjects = [NSMutableArray array];
[listOfObjectData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
NSDictionary *objectData = (NSDictionary *)obj;
NSManagedObject *dataObject = [self MR_importFromObject:objectData inContext:context];
[dataObjects addObject:dataObject];
}];
return dataObjects;
}
@end

Просмотреть файл

@ -1,65 +0,0 @@
//
// NSManagedObject+MagicalFinders.h
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObject (MagicalFinders)
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAll;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findAllWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirst;
+ (MR_nullable instancetype) MR_findFirstInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchterm sortedBy:(MR_nullable NSString *)property ascending:(BOOL)ascending;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchterm sortedBy:(MR_nullable NSString *)property ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm andRetrieveAttributes:(MR_nullable NSArray *)attributes;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm andRetrieveAttributes:(MR_nullable NSArray *)attributes inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(MR_nullable id)attributes, ...;
+ (MR_nullable instancetype) MR_findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortBy ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context andRetrieveAttributes:(MR_nullable id)attributes, ...;
+ (MR_nullable instancetype) MR_findFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue;
+ (MR_nullable instancetype) MR_findFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_findFirstOrderedByAttribute:(MR_nonnull NSString *)attribute ascending:(BOOL)ascending;
+ (MR_nullable instancetype) MR_findFirstOrderedByAttribute:(MR_nonnull NSString *)attribute ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull instancetype) MR_findFirstOrCreateByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue;
+ (MR_nonnull instancetype) MR_findFirstOrCreateByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue andOrderBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue andOrderBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) MR_fetchController:(MR_nonnull NSFetchRequest *)request delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate useFileCache:(BOOL)useFileCache groupedBy:(MR_nullable NSString *)groupKeyPath inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllWithDelegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllWithDelegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllSortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm groupBy:(MR_nullable NSString *)groupingKeyPath delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllSortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm groupBy:(MR_nullable NSString *)groupingKeyPath delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate;
+ (MR_nonnull NSFetchedResultsController *) MR_fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate inContext:(MR_nonnull NSManagedObjectContext *)context;
#endif
@end

Просмотреть файл

@ -1,420 +0,0 @@
//
// 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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findAllInContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findAllSortedBy:sortTerm
ascending:ascending
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findAllWithPredicate:searchTerm
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (instancetype) MR_findFirstInContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_createFetchRequestInContext:context];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (instancetype) MR_findFirst
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findFirstInContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (instancetype) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestFirstByAttribute:attribute withValue:searchValue inContext:context];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (instancetype) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findFirstByAttribute:attribute
withValue:searchValue
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (instancetype) 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];
}
+ (instancetype) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findFirstOrderedByAttribute:attribute
ascending:ascending
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (instancetype) MR_findFirstOrCreateByAttribute:(NSString *)attribute withValue:(id)searchValue
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findFirstOrCreateByAttribute:attribute
withValue:searchValue
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (instancetype) MR_findFirstOrCreateByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context
{
id result = [self MR_findFirstByAttribute:attribute
withValue:searchValue
inContext:context];
if (result != nil) {
return result;
}
result = [self MR_createEntityInContext:context];
[result setValue:searchValue forKey:attribute];
return result;
}
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findFirstWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestFirstWithPredicate:searchTerm inContext:context];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (instancetype) 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];
}
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findFirstWithPredicate:searchterm
sortedBy:property
ascending:ascending
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (instancetype) 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];
}
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findFirstWithPredicate:searchTerm
andRetrieveAttributes:attributes
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (instancetype) 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 inContext:context]];
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:context];
}
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ...
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findFirstWithPredicate:searchTerm
sortedBy:sortBy
ascending:ascending
inContext:[NSManagedObjectContext MR_contextForCurrentThread]
andRetrieveAttributes:attributes];
#pragma clang diagnostic pop
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findByAttribute:attribute
withValue:searchValue
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_findByAttribute:attribute
withValue:searchValue
andOrderBy:sortTerm
ascending:ascending
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
#pragma mark -
#pragma mark NSFetchedResultsController helpers
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (NSFetchedResultsController *) MR_fetchController:(NSFetchRequest *)request delegate:(id<NSFetchedResultsControllerDelegate>)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<NSFetchedResultsControllerDelegate>)delegate;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_fetchAllWithDelegate:delegate inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSFetchedResultsController *) MR_fetchAllWithDelegate:(id<NSFetchedResultsControllerDelegate>)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<NSFetchedResultsControllerDelegate>)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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_fetchAllGroupedBy:group
withPredicate:searchTerm
sortedBy:sortTerm
ascending:ascending
delegate:delegate
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_fetchAllGroupedBy:group
withPredicate:searchTerm
sortedBy:sortTerm
ascending:ascending
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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:context];
[self MR_performFetch:controller];
return controller;
}
+ (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_fetchAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
groupBy:groupingKeyPath
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id<NSFetchedResultsControllerDelegate>)delegate inContext:(NSManagedObjectContext *)context
{
return [self MR_fetchAllGroupedBy:groupingKeyPath
withPredicate:searchTerm
sortedBy:sortTerm
ascending:ascending
delegate:delegate
inContext:context];
}
+ (NSFetchedResultsController *) MR_fetchAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm groupBy:(NSString *)groupingKeyPath delegate:(id<NSFetchedResultsControllerDelegate>)delegate
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_fetchAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
groupBy:groupingKeyPath
delegate:delegate
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
#endif
@end

Просмотреть файл

@ -1,75 +0,0 @@
//
//
// Created by Saul Mora on 11/15/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordDeprecationMacros.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObject (MagicalRecord)
/**
* If the NSManagedObject subclass calling this method has implemented the `entityName` method, then the return value of that will be used.
* If `entityName` is not implemented, then the name of the class is returned. If the class is written in Swift, the module name will be removed.
*
* @return String based name for the entity
*/
+ (MR_nonnull NSString *) MR_entityName;
+ (NSUInteger) MR_defaultBatchSize;
+ (void) MR_setDefaultBatchSize:(NSUInteger)newBatchSize;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_executeFetchRequest:(MR_nonnull NSFetchRequest *)request;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) MR_executeFetchRequest:(MR_nonnull NSFetchRequest *)request inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_executeFetchRequestAndReturnFirstObject:(MR_nonnull NSFetchRequest *)request;
+ (MR_nullable instancetype) MR_executeFetchRequestAndReturnFirstObject:(MR_nonnull NSFetchRequest *)request inContext:(MR_nonnull NSManagedObjectContext *)context;
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (BOOL) MR_performFetch:(MR_nonnull NSFetchedResultsController *)controller;
#endif
+ (MR_nullable NSEntityDescription *) MR_entityDescription;
+ (MR_nullable NSEntityDescription *) MR_entityDescriptionInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_GENERIC(NSArray, NSPropertyDescription *) *) MR_propertiesNamed:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)properties;
+ (MR_nullable MR_GENERIC(NSArray, NSPropertyDescription *) *) MR_propertiesNamed:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)properties inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) MR_createEntity;
+ (MR_nullable instancetype) MR_createEntityInContext:(MR_nonnull NSManagedObjectContext *)context;
- (BOOL) MR_deleteEntity;
- (BOOL) MR_deleteEntityInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (BOOL) MR_deleteAllMatchingPredicate:(MR_nonnull NSPredicate *)predicate;
+ (BOOL) MR_deleteAllMatchingPredicate:(MR_nonnull NSPredicate *)predicate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (BOOL) MR_truncateAll;
+ (BOOL) MR_truncateAllInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull MR_GENERIC(NSArray, NSSortDescriptor *) *) MR_ascendingSortDescriptors:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)attributesToSortBy;
+ (MR_nonnull MR_GENERIC(NSArray, NSSortDescriptor *) *) MR_descendingSortDescriptors:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)attributesToSortBy;
- (MR_nullable instancetype) MR_inContext:(MR_nonnull NSManagedObjectContext *)otherContext;
- (MR_nullable instancetype) MR_inThreadContext;
@end
@protocol MagicalRecord_MOGenerator <NSObject>
@optional
+ (MR_nonnull NSString *)entityName;
- (MR_nullable instancetype) entityInManagedObjectContext:(MR_nonnull NSManagedObjectContext *)object;
- (MR_nullable instancetype) insertInManagedObjectContext:(MR_nonnull NSManagedObjectContext *)object;
@end
#pragma mark - Deprecated Methods — DO NOT USE
@interface NSManagedObject (MagicalRecordDeprecated)
+ (MR_nullable instancetype) MR_createInContext:(MR_nonnull NSManagedObjectContext *)context MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_createEntityInContext:");
- (BOOL) MR_deleteInContext:(MR_nonnull NSManagedObjectContext *)context MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_deleteEntityInContext:");
@end

Просмотреть файл

@ -1,330 +0,0 @@
// Created by Saul Mora on 11/15/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import "NSManagedObject+MagicalRecord.h"
#import "NSManagedObject+MagicalRequests.h"
#import "NSManagedObjectContext+MagicalThreading.h"
#import "MagicalRecord+ErrorHandling.h"
#import "MagicalRecordLogging.h"
static NSUInteger kMagicalRecordDefaultBatchSize = 20;
@implementation NSManagedObject (MagicalRecord)
+ (NSString *) MR_entityName;
{
NSString *entityName;
if ([self respondsToSelector:@selector(entityName)])
{
entityName = [self performSelector:@selector(entityName)];
}
if ([entityName length] == 0)
{
// Remove module prefix from Swift subclasses
entityName = [NSStringFromClass(self) componentsSeparatedByString:@"."].lastObject;
}
return entityName;
}
+ (void) MR_setDefaultBatchSize:(NSUInteger)newBatchSize
{
@synchronized(self)
{
kMagicalRecordDefaultBatchSize = newBatchSize;
}
}
+ (NSUInteger) MR_defaultBatchSize
{
return kMagicalRecordDefaultBatchSize;
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_executeFetchRequest:request inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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 firstObject];
}
+ (id) MR_executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_executeFetchRequestAndReturnFirstObject:request inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
#if TARGET_OS_IPHONE
+ (BOOL) MR_performFetch:(NSFetchedResultsController *)controller
{
NSError *error = nil;
BOOL success = [controller performFetch:&error];
if (!success)
{
[MagicalRecord handleErrors:error];
}
return success;
}
#endif
+ (NSEntityDescription *) MR_entityDescription
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_entityDescriptionInContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSEntityDescription *) MR_entityDescriptionInContext:(NSManagedObjectContext *)context
{
NSString *entityName = [self MR_entityName];
return [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
}
+ (NSArray *) MR_propertiesNamed:(NSArray *)properties
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_propertiesNamed:properties inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSArray *) MR_propertiesNamed:(NSArray *)properties inContext:(NSManagedObjectContext *)context
{
NSEntityDescription *description = [self MR_entityDescriptionInContext:context];
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
{
MRLogWarn(@"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_createEntityInContext:(NSManagedObjectContext *)context
{
if ([self respondsToSelector:@selector(insertInManagedObjectContext:)] && context != nil)
{
id entity = [self performSelector:@selector(insertInManagedObjectContext:) withObject:context];
return entity;
}
else
{
NSEntityDescription *entity = nil;
if (context == nil)
{
entity = [self MR_entityDescription];
}
else
{
entity = [self MR_entityDescriptionInContext:context];
}
if (entity == nil)
{
return nil;
}
return [[self alloc] initWithEntity:entity insertIntoManagedObjectContext:context];
}
}
+ (id) MR_createEntity
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSManagedObject *newEntity = [self MR_createEntityInContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
return newEntity;
}
- (BOOL) MR_deleteEntityInContext:(NSManagedObjectContext *)context
{
NSError *error = nil;
NSManagedObject *entityInContext = [context existingObjectWithID:[self objectID] error:&error];
[MagicalRecord handleErrors:error];
if (entityInContext) {
[context deleteObject:entityInContext];
}
return YES;
}
- (BOOL) MR_deleteEntity
{
[self MR_deleteEntityInContext:[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_deleteEntityInContext:context];
}
return YES;
}
+ (BOOL) MR_deleteAllMatchingPredicate:(NSPredicate *)predicate
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_deleteAllMatchingPredicate:predicate inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (BOOL) MR_truncateAllInContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self MR_requestAllInContext:context];
[request setReturnsObjectsAsFaults:YES];
[request setIncludesPropertyValues:NO];
NSArray *objectsToDelete = [self MR_executeFetchRequest:request inContext:context];
for (NSManagedObject *objectToDelete in objectsToDelete)
{
[objectToDelete MR_deleteEntityInContext:context];
}
return YES;
}
+ (BOOL) MR_truncateAll
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[self MR_truncateAllInContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
return YES;
}
- (id) MR_inContext:(NSManagedObjectContext *)otherContext
{
NSError *error = nil;
if ([[self objectID] isTemporaryID])
{
BOOL success = [[self managedObjectContext] obtainPermanentIDsForObjects:@[self] error:&error];
if (!success)
{
[MagicalRecord handleErrors:error];
return nil;
}
}
error = nil;
NSManagedObject *inContext = [otherContext existingObjectWithID:[self objectID] error:&error];
[MagicalRecord handleErrors:error];
return inContext;
}
- (id) MR_inThreadContext
{
NSManagedObject *weakSelf = self;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [weakSelf MR_inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
@end
#pragma mark - Deprecated Methods DO NOT USE
@implementation NSManagedObject (MagicalRecordDeprecated)
+ (instancetype) MR_createInContext:(NSManagedObjectContext *)context
{
return [self MR_createEntityInContext:context];
}
- (BOOL) MR_deleteInContext:(NSManagedObjectContext *)context
{
return [self MR_deleteEntityInContext:context];
}
@end

Просмотреть файл

@ -1,32 +0,0 @@
//
// NSManagedObject+MagicalRequests.h
// Magical Record
//
// Created by Saul Mora on 3/7/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObject (MagicalRequests)
+ (MR_nonnull NSFetchRequest *) MR_createFetchRequest;
+ (MR_nonnull NSFetchRequest *) MR_createFetchRequestInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAll;
+ (MR_nonnull NSFetchRequest *) MR_requestAllInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAllWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSFetchRequest *) MR_requestAllWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAllWhere:(MR_nonnull NSString *)property isEqualTo:(MR_nonnull id)value;
+ (MR_nonnull NSFetchRequest *) MR_requestAllWhere:(MR_nonnull NSString *)property isEqualTo:(MR_nonnull id)value inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSFetchRequest *) MR_requestFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nullable id)searchValue;
+ (MR_nonnull NSFetchRequest *) MR_requestFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nullable id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nonnull NSFetchRequest *) MR_requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) MR_requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSFetchRequest *) MR_requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
@end

Просмотреть файл

@ -1,173 +0,0 @@
//
// 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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_createFetchRequestInContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSFetchRequest *) MR_requestAll
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_createFetchRequestInContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (NSFetchRequest *) MR_requestAllInContext:(NSManagedObjectContext *)context
{
return [self MR_createFetchRequestInContext:context];
}
+ (NSFetchRequest *) MR_requestAllWithPredicate:(NSPredicate *)searchTerm;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_requestAllWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_requestAllWhere:property isEqualTo:value inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_requestFirstWithPredicate:searchTerm inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_requestFirstByAttribute:attribute withValue:searchValue inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self MR_requestAllSortedBy:sortTerm
ascending:ascending
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
}
+ (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 (__strong NSString* sortKey in sortKeys)
{
NSArray * sortComponents = [sortKey componentsSeparatedByString:@":"];
if (sortComponents.count > 1)
{
NSString * customAscending = sortComponents.lastObject;
ascending = customAscending.boolValue;
sortKey = sortComponents[0];
}
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;
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSFetchRequest *request = [self MR_requestAllSortedBy:sortTerm
ascending:ascending
withPredicate:searchTerm
inContext:[NSManagedObjectContext MR_contextForCurrentThread]];
#pragma clang diagnostic pop
return request;
}
@end

Просмотреть файл

@ -1,36 +0,0 @@
//
// NSManagedObjectContext+MagicalChainSave.h
// Magical Record
//
// Created by Lee on 8/27/14.
// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/NSManagedObjectContext+MagicalSaves.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObjectContext (MagicalRecordChainSave)
/**
Creates a child context for the current context that you can make changes within, before saving up through all parent contexts to the main queue context, and finally to the saving context. This method will return immediately, and execute the save initially on a background thread, and then on the appropriate thread for each context it saves.
@param block Block that is passed a managed object context.
*/
- (void)MR_saveWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block;
/**
Creates a child context for the current context that you can make changes within, before saving up through all parent contexts to the main queue context, and finally to the saving context. This method will return immediately, and execute the save initially on a background thread, and then on the appropriate thread for each context it saves.
@param block Block that is passed a managed object context.
@param completion Completion block that is called once all contexts have been saved, or if an error is encountered.
*/
- (void)MR_saveWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block completion:(MR_nullable MRSaveCompletionHandler)completion;
/**
Creates a child context for the current context that you can make changes within, before saving up through all parent contexts to the main queue context, and finally to the saving context. This method will not return until the save has completed, blocking the thread it is called on.
@param block Block that is passed a managed object context.
*/
- (void)MR_saveWithBlockAndWait:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block;
@end

Просмотреть файл

@ -1,50 +0,0 @@
//
// NSManagedObjectContext+MagicalChainSave.m
// Magical Record
//
// Created by Lee on 8/27/14.
// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.
//
#import "NSManagedObjectContext+MagicalChainSave.h"
#import "NSManagedObjectContext+MagicalRecord.h"
@implementation NSManagedObjectContext (MagicalRecord_ChainSave)
- (void)MR_saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block;
{
[self MR_saveWithBlock:block completion:nil];
}
- (void)MR_saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:self];
[localContext performBlock:^{
[localContext MR_setWorkingName:NSStringFromSelector(_cmd)];
if (block) {
block(localContext);
}
[localContext MR_saveWithOptions:MRSaveParentContexts completion:completion];
}];
}
#pragma mark - Synchronous saving
- (void)MR_saveWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:self];
[localContext performBlockAndWait:^{
[localContext MR_setWorkingName:NSStringFromSelector(_cmd)];
if (block) {
block(localContext);
}
[localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil];
}];
}
@end

Просмотреть файл

@ -1,70 +0,0 @@
//
// NSManagedObjectContext+MagicalObserving.h
// Magical Record
//
// Created by Saul Mora on 3/9/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordDidMergeChangesFromiCloudNotification;
/**
Category methods to aid in observing changes in other contexts.
@since Available in v2.0 and later.
*/
@interface NSManagedObjectContext (MagicalObserving)
/**
Merge changes from another context into self.
@param otherContext Managed object context to observe.
@since Available in v2.0 and later.
*/
- (void) MR_observeContext:(MR_nonnull NSManagedObjectContext *)otherContext;
/**
Stops merging changes from the supplied context into self.
@param otherContext Managed object context to stop observing.
@since Available in v2.0 and later.
*/
- (void) MR_stopObservingContext:(MR_nonnull NSManagedObjectContext *)otherContext;
/**
Merges changes from another context into self on the main thread.
@param otherContext Managed object context to observe.
@since Available in v2.0 and later.
*/
- (void) MR_observeContextOnMainThread:(MR_nonnull NSManagedObjectContext *)otherContext;
/**
Merges changes from the supplied persistent store coordinator into self in response to changes from iCloud.
@param coordinator Persistent store coordinator
@see -MR_stopObservingiCloudChangesInCoordinator:
@since Available in v2.0 and later.
*/
- (void) MR_observeiCloudChangesInCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
/**
Stops observation and merging of changes from the supplied persistent store coordinator in response to changes from iCloud.
@param coordinator Persistent store coordinator
@see -MR_observeiCloudChangesInCoordinator:
@since Available in v2.0 and later.
*/
- (void) MR_stopObservingiCloudChangesInCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
@end

Просмотреть файл

@ -1,108 +0,0 @@
//
// 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+iCloud.h"
#import "MagicalRecordLogging.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_stopObservingContext:(NSManagedObjectContext *)otherContext
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:otherContext];
}
- (void) MR_observeContextOnMainThread:(NSManagedObjectContext *)otherContext
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(MR_mergeChangesOnMainThread:)
name:NSManagedObjectContextDidSaveNotification
object:otherContext];
}
#pragma mark - Context iCloud Merge Helpers
- (void) MR_mergeChangesFromiCloud:(NSNotification *)notification;
{
[self performBlock:^{
MRLogVerbose(@"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;
{
MRLogVerbose(@"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

Просмотреть файл

@ -1,130 +0,0 @@
//
// NSManagedObjectContext+MagicalRecord.h
//
// Created by Saul Mora on 11/23/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordDeprecationMacros.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObjectContext (MagicalRecord)
#pragma mark - Setup
/**
Initializes MagicalRecord's default contexts using the provided persistent store coordinator.
@param coordinator Persistent Store Coordinator
*/
+ (void) MR_initializeDefaultContextWithCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
#pragma mark - Default Contexts
/**
Root context responsible for sending changes to the main persistent store coordinator that will be saved to disk.
@discussion Use this context for making and saving changes. All saves will be merged into the context returned by `MR_defaultContext` as well.
@return Private context used for saving changes to disk on a background thread
*/
+ (MR_nonnull NSManagedObjectContext *) MR_rootSavingContext;
/**
@discussion Please do not use this context for saving changes, as it will block the main thread when doing so.
@return Main queue context that can be observed for changes
*/
+ (MR_nonnull NSManagedObjectContext *) MR_defaultContext;
#pragma mark - Context Creation
/**
Creates and returns a new managed object context of type `NSPrivateQueueConcurrencyType`, with it's parent context set to the root saving context.
@return Private context with the parent set to the root saving context
*/
+ (MR_nonnull NSManagedObjectContext *) MR_context;
/**
Creates and returns a new managed object context of type `NSPrivateQueueConcurrencyType`, with it's parent context set to the root saving context.
@param parentContext Context to set as the parent of the newly initialized context
@return Private context with the parent set to the provided context
*/
+ (MR_nonnull NSManagedObjectContext *) MR_contextWithParent:(MR_nonnull NSManagedObjectContext *)parentContext;
/**
Creates and returns a new managed object context of type `NSPrivateQueueConcurrencyType`, with it's persistent store coordinator set to the provided coordinator.
@param coordinator A persistent store coordinator
@return Private context with it's persistent store coordinator set to the provided coordinator
*/
+ (MR_nonnull NSManagedObjectContext *) MR_contextWithStoreCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
/**
Initializes a context of type `NSMainQueueConcurrencyType`.
@return A context initialized using the `NSPrivateQueueConcurrencyType` concurrency type.
*/
+ (MR_nonnull NSManagedObjectContext *) MR_newMainQueueContext NS_RETURNS_RETAINED;
/**
Initializes a context of type `NSPrivateQueueConcurrencyType`.
@return A context initialized using the `NSPrivateQueueConcurrencyType` concurrency type.
*/
+ (MR_nonnull NSManagedObjectContext *) MR_newPrivateQueueContext NS_RETURNS_RETAINED;
#pragma mark - Debugging
/**
Sets a working name for the context, which will be used in debug logs.
@param workingName Name for the context
*/
- (void) MR_setWorkingName:(MR_nonnull NSString *)workingName;
/**
@return Working name for the context
*/
- (MR_nonnull NSString *) MR_workingName;
/**
@return Description of this context
*/
- (MR_nonnull NSString *) MR_description;
/**
@return Description of the parent contexts of this context
*/
- (MR_nonnull NSString *) MR_parentChain;
#pragma mark - Helpers
/**
Reset the default context.
*/
+ (void) MR_resetDefaultContext;
/**
Delete the provided objects from the context
@param objects An object conforming to `NSFastEnumeration`, containing NSManagedObject instances
*/
- (void) MR_deleteObjects:(MR_nonnull id <NSFastEnumeration>)objects;
@end
#pragma mark - Deprecated Methods — DO NOT USE
@interface NSManagedObjectContext (MagicalRecordDeprecated)
+ (MR_nonnull NSManagedObjectContext *) MR_contextWithoutParent MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_newPrivateQueueContext");
+ (MR_nonnull NSManagedObjectContext *) MR_newContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_context");
+ (MR_nonnull NSManagedObjectContext *) MR_newContextWithParent:(MR_nonnull NSManagedObjectContext *)parentContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithParent:");
+ (MR_nonnull NSManagedObjectContext *) MR_newContextWithStoreCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithStoreCoordinator:");
@end

Просмотреть файл

@ -1,349 +0,0 @@
//
// NSManagedObjectContext+MagicalRecord.m
//
// Created by Saul Mora on 11/23/09.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import "NSManagedObjectContext+MagicalRecord.h"
#import "NSManagedObjectContext+MagicalObserving.h"
#import "NSManagedObjectContext+MagicalThreading.h"
#import "NSPersistentStoreCoordinator+MagicalRecord.h"
#import "MagicalRecord+ErrorHandling.h"
#import "MagicalRecord+iCloud.h"
#import "MagicalRecordLogging.h"
static NSString * const MagicalRecordContextWorkingName = @"MagicalRecordContextWorkingName";
static NSManagedObjectContext *MagicalRecordRootSavingContext;
static NSManagedObjectContext *MagicalRecordDefaultContext;
static id MagicalRecordUbiquitySetupNotificationObserver;
@implementation NSManagedObjectContext (MagicalRecord)
#pragma mark - Setup
+ (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator;
{
NSAssert(coordinator, @"Provided coordinator cannot be nil!");
if (MagicalRecordDefaultContext == nil)
{
NSManagedObjectContext *rootContext = [self MR_contextWithStoreCoordinator:coordinator];
[self MR_setRootSavingContext:rootContext];
NSManagedObjectContext *defaultContext = [self MR_newMainQueueContext];
[self MR_setDefaultContext:defaultContext];
[defaultContext setParentContext:rootContext];
}
}
#pragma mark - Default Contexts
+ (NSManagedObjectContext *) MR_defaultContext
{
@synchronized(self) {
NSAssert(MagicalRecordDefaultContext != nil, @"Default context is nil! Did you forget to initialize the Core Data Stack?");
return MagicalRecordDefaultContext;
}
}
+ (NSManagedObjectContext *) MR_rootSavingContext;
{
NSAssert(MagicalRecordRootSavingContext != nil, @"Root saving context is nil! Did you forget to initialize the Core Data Stack?");
return MagicalRecordRootSavingContext;
}
#pragma mark - Context Creation
+ (NSManagedObjectContext *) MR_context
{
return [self MR_contextWithParent:[self MR_rootSavingContext]];
}
+ (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext
{
NSManagedObjectContext *context = [self MR_newPrivateQueueContext];
[context setParentContext:parentContext];
[context MR_obtainPermanentIDsBeforeSaving];
return context;
}
+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator
{
NSManagedObjectContext *context = nil;
if (coordinator != nil)
{
context = [self MR_newPrivateQueueContext];
[context performBlockAndWait:^{
[context setPersistentStoreCoordinator:coordinator];
MRLogVerbose(@"Created new context %@ with store coordinator: %@", [context MR_workingName], coordinator);
}];
}
return context;
}
+ (NSManagedObjectContext *) MR_newMainQueueContext
{
NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
MRLogInfo(@"Created new main queue context: %@", context);
return context;
}
+ (NSManagedObjectContext *) MR_newPrivateQueueContext
{
NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
MRLogInfo(@"Created new private queue context: %@", context);
return context;
}
#pragma mark - Debugging
- (void)MR_setWorkingName:(NSString *)workingName
{
void (^setWorkingName)() = ^{
[[self userInfo] setObject:workingName forKey:MagicalRecordContextWorkingName];
};
if (self.concurrencyType == NSMainQueueConcurrencyType && [NSThread isMainThread])
{
setWorkingName();
}
else
{
[self performBlockAndWait:setWorkingName];
}
}
- (NSString *)MR_workingName
{
__block NSString *workingName;
void (^getWorkingName)() = ^{
workingName = [[self userInfo] objectForKey:MagicalRecordContextWorkingName];
};
if (self.concurrencyType == NSMainQueueConcurrencyType && [NSThread isMainThread])
{
getWorkingName();
}
else
{
[self performBlockAndWait:getWorkingName];
}
if ([workingName length] == 0)
{
workingName = @"Untitled Context";
}
return workingName;
}
- (NSString *) MR_description
{
NSString *onMainThread = [NSThread isMainThread] ? @"the main thread" : @"a background thread";
__block NSString *workingName;
[self performBlockAndWait:^{
workingName = [self MR_workingName];
}];
return [NSString stringWithFormat:@"<%@ (%p): %@> on %@", NSStringFromClass([self class]), self, workingName, 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];
}
#pragma mark - Helpers
+ (void) MR_resetDefaultContext
{
NSManagedObjectContext *defaultContext = [NSManagedObjectContext MR_defaultContext];
NSAssert(NSConfinementConcurrencyType == [defaultContext concurrencyType], @"Do not call this method on a confinement context.");
if ([NSThread isMainThread] == NO) {
dispatch_async(dispatch_get_main_queue(), ^{
[self MR_resetDefaultContext];
});
return;
}
[defaultContext reset];
}
- (void) MR_deleteObjects:(id <NSFastEnumeration>)objects
{
for (NSManagedObject *managedObject in objects)
{
[self deleteObject:managedObject];
}
}
#pragma mark - Notification Handlers
- (void) MR_contextWillSave:(NSNotification *)notification
{
NSManagedObjectContext *context = [notification object];
NSSet *insertedObjects = [context insertedObjects];
if ([insertedObjects count])
{
MRLogVerbose(@"Context '%@' is about to save: obtaining permanent IDs for %lu new inserted object(s).", [context MR_workingName], (unsigned long)[insertedObjects count]);
NSError *error = nil;
BOOL success = [context obtainPermanentIDsForObjects:[insertedObjects allObjects] error:&error];
if (!success)
{
[MagicalRecord handleErrors:error];
}
}
}
+ (void)rootContextDidSave:(NSNotification *)notification
{
if ([notification object] != [self MR_rootSavingContext])
{
return;
}
if ([NSThread isMainThread] == NO)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self rootContextDidSave:notification];
});
return;
}
for (NSManagedObject *object in [[notification userInfo] objectForKey:NSUpdatedObjectsKey])
{
[[[self MR_defaultContext] objectWithID:[object objectID]] willAccessValueForKey:nil];
}
[[self MR_defaultContext] mergeChangesFromContextDidSaveNotification:notification];
}
#pragma mark - Private Methods
+ (void) MR_cleanUp
{
[self MR_setDefaultContext:nil];
[self MR_setRootSavingContext:nil];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[self MR_clearNonMainThreadContextsCache];
#pragma clang diagnostic pop
}
- (void) MR_obtainPermanentIDsBeforeSaving
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(MR_contextWillSave:)
name:NSManagedObjectContextWillSaveNotification
object:self];
}
+ (void) MR_setDefaultContext:(NSManagedObjectContext *)moc
{
if (MagicalRecordDefaultContext)
{
[[NSNotificationCenter defaultCenter] removeObserver:MagicalRecordDefaultContext];
}
NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_defaultStoreCoordinator];
if (MagicalRecordUbiquitySetupNotificationObserver)
{
[[NSNotificationCenter defaultCenter] removeObserver:MagicalRecordUbiquitySetupNotificationObserver];
MagicalRecordUbiquitySetupNotificationObserver = nil;
}
if ([MagicalRecord isICloudEnabled])
{
[MagicalRecordDefaultContext MR_stopObservingiCloudChangesInCoordinator:coordinator];
}
MagicalRecordDefaultContext = moc;
[MagicalRecordDefaultContext MR_setWorkingName:@"MagicalRecord Default Context"];
if ((MagicalRecordDefaultContext != nil) && ([self MR_rootSavingContext] != nil)) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(rootContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:[self MR_rootSavingContext]];
}
[moc MR_obtainPermanentIDsBeforeSaving];
if ([MagicalRecord isICloudEnabled])
{
[MagicalRecordDefaultContext 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
MagicalRecordUbiquitySetupNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMagicalRecordPSCDidCompleteiCloudSetupNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[[NSManagedObjectContext MR_defaultContext] MR_observeiCloudChangesInCoordinator:coordinator];
}];
}
MRLogInfo(@"Set default context: %@", MagicalRecordDefaultContext);
}
+ (void)MR_setRootSavingContext:(NSManagedObjectContext *)context
{
if (MagicalRecordRootSavingContext)
{
[[NSNotificationCenter defaultCenter] removeObserver:MagicalRecordRootSavingContext];
}
MagicalRecordRootSavingContext = context;
[MagicalRecordRootSavingContext performBlock:^{
[MagicalRecordRootSavingContext MR_obtainPermanentIDsBeforeSaving];
[MagicalRecordRootSavingContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[MagicalRecordRootSavingContext MR_setWorkingName:@"MagicalRecord Root Saving Context"];
}];
MRLogInfo(@"Set root saving context: %@", MagicalRecordRootSavingContext);
}
@end
#pragma mark - Deprecated Methods DO NOT USE
@implementation NSManagedObjectContext (MagicalRecordDeprecated)
+ (NSManagedObjectContext *) MR_contextWithoutParent
{
return [self MR_newPrivateQueueContext];
}
+ (NSManagedObjectContext *) MR_newContext
{
return [self MR_context];
}
+ (NSManagedObjectContext *) MR_newContextWithParent:(NSManagedObjectContext *)parentContext
{
return [self MR_contextWithParent:parentContext];
}
+ (NSManagedObjectContext *) MR_newContextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator
{
return [self MR_contextWithStoreCoordinator:coordinator];
}
@end

Просмотреть файл

@ -1,92 +0,0 @@
//
// NSManagedObjectContext+MagicalSaves.h
// Magical Record
//
// Created by Saul Mora on 3/9/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordDeprecationMacros.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
typedef NS_OPTIONS(NSUInteger, MRSaveOptions) {
/** No options — used for cleanliness only */
MRSaveOptionNone = 0,
/** When saving, continue saving parent contexts until the changes are present in the persistent store */
MRSaveParentContexts = 1 << 1,
/** Perform saves synchronously, blocking execution on the current thread until the save is complete */
MRSaveSynchronously = 1 << 2,
/** Perform saves synchronously, blocking execution on the current thread until the save is complete; however, saves root context asynchronously */
MRSaveSynchronouslyExceptRootContext = 1 << 3
};
typedef void (^MRSaveCompletionHandler)(BOOL contextDidSave, NSError * __MR_nullable error);
@interface NSManagedObjectContext (MagicalSaves)
/**
Asynchronously save changes in the current context and it's parent.
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.
@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.
@since Available in v2.1.0 and later.
*/
- (void) MR_saveOnlySelfWithCompletion:(MR_nullable MRSaveCompletionHandler)completion;
/**
Asynchronously save changes in the current context all the way back to the persistent store.
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.
@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.
@since Available in v2.1.0 and later.
*/
- (void) MR_saveToPersistentStoreWithCompletion:(MR_nullable MRSaveCompletionHandler)completion;
/**
Synchronously save changes in the current context and it's parent.
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.
@since Available in v2.1.0 and later.
*/
- (void) MR_saveOnlySelfAndWait;
/**
Synchronously save changes in the current context all the way back to the persistent store.
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.
@since Available in v2.1.0 and later.
*/
- (void) MR_saveToPersistentStoreAndWait;
/**
Save the current context with options.
All other save methods are conveniences to this method.
@param saveOptions 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.
@since Available in v2.1.0 and later.
*/
- (void) MR_saveWithOptions:(MRSaveOptions)saveOptions completion:(MR_nullable MRSaveCompletionHandler)completion;
@end
#pragma mark - Deprecated Methods — DO NOT USE
@interface NSManagedObjectContext (MagicalSavesDeprecated)
- (void) MR_save MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreAndWait");
- (void) MR_saveWithErrorCallback:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
- (void) MR_saveInBackgroundCompletion:(void (^ __MR_nullable)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
- (void) MR_saveInBackgroundErrorHandler:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
- (void) MR_saveInBackgroundErrorHandler:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback completion:(void (^ __MR_nullable)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
- (void) MR_saveNestedContexts MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:");
- (void) MR_saveNestedContextsErrorHandler:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:");
- (void) MR_saveNestedContextsErrorHandler:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback completion:(void (^ __MR_nullable)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:");
@end

Просмотреть файл

@ -1,219 +0,0 @@
//
// 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 "NSManagedObjectContext+MagicalRecord.h"
#import "MagicalRecord+ErrorHandling.h"
#import "MagicalRecordLogging.h"
@implementation NSManagedObjectContext (MagicalSaves)
- (void) MR_saveOnlySelfWithCompletion:(MRSaveCompletionHandler)completion;
{
[self MR_saveWithOptions:MRSaveOptionNone 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:(MRSaveOptions)saveOptions completion:(MRSaveCompletionHandler)completion;
{
__block BOOL hasChanges = NO;
if ([self concurrencyType] == NSConfinementConcurrencyType)
{
hasChanges = [self hasChanges];
}
else
{
[self performBlockAndWait:^{
hasChanges = [self hasChanges];
}];
}
if (!hasChanges)
{
MRLogVerbose(@"NO CHANGES IN ** %@ ** CONTEXT - NOT SAVING", [self MR_workingName]);
if (completion)
{
dispatch_async(dispatch_get_main_queue(), ^{
completion(NO, nil);
});
}
return;
}
BOOL shouldSaveParentContexts = ((saveOptions & MRSaveParentContexts) == MRSaveParentContexts);
BOOL shouldSaveSynchronously = ((saveOptions & MRSaveSynchronously) == MRSaveSynchronously);
BOOL shouldSaveSynchronouslyExceptRoot = ((saveOptions & MRSaveSynchronouslyExceptRootContext) == MRSaveSynchronouslyExceptRootContext);
BOOL saveSynchronously = (shouldSaveSynchronously && !shouldSaveSynchronouslyExceptRoot) ||
(shouldSaveSynchronouslyExceptRoot && (self != [[self class] MR_rootSavingContext]));
id saveBlock = ^{
MRLogInfo(@"→ Saving %@", [self MR_description]);
MRLogVerbose(@"→ Save Parents? %@", shouldSaveParentContexts ? @"YES" : @"NO");
MRLogVerbose(@"→ Save Synchronously? %@", saveSynchronously ? @"YES" : @"NO");
BOOL saveResult = NO;
NSError *error = nil;
@try
{
saveResult = [self save:&error];
}
@catch(NSException *exception)
{
MRLogError(@"Unable to perform save: %@", (id)[exception userInfo] ?: (id)[exception reason]);
}
@finally
{
[MagicalRecord handleErrors:error];
if (saveResult && shouldSaveParentContexts && [self parentContext])
{
// Add/remove the synchronous save option from the mask if necessary
MRSaveOptions modifiedOptions = saveOptions;
if (saveSynchronously)
{
modifiedOptions |= MRSaveSynchronously;
}
else
{
modifiedOptions &= ~MRSaveSynchronously;
}
// If we're saving parent contexts, do so
[[self parentContext] MR_saveWithOptions:modifiedOptions completion:completion];
}
else
{
if (saveResult)
{
MRLogVerbose(@"→ Finished saving: %@", [self MR_description]);
}
if (completion)
{
dispatch_async(dispatch_get_main_queue(), ^{
completion(saveResult, error);
});
}
}
}
};
if (saveSynchronously)
{
[self performBlockAndWait:saveBlock];
}
else
{
[self performBlock:saveBlock];
}
}
@end
#pragma mark - Deprecated Methods DO NOT USE
@implementation NSManagedObjectContext (MagicalSavesDeprecated)
- (void) MR_save;
{
[self MR_saveToPersistentStoreAndWait];
}
- (void) MR_saveWithErrorCallback:(void (^)(NSError *error))errorCallback;
{
[self MR_saveWithOptions:MRSaveSynchronously | MRSaveParentContexts completion:^(BOOL contextDidSave, NSError *error) {
if (!contextDidSave && errorCallback)
{
errorCallback(error);
}
}];
}
- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion;
{
[self MR_saveOnlySelfWithCompletion:^(BOOL contextDidSave, NSError *error) {
if (contextDidSave && completion)
{
completion();
}
}];
}
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback;
{
[self MR_saveOnlySelfWithCompletion:^(BOOL contextDidSave, NSError *error) {
if (!contextDidSave && errorCallback)
{
errorCallback(error);
}
}];
}
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
{
[self MR_saveOnlySelfWithCompletion:^(BOOL contextDidSave, NSError *error) {
if (contextDidSave && 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 contextDidSave, NSError *error) {
if (!contextDidSave && errorCallback)
{
errorCallback(error);
}
}];
}
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
{
[self MR_saveToPersistentStoreWithCompletion:^(BOOL contextDidSave, NSError *error) {
if (contextDidSave && completion)
{
completion();
}
else if (errorCallback)
{
errorCallback(error);
}
}];
}
@end

Просмотреть файл

@ -1,19 +0,0 @@
//
// NSManagedObjectContext+MagicalThreading.h
// Magical Record
//
// Created by Saul Mora on 3/9/12.
// Copyright (c) 2012 Magical Panda Software LLC. All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObjectContext (MagicalThreading)
+ (MR_nonnull NSManagedObjectContext *) MR_contextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0")));
+ (void) MR_clearNonMainThreadContextsCache __attribute((deprecated("This method will be removed in MagicalRecord 3.0")));
+ (void) MR_resetContextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0")));
+ (void) MR_clearContextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0")));
@end

Просмотреть файл

@ -1,69 +0,0 @@
//
// 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 "NSManagedObjectContext+MagicalRecord.h"
#import "NSManagedObject+MagicalRecord.h"
#include <libkern/OSAtomic.h>
static NSString const * kMagicalRecordManagedObjectContextKey = @"MagicalRecord_NSManagedObjectContextForThreadKey";
static NSString const * kMagicalRecordManagedObjectContextCacheVersionKey = @"MagicalRecord_CacheVersionOfNSManagedObjectContextForThreadKey";
static volatile int32_t contextsCacheVersion = 0;
@implementation NSManagedObjectContext (MagicalThreading)
+ (void)MR_resetContextForCurrentThread
{
[[NSManagedObjectContext MR_contextForCurrentThread] reset];
}
+ (void) MR_clearNonMainThreadContextsCache
{
OSAtomicIncrement32(&contextsCacheVersion);
}
+ (NSManagedObjectContext *) MR_contextForCurrentThread;
{
if ([NSThread isMainThread])
{
return [self MR_defaultContext];
}
else
{
// contextsCacheVersion can change (atomically) at any time, so grab a copy to ensure that we always
// use the same value throughout the remainder of this method. We are OK with this method returning
// an outdated context if MR_clearNonMainThreadContextsCache is called from another thread while this
// method is being executed. This behavior is unrelated to our choice to use a counter for synchronization.
// We would have the same behavior if we used @synchronized() (or any other lock-based synchronization
// method) since MR_clearNonMainThreadContextsCache would have to wait until this method finished before
// it could acquire the mutex, resulting in us still returning an outdated context in that case as well.
int32_t targetCacheVersionForContext = contextsCacheVersion;
NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
NSManagedObjectContext *threadContext = [threadDict objectForKey:kMagicalRecordManagedObjectContextKey];
NSNumber *currentCacheVersionForContext = [threadDict objectForKey:kMagicalRecordManagedObjectContextCacheVersionKey];
NSAssert((threadContext && currentCacheVersionForContext) || (!threadContext && !currentCacheVersionForContext),
@"The Magical Record keys should either both be present or neither be present, otherwise we're in an inconsistent state!");
if ((threadContext == nil) || (currentCacheVersionForContext == nil) || ((int32_t)[currentCacheVersionForContext integerValue] != targetCacheVersionForContext))
{
threadContext = [self MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
[threadDict setObject:threadContext forKey:kMagicalRecordManagedObjectContextKey];
[threadDict setObject:[NSNumber numberWithInteger:targetCacheVersionForContext]
forKey:kMagicalRecordManagedObjectContextCacheVersionKey];
}
return threadContext;
}
}
+ (void) MR_clearContextForCurrentThread {
[[[NSThread currentThread] threadDictionary] removeObjectForKey:kMagicalRecordManagedObjectContextKey];
[[[NSThread currentThread] threadDictionary] removeObjectForKey:kMagicalRecordManagedObjectContextCacheVersionKey];
}
@end

Просмотреть файл

@ -1,23 +0,0 @@
//
// NSManagedObjectModel+MagicalRecord.h
//
// Created by Saul Mora on 3/11/10.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObjectModel (MagicalRecord)
+ (MR_nullable NSManagedObjectModel *) MR_defaultManagedObjectModel;
+ (void) MR_setDefaultManagedObjectModel:(MR_nullable NSManagedObjectModel *)newDefaultModel;
+ (MR_nullable NSManagedObjectModel *) MR_mergedObjectModelFromMainBundle;
+ (MR_nullable NSManagedObjectModel *) MR_newManagedObjectModelNamed:(MR_nonnull NSString *)modelFileName NS_RETURNS_RETAINED;
+ (MR_nullable NSManagedObjectModel *) MR_managedObjectModelNamed:(MR_nonnull NSString *)modelFileName;
+ (MR_nullable NSManagedObjectModel *) MR_newModelNamed:(MR_nonnull NSString *) modelName inBundleNamed:(MR_nonnull NSString *) bundleName NS_RETURNS_RETAINED;
+ (MR_nullable NSManagedObjectModel *) MR_newModelNamed:(MR_nonnull NSString *) modelName inBundle:(MR_nonnull NSBundle*) bundle NS_RETURNS_RETAINED;
@end

Просмотреть файл

@ -1,73 +0,0 @@
//
// 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 "MagicalRecord+Options.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_newModelNamed:(NSString *) modelName inBundle:(NSBundle*) bundle
{
NSString *path = [bundle pathForResource:[modelName stringByDeletingPathExtension]
ofType:[modelName pathExtension]];
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

Просмотреть файл

@ -1,30 +0,0 @@
//
// NSPersistentStore+MagicalRecord.h
//
// Created by Saul Mora on 3/11/10.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
#import "MagicalRecordDeprecationMacros.h"
// option to autodelete store if it already exists
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordDefaultStoreFileName;
@interface NSPersistentStore (MagicalRecord)
+ (MR_nonnull NSURL *) MR_defaultLocalStoreUrl;
+ (MR_nullable NSPersistentStore *) MR_defaultPersistentStore;
+ (void) MR_setDefaultPersistentStore:(MR_nullable NSPersistentStore *) store;
+ (MR_nullable NSURL *) MR_urlForStoreName:(MR_nonnull NSString *)storeFileName;
+ (MR_nullable NSURL *) MR_cloudURLForUbiquitousContainer:(MR_nonnull NSString *)bucketName;
+ (MR_nullable NSURL *) MR_cloudURLForUbiqutiousContainer:(MR_nonnull NSString *)bucketName MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_cloudURLForUbiquitousContainer:");
@end

Просмотреть файл

@ -1,71 +0,0 @@
//
// NSPersistentStore+MagicalRecord.m
//
// Created by Saul Mora on 3/11/10.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import "NSPersistentStore+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:(NSSearchPathDirectory)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
{
NSString *pathForStoreName = [[self MR_applicationStorageDirectory] stringByAppendingPathComponent:storeFileName];
return [NSURL fileURLWithPath:pathForStoreName];
}
+ (NSURL *) MR_cloudURLForUbiquitousContainer:(NSString *)bucketName;
{
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *cloudURL = nil;
if ([fileManager respondsToSelector:@selector(URLForUbiquityContainerIdentifier:)])
{
cloudURL = [fileManager URLForUbiquityContainerIdentifier:bucketName];
}
return cloudURL;
}
+ (NSURL *) MR_cloudURLForUbiqutiousContainer:(NSString *)bucketName;
{
return [self MR_cloudURLForUbiquitousContainer:bucketName];
}
+ (NSURL *) MR_defaultLocalStoreUrl
{
return [self MR_urlForStoreName:kMagicalRecordDefaultStoreFileName];
}
@end

Просмотреть файл

@ -1,51 +0,0 @@
//
// NSPersistentStoreCoordinator+MagicalRecord.h
//
// Created by Saul Mora on 3/11/10.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import <CoreData/CoreData.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordPSCDidCompleteiCloudSetupNotification;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordPSCMismatchWillDeleteStore;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordPSCMismatchDidDeleteStore;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordPSCMismatchWillRecreateStore;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordPSCMismatchDidRecreateStore;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordPSCMismatchCouldNotDeleteStore;
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordPSCMismatchCouldNotRecreateStore;
@interface NSPersistentStoreCoordinator (MagicalRecord)
+ (MR_nullable NSPersistentStoreCoordinator *) MR_defaultStoreCoordinator;
+ (void) MR_setDefaultStoreCoordinator:(MR_nullable NSPersistentStoreCoordinator *)coordinator;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithInMemoryStore;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_newPersistentStoreCoordinator NS_RETURNS_RETAINED;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreNamed:(MR_nonnull NSString *)storeFileName;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithAutoMigratingSqliteStoreNamed:(MR_nonnull NSString *)storeFileName;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreAtURL:(MR_nonnull NSURL *)storeURL;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithAutoMigratingSqliteStoreAtURL:(MR_nonnull NSURL *)storeURL;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithPersistentStore:(MR_nonnull NSPersistentStore *)persistentStore;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreNamed:(MR_nonnull NSString *)localStoreName cloudStorePathComponent:(MR_nullable NSString *)subPathComponent;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreAtURL:(MR_nonnull NSURL *)storeURL cloudStorePathComponent:(MR_nullable NSString *)subPathComponent;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreNamed:(MR_nonnull NSString *)localStoreName cloudStorePathComponent:(MR_nullable NSString *)subPathComponent completion:(void (^ __MR_nullable)(void))completionHandler;
+ (MR_nonnull NSPersistentStoreCoordinator *) MR_coordinatorWithiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreAtURL:(MR_nonnull NSURL *)storeURL cloudStorePathComponent:(MR_nullable NSString *)subPathComponent completion:(void (^ __MR_nullable)(void))completionHandler;
- (MR_nullable NSPersistentStore *) MR_addInMemoryStore;
- (MR_nullable NSPersistentStore *) MR_addAutoMigratingSqliteStoreNamed:(MR_nonnull NSString *) storeFileName;
- (MR_nullable NSPersistentStore *) MR_addAutoMigratingSqliteStoreAtURL:(MR_nonnull NSURL *)storeURL;
- (MR_nullable NSPersistentStore *) MR_addSqliteStoreNamed:(MR_nonnull id)storeFileName withOptions:(MR_nullable __autoreleasing NSDictionary *)options;
- (MR_nullable NSPersistentStore *) MR_addSqliteStoreNamed:(MR_nonnull id)storeFileName configuration:(MR_nullable NSString *)configuration withOptions:(MR_nullable __autoreleasing NSDictionary *)options;
- (void) MR_addiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreNamed:(MR_nonnull NSString *)localStoreName cloudStorePathComponent:(MR_nullable NSString *)subPathComponent;
- (void) MR_addiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreAtURL:(MR_nonnull NSURL *)storeURL cloudStorePathComponent:(MR_nullable NSString *)subPathComponent;
- (void) MR_addiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreNamed:(MR_nonnull NSString *)localStoreName cloudStorePathComponent:(MR_nullable NSString *)subPathComponent completion:(void (^ __MR_nullable)(void))completionBlock;
- (void) MR_addiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreAtURL:(MR_nonnull NSURL *)storeURL cloudStorePathComponent:(MR_nullable NSString *)subPathComponent completion:(void (^ __MR_nullable)(void))completionBlock;
@end

Просмотреть файл

@ -1,457 +0,0 @@
//
// NSPersistentStoreCoordinator+MagicalRecord.m
//
// Created by Saul Mora on 3/11/10.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import "NSPersistentStoreCoordinator+MagicalRecord.h"
#import "NSPersistentStore+MagicalRecord.h"
#import "NSManagedObjectModel+MagicalRecord.h"
#import "MagicalRecord+ErrorHandling.h"
#import "MagicalRecordLogging.h"
static NSPersistentStoreCoordinator *defaultCoordinator_ = nil;
NSString * const kMagicalRecordPSCDidCompleteiCloudSetupNotification = @"kMagicalRecordPSCDidCompleteiCloudSetupNotification";
NSString * const kMagicalRecordPSCMismatchWillDeleteStore = @"kMagicalRecordPSCMismatchWillDeleteStore";
NSString * const kMagicalRecordPSCMismatchDidDeleteStore = @"kMagicalRecordPSCMismatchDidDeleteStore";
NSString * const kMagicalRecordPSCMismatchWillRecreateStore = @"kMagicalRecordPSCMismatchWillRecreateStore";
NSString * const kMagicalRecordPSCMismatchDidRecreateStore = @"kMagicalRecordPSCMismatchDidRecreateStore";
NSString * const kMagicalRecordPSCMismatchCouldNotDeleteStore = @"kMagicalRecordPSCMismatchCouldNotDeleteStore";
NSString * const kMagicalRecordPSCMismatchCouldNotRecreateStore = @"kMagicalRecordPSCMismatchCouldNotRecreateStore";
@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 firstObject]];
}
}
}
- (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
{
return [self MR_addSqliteStoreNamed:storeFileName configuration:nil withOptions:options];
}
- (NSPersistentStore *) MR_addSqliteStoreNamed:(id)storeFileName configuration:(NSString *)configuration 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:configuration
URL:url
options:options
error:&error];
if (!store)
{
if ([MagicalRecord shouldDeleteStoreOnModelMismatch])
{
BOOL isMigrationError = (([error code] == NSPersistentStoreIncompatibleVersionHashError) || ([error code] == NSMigrationMissingSourceModelError) || ([error code] == NSMigrationError));
if ([[error domain] isEqualToString:NSCocoaErrorDomain] && isMigrationError)
{
[[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchWillDeleteStore object:nil];
NSError * deleteStoreError;
// Could not open the database, so... kill it! (AND WAL bits)
NSString *rawURL = [url absoluteString];
NSURL *shmSidecar = [NSURL URLWithString:[rawURL stringByAppendingString:@"-shm"]];
NSURL *walSidecar = [NSURL URLWithString:[rawURL stringByAppendingString:@"-wal"]];
[[NSFileManager defaultManager] removeItemAtURL:url error:&deleteStoreError];
[[NSFileManager defaultManager] removeItemAtURL:shmSidecar error:nil];
[[NSFileManager defaultManager] removeItemAtURL:walSidecar error:nil];
MRLogWarn(@"Removed incompatible model version: %@", [url lastPathComponent]);
if(deleteStoreError) {
[[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchCouldNotDeleteStore object:nil userInfo:@{@"Error":deleteStoreError}];
}
else {
[[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchDidDeleteStore object:nil];
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchWillRecreateStore object:nil];
// Try one more time to create the store
store = [self addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:url
options:options
error:&error];
if (store)
{
[[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchDidRecreateStore object:nil];
// If we successfully added a store, remove the error that was initially created
error = nil;
}
else {
[[NSNotificationCenter defaultCenter] postNotificationName:kMagicalRecordPSCMismatchCouldNotRecreateStore object:nil userInfo:@{@"Error":error}];
}
}
}
[MagicalRecord handleErrors:error];
}
return store;
}
- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey storeIdentifier:(id)storeIdentifier cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock
{
if (contentNameKey.length > 0)
{
NSAssert([contentNameKey rangeOfString:@"."].location == NSNotFound, @"NSPersistentStoreUbiquitousContentNameKey cannot contain a period.");
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *cloudURL = [NSPersistentStore MR_cloudURLForUbiquitousContainer:containerID];
if (subPathComponent)
{
cloudURL = [cloudURL URLByAppendingPathComponent:subPathComponent];
}
[MagicalRecord setICloudEnabled:cloudURL != nil];
NSDictionary *options = [[self class] MR_autoMigrationOptions];
if (cloudURL) //iCloud is available
{
NSMutableDictionary *iCloudOptions = [[NSMutableDictionary alloc] init];
[iCloudOptions setObject:cloudURL forKey:NSPersistentStoreUbiquitousContentURLKey];
if ([contentNameKey length] > 0)
{
[iCloudOptions setObject:contentNameKey forKey:NSPersistentStoreUbiquitousContentNameKey];
}
options = [options MR_dictionaryByMergingDictionary:iCloudOptions];
}
else
{
MRLogWarn(@"iCloud is not enabled");
}
if ([self respondsToSelector:@selector(performBlockAndWait:)])
{
[self performSelector:@selector(performBlockAndWait:) withObject:^{
[self MR_addSqliteStoreNamed:storeIdentifier withOptions:options];
}];
}
else
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[self lock];
#pragma clang diagnostic pop
[self MR_addSqliteStoreNamed:storeIdentifier withOptions:options];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[self unlock];
#pragma clang diagnostic pop
}
dispatch_async(dispatch_get_main_queue(), ^{
if ([NSPersistentStore MR_defaultPersistentStore] == nil)
{
[NSPersistentStore MR_setDefaultPersistentStore:[[self persistentStores] firstObject]];
}
if (completionBlock)
{
completionBlock();
}
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter postNotificationName:kMagicalRecordPSCDidCompleteiCloudSetupNotification object:nil];
});
});
}
#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];
}
- (NSPersistentStore *) MR_addAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL
{
NSDictionary *options = [[self class] MR_autoMigrationOptions];
return [self MR_addSqliteStoreNamed:storeURL 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_coordinatorWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL
{
NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
[coordinator MR_addAutoMigratingSqliteStoreAtURL:storeURL];
//HACK: lame solution to fix automigration error "Migration failed after first pass"
if ([[coordinator persistentStores] count] == 0)
{
[coordinator performSelector:@selector(MR_addAutoMigratingSqliteStoreAtURL:) withObject:storeURL 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 localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent
{
[self MR_addiCloudContainerID:containerID
contentNameKey:contentNameKey
localStoreAtURL:storeURL
cloudStorePathComponent:subPathComponent
completion:nil];
}
- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreNamed:(NSString *)localStoreName cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock;
{
[self MR_addiCloudContainerID:containerID
contentNameKey:contentNameKey
storeIdentifier:localStoreName
cloudStorePathComponent:subPathComponent
completion:completionBlock];
}
- (void) MR_addiCloudContainerID:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)subPathComponent completion:(void(^)(void))completionBlock;
{
[self MR_addiCloudContainerID:containerID
contentNameKey:contentNameKey
storeIdentifier:storeURL
cloudStorePathComponent:subPathComponent
completion:completionBlock];
}
+ (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
localStoreAtURL:(NSURL *)storeURL
cloudStorePathComponent:(NSString *)subPathComponent
{
return [self MR_coordinatorWithiCloudContainerID:containerID
contentNameKey:contentNameKey
localStoreAtURL:storeURL
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_coordinatorWithiCloudContainerID:(NSString *)containerID
contentNameKey:(NSString *)contentNameKey
localStoreAtURL:(NSURL *)storeURL
cloudStorePathComponent:(NSString *)subPathComponent
completion:(void (^)(void))completionHandler
{
NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
[psc MR_addiCloudContainerID:containerID
contentNameKey:contentNameKey
localStoreAtURL:storeURL
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_coordinatorWithSqliteStoreAtURL:(NSURL *)storeURL withOptions:(NSDictionary *)options
{
NSManagedObjectModel *model = [NSManagedObjectModel MR_defaultManagedObjectModel];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
[psc MR_addSqliteStoreNamed:storeURL withOptions:options];
return psc;
}
+ (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreNamed:(NSString *)storeFileName
{
return [self MR_coordinatorWithSqliteStoreNamed:storeFileName withOptions:nil];
}
+ (NSPersistentStoreCoordinator *) MR_coordinatorWithSqliteStoreAtURL:(NSURL *)storeURL
{
return [self MR_coordinatorWithSqliteStoreAtURL:storeURL withOptions:nil];
}
@end
@implementation NSDictionary (Merging)
- (NSMutableDictionary *) MR_dictionaryByMergingDictionary:(NSDictionary *)d;
{
NSMutableDictionary *mutDict = [self mutableCopy];
[mutDict addEntriesFromDictionary:d];
return mutDict;
}
@end

Просмотреть файл

@ -1,35 +0,0 @@
//
// MagicalRecord+Actions.h
//
// Created by Saul Mora on 2/24/11.
// Copyright 2011 Magical Panda Software. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MagicalRecord/MagicalRecordInternal.h>
#import <MagicalRecord/MagicalRecordDeprecationMacros.h>
#import <MagicalRecord/NSManagedObjectContext+MagicalSaves.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface MagicalRecord (Actions)
/* For all background saving operations. These calls will be sent to a different thread/queue.
*/
+ (void) saveWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block;
+ (void) saveWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block completion:(MR_nullable MRSaveCompletionHandler)completion;
/* For saving on the current thread as the caller, only with a separate context. Useful when you're managing your own threads/queues and need a serial call to create or change data
*/
+ (void) saveWithBlockAndWait:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block;
@end
@interface MagicalRecord (ActionsDeprecated)
+ (void) saveUsingCurrentThreadContextWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block completion:(MR_nullable MRSaveCompletionHandler)completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
+ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
+ (void) saveInBackgroundWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
+ (void) saveInBackgroundWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block completion:(void (^ __MR_nullable)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block completion:(void (^ __MR_nullable)(void))completion errorHandler:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorHandler MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
@end

Просмотреть файл

@ -1,143 +0,0 @@
//
// MagicalRecord+Actions.m
//
// Created by Saul Mora on 2/24/11.
// Copyright 2011 Magical Panda Software. All rights reserved.
//
#import "MagicalRecord+Actions.h"
#import "NSManagedObjectContext+MagicalRecord.h"
#import "NSManagedObjectContext+MagicalThreading.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 *savingContext = [NSManagedObjectContext MR_rootSavingContext];
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:savingContext];
[localContext performBlock:^{
[localContext MR_setWorkingName:NSStringFromSelector(_cmd)];
if (block) {
block(localContext);
}
[localContext MR_saveWithOptions:MRSaveParentContexts completion:completion];
}];
}
#pragma mark - Synchronous saving
+ (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block;
{
NSManagedObjectContext *savingContext = [NSManagedObjectContext MR_rootSavingContext];
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:savingContext];
[localContext performBlockAndWait:^{
[localContext MR_setWorkingName:NSStringFromSelector(_cmd)];
if (block) {
block(localContext);
}
[localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil];
}];
}
@end
#pragma mark - Deprecated Methods DO NOT USE
@implementation MagicalRecord (ActionsDeprecated)
+ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext performBlock:^{
[localContext MR_setWorkingName:NSStringFromSelector(_cmd)];
if (block) {
block(localContext);
}
[localContext MR_saveWithOptions:MRSaveParentContexts completion:completion];
}];
}
+ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;
{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext performBlockAndWait:^{
[localContext MR_setWorkingName:NSStringFromSelector(_cmd)];
if (block) {
block(localContext);
}
[localContext MR_saveWithOptions:MRSaveParentContexts|MRSaveSynchronously completion:nil];
}];
}
+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block
{
[[self class] saveWithBlock:block completion:nil];
}
+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))completion
{
NSManagedObjectContext *savingContext = [NSManagedObjectContext MR_rootSavingContext];
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextWithParent:savingContext];
[localContext performBlock:^{
[localContext MR_setWorkingName:NSStringFromSelector(_cmd)];
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:^{
[localContext MR_setWorkingName:NSStringFromSelector(_cmd)];
if (block) {
block(localContext);
}
[localContext MR_saveToPersistentStoreWithCompletion:^(BOOL contextDidSave, NSError *error) {
if (contextDidSave) {
if (completion) {
completion();
}
}
else {
if (errorHandler) {
errorHandler(error);
}
}
}];
}];
}
@end

Просмотреть файл

@ -1,21 +0,0 @@
//
// 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/MagicalRecordInternal.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface MagicalRecord (ErrorHandling)
+ (void) handleErrors:(MR_nonnull NSError *)error;
- (void) handleErrors:(MR_nonnull NSError *)error;
+ (void) setErrorHandlerTarget:(MR_nullable id)target action:(MR_nonnull SEL)action;
+ (MR_nonnull SEL) errorHandlerAction;
+ (MR_nullable id) errorHandlerTarget;
@end

Просмотреть файл

@ -1,95 +0,0 @@
//
// 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"
#import "MagicalRecordLogging.h"
__weak 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)])
{
MRLogError(@"Error Details: %@", [e userInfo]);
}
else
{
MRLogError(@"Error Details: %@", e);
}
}
}
else
{
MRLogError(@"Error: %@", detailedError);
}
}
MRLogError(@"Error Message: %@", [error localizedDescription]);
MRLogError(@"Error Domain: %@", [error domain]);
MRLogError(@"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

Просмотреть файл

@ -1,148 +0,0 @@
//
// 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/MagicalRecordInternal.h>
/**
Defines "levels" of logging that will be used as values in a bitmask that filters log messages.
@since Available in v2.3 and later.
*/
typedef NS_ENUM (NSUInteger, MagicalRecordLoggingMask)
{
/** Log all errors */
MagicalRecordLoggingMaskError = 1 << 0,
/** Log warnings, and all errors */
MagicalRecordLoggingMaskWarn = 1 << 1,
/** Log informative messagess, warnings and all errors */
MagicalRecordLoggingMaskInfo = 1 << 2,
/** Log debugging messages, informative messages, warnings and all errors */
MagicalRecordLoggingMaskDebug = 1 << 3,
/** Log verbose diagnostic information, debugging messages, informative messages, messages, warnings and all errors */
MagicalRecordLoggingMaskVerbose = 1 << 4,
};
/**
Defines a mask for logging that will be used by to filter log messages.
@since Available in v2.3 and later.
*/
typedef NS_ENUM (NSUInteger, MagicalRecordLoggingLevel)
{
/** Don't log anything */
MagicalRecordLoggingLevelOff = 0,
/** Log all errors and fatal messages */
MagicalRecordLoggingLevelError = (MagicalRecordLoggingMaskError),
/** Log warnings, errors and fatal messages */
MagicalRecordLoggingLevelWarn = (MagicalRecordLoggingLevelError | MagicalRecordLoggingMaskWarn),
/** Log informative, warning and error messages */
MagicalRecordLoggingLevelInfo = (MagicalRecordLoggingLevelWarn | MagicalRecordLoggingMaskInfo),
/** Log all debugging, informative, warning and error messages */
MagicalRecordLoggingLevelDebug = (MagicalRecordLoggingLevelInfo | MagicalRecordLoggingMaskDebug),
/** Log verbose diagnostic, debugging, informative, warning and error messages */
MagicalRecordLoggingLevelVerbose = (MagicalRecordLoggingLevelDebug | MagicalRecordLoggingMaskVerbose),
/** Log everything */
MagicalRecordLoggingLevelAll = NSUIntegerMax
};
@interface MagicalRecord (Options)
/**
@name Configuration Options
*/
/**
If this is true, the default managed object model will be automatically created if it doesn't exist when calling `[NSManagedObjectModel MR_defaultManagedObjectModel]`.
@return current value of shouldAutoCreateManagedObjectModel.
@since Available in v2.0.4 and later.
*/
+ (BOOL) shouldAutoCreateManagedObjectModel;
/**
Setting this to true will make MagicalRecord create the default managed object model automatically if it doesn't exist when calling `[NSManagedObjectModel MR_defaultManagedObjectModel]`.
@param autoCreate BOOL value that flags whether the default persistent store should be automatically created.
@since Available in v2.0.4 and later.
*/
+ (void) setShouldAutoCreateManagedObjectModel:(BOOL)autoCreate;
/**
If this is true, the default persistent store will be automatically created if it doesn't exist when calling `[NSPersistentStoreCoordinator MR_defaultStoreCoordinator]`.
@return current value of shouldAutoCreateDefaultPersistentStoreCoordinator.
@since Available in v2.0.4 and later.
*/
+ (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator;
/**
Setting this to true will make MagicalRecord create the default persistent store automatically if it doesn't exist when calling `[NSPersistentStoreCoordinator MR_defaultStoreCoordinator]`.
@param autoCreate BOOL value that flags whether the default persistent store should be automatically created.
@since Available in v2.0.4 and later.
*/
+ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)autoCreate;
/**
If this is true and MagicalRecord encounters a store with a version that does not match that of the model, the store will be removed from the disk.
This is extremely useful during development where frequent model changes can potentially require a delete and reinstall of the app.
@return current value of shouldDeleteStoreOnModelMismatch
@since Available in v2.0.4 and later.
*/
+ (BOOL) shouldDeleteStoreOnModelMismatch;
/**
Setting this to true will make MagicalRecord delete any stores that it encounters which do not match the version of their model.
This is extremely useful during development where frequent model changes can potentially require a delete and reinstall of the app.
@param shouldDelete BOOL value that flags whether mismatched stores should be deleted
@since Available in v2.0.4 and later.
*/
+ (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDelete;
/**
@name Logging Levels
*/
/**
Returns the logging mask set for MagicalRecord in the current application.
@return Current MagicalRecordLoggingLevel
@since Available in v2.3 and later.
*/
+ (MagicalRecordLoggingLevel) loggingLevel;
/**
Sets the logging mask set for MagicalRecord in the current application.
@param level Any value from MagicalRecordLogLevel
@since Available in v2.3 and later.
*/
+ (void) setLoggingLevel:(MagicalRecordLoggingLevel)level;
@end

Просмотреть файл

@ -1,64 +0,0 @@
//
// 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"
#ifdef DEBUG
static MagicalRecordLoggingLevel kMagicalRecordLoggingLevel = MagicalRecordLoggingLevelDebug;
#else
static MagicalRecordLoggingLevel kMagicalRecordLoggingLevel = MagicalRecordLoggingLevelError;
#endif
static BOOL kMagicalRecordShouldAutoCreateManagedObjectModel = NO;
static BOOL kMagicalRecordShouldAutoCreateDefaultPersistentStoreCoordinator = NO;
static BOOL kMagicalRecordShouldDeleteStoreOnModelMismatch = NO;
@implementation MagicalRecord (Options)
#pragma mark - Configuration Options
+ (BOOL) shouldAutoCreateManagedObjectModel;
{
return kMagicalRecordShouldAutoCreateManagedObjectModel;
}
+ (void) setShouldAutoCreateManagedObjectModel:(BOOL)autoCreate;
{
kMagicalRecordShouldAutoCreateManagedObjectModel = autoCreate;
}
+ (BOOL) shouldAutoCreateDefaultPersistentStoreCoordinator;
{
return kMagicalRecordShouldAutoCreateDefaultPersistentStoreCoordinator;
}
+ (void) setShouldAutoCreateDefaultPersistentStoreCoordinator:(BOOL)autoCreate;
{
kMagicalRecordShouldAutoCreateDefaultPersistentStoreCoordinator = autoCreate;
}
+ (BOOL) shouldDeleteStoreOnModelMismatch;
{
return kMagicalRecordShouldDeleteStoreOnModelMismatch;
}
+ (void) setShouldDeleteStoreOnModelMismatch:(BOOL)shouldDelete;
{
kMagicalRecordShouldDeleteStoreOnModelMismatch = shouldDelete;
}
+ (MagicalRecordLoggingLevel) loggingLevel;
{
return kMagicalRecordLoggingLevel;
}
+ (void) setLoggingLevel:(MagicalRecordLoggingLevel)level;
{
kMagicalRecordLoggingLevel = level;
}
@end

Просмотреть файл

@ -1,25 +0,0 @@
//
// 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/MagicalRecordInternal.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface MagicalRecord (Setup)
+ (void) setupCoreDataStack;
+ (void) setupCoreDataStackWithInMemoryStore;
+ (void) setupAutoMigratingCoreDataStack;
+ (void) setupCoreDataStackWithStoreNamed:(MR_nonnull NSString *)storeName;
+ (void) setupCoreDataStackWithAutoMigratingSqliteStoreNamed:(MR_nonnull NSString *)storeName;
+ (void) setupCoreDataStackWithStoreAtURL:(MR_nonnull NSURL *)storeURL;
+ (void) setupCoreDataStackWithAutoMigratingSqliteStoreAtURL:(MR_nonnull NSURL *)storeURL;
@end

Просмотреть файл

@ -1,76 +0,0 @@
//
// 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) setupCoreDataStackWithStoreAtURL:(NSURL *)storeURL
{
if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return;
NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithSqliteStoreAtURL:storeURL];
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
[NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator];
}
+ (void) setupCoreDataStackWithAutoMigratingSqliteStoreAtURL:(NSURL *)storeURL
{
if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return;
NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithAutoMigratingSqliteStoreAtURL:storeURL];
[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

Просмотреть файл

@ -1,10 +0,0 @@
//
// Copyright (c) 2015 Magical Panda Software LLC. All rights reserved.
#import <MagicalRecord/MagicalRecord.h>
@interface MagicalRecord (ShorthandMethods)
+ (void)enableShorthandMethods;
@end

Просмотреть файл

@ -1,134 +0,0 @@
//
// Copyright (c) 2015 Magical Panda Software LLC. All rights reserved.
#import "MagicalRecord+ShorthandMethods.h"
#import <objc/runtime.h>
static NSString *const kMagicalRecordCategoryPrefix = @"MR_";
static BOOL kMagicalRecordShorthandMethodsSwizzled = NO;
@implementation MagicalRecord (ShorthandMethods)
+ (void)enableShorthandMethods
{
if (kMagicalRecordShorthandMethodsSwizzled == NO)
{
NSArray *classes = [self classesToSwizzle];
[classes enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) {
Class objectClass = (Class)object;
[self updateResolveMethodsForClass:objectClass];
}];
kMagicalRecordShorthandMethodsSwizzled = YES;
}
}
+ (NSArray *)classesToSwizzle
{
return @[ [NSManagedObject class],
[NSManagedObjectContext class],
[NSManagedObjectModel class],
[NSPersistentStore class],
[NSPersistentStoreCoordinator class] ];
}
+ (NSArray *)methodNameBlacklist
{
return @[ NSStringFromSelector(@selector(entityName)) ];
}
+ (BOOL)MR_resolveClassMethod:(SEL)originalSelector
{
BOOL resolvedClassMethod = [self MR_resolveClassMethod:originalSelector];
if (!resolvedClassMethod)
{
resolvedClassMethod = MRAddShortHandMethodForPrefixedClassMethod(self, originalSelector, kMagicalRecordCategoryPrefix);
}
return resolvedClassMethod;
}
+ (BOOL)MR_resolveInstanceMethod:(SEL)originalSelector
{
BOOL resolvedClassMethod = [self MR_resolveInstanceMethod:originalSelector];
if (!resolvedClassMethod)
{
resolvedClassMethod = MRAddShorthandMethodForPrefixedInstanceMethod(self, originalSelector, kMagicalRecordCategoryPrefix);
}
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)objectClass
{
MRReplaceSelectorForTargetWithSourceImplementation(self, @selector(MR_resolveClassMethod:), objectClass, @selector(resolveClassMethod:));
MRReplaceSelectorForTargetWithSourceImplementation(self, @selector(MR_resolveInstanceMethod:), objectClass, @selector(resolveInstanceMethod:));
}
static void MRReplaceSelectorForTargetWithSourceImplementation(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));
}
}
static BOOL MRAddShorthandMethodForPrefixedInstanceMethod(Class objectClass, SEL originalSelector, NSString *prefix)
{
NSString *originalSelectorString = NSStringFromSelector(originalSelector);
if ([originalSelectorString hasPrefix:prefix] == NO)
{
NSString *prefixedSelector = [prefix stringByAppendingString:originalSelectorString];
Method existingMethod = class_getInstanceMethod(objectClass, NSSelectorFromString(prefixedSelector));
if (existingMethod)
{
BOOL methodWasAdded = class_addMethod(objectClass,
originalSelector,
method_getImplementation(existingMethod),
method_getTypeEncoding(existingMethod));
return methodWasAdded;
}
}
return NO;
}
static BOOL MRAddShortHandMethodForPrefixedClassMethod(Class objectClass, SEL originalSelector, NSString *prefix)
{
NSString *originalSelectorString = NSStringFromSelector(originalSelector);
if ([originalSelectorString hasPrefix:prefix] == NO &&
[originalSelectorString hasSuffix:@"entityName"] == NO)
{
NSString *prefixedSelector = [prefix stringByAppendingString:originalSelectorString];
Method existingMethod = class_getClassMethod(objectClass, NSSelectorFromString(prefixedSelector));
if (existingMethod)
{
Class metaClass = objc_getMetaClass([NSStringFromClass(objectClass) cStringUsingEncoding:NSUTF8StringEncoding]);
BOOL methodWasAdded = class_addMethod(metaClass,
originalSelector,
method_getImplementation(existingMethod),
method_getTypeEncoding(existingMethod));
return methodWasAdded;
}
}
return NO;
}
@end

Просмотреть файл

@ -1,44 +0,0 @@
//
// 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/MagicalRecordInternal.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface MagicalRecord (iCloud)
+ (BOOL)isICloudEnabled;
+ (void)setupCoreDataStackWithiCloudContainer:(MR_nonnull NSString *)containerID
localStoreNamed:(MR_nonnull NSString *)localStore;
+ (void)setupCoreDataStackWithiCloudContainer:(MR_nonnull NSString *)containerID
contentNameKey:(MR_nullable NSString *)contentNameKey
localStoreNamed:(MR_nonnull NSString *)localStoreName
cloudStorePathComponent:(MR_nullable NSString *)pathSubcomponent;
+ (void)setupCoreDataStackWithiCloudContainer:(MR_nonnull NSString *)containerID
contentNameKey:(MR_nullable NSString *)contentNameKey
localStoreNamed:(MR_nonnull NSString *)localStoreName
cloudStorePathComponent:(MR_nullable NSString *)pathSubcomponent
completion:(void (^ __MR_nullable)(void))completion;
+ (void)setupCoreDataStackWithiCloudContainer:(MR_nonnull NSString *)containerID
localStoreAtURL:(MR_nonnull NSURL *)storeURL;
+ (void)setupCoreDataStackWithiCloudContainer:(MR_nonnull NSString *)containerID
contentNameKey:(MR_nullable NSString *)contentNameKey
localStoreAtURL:(MR_nonnull NSURL *)storeURL
cloudStorePathComponent:(MR_nullable NSString *)pathSubcomponent;
+ (void)setupCoreDataStackWithiCloudContainer:(MR_nonnull NSString *)containerID
contentNameKey:(MR_nullable NSString *)contentNameKey
localStoreAtURL:(MR_nonnull NSURL *)storeURL
cloudStorePathComponent:(MR_nullable NSString *)pathSubcomponent
completion:(void (^ __MR_nullable)(void))completion;
@end

Просмотреть файл

@ -1,86 +0,0 @@
//
// 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 *)containerID localStoreNamed:(NSString *)localStore;
{
[self setupCoreDataStackWithiCloudContainer:containerID
contentNameKey:nil
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];
}
+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID localStoreAtURL:(NSURL *)storeURL
{
NSString *contentNameKey = [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleIdentifierKey];
[self setupCoreDataStackWithiCloudContainer:containerID
contentNameKey:contentNameKey
localStoreAtURL:storeURL
cloudStorePathComponent:nil];
}
+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)pathSubcomponent
{
[self setupCoreDataStackWithiCloudContainer:containerID
contentNameKey:contentNameKey
localStoreAtURL:storeURL
cloudStorePathComponent:pathSubcomponent
completion:nil];
}
+ (void) setupCoreDataStackWithiCloudContainer:(NSString *)containerID contentNameKey:(NSString *)contentNameKey localStoreAtURL:(NSURL *)storeURL cloudStorePathComponent:(NSString *)pathSubcomponent completion:(void (^)(void))completion
{
NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_coordinatorWithiCloudContainerID:containerID contentNameKey:contentNameKey localStoreAtURL:storeURL cloudStorePathComponent:pathSubcomponent completion:completion];
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];
[NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator];
}
@end

Просмотреть файл

@ -1,7 +0,0 @@
//
// Created by Tony Arnold on 10/04/2014.
// Copyright (c) 2014 Magical Panda Software LLC. All rights reserved.
//
#define MR_DEPRECATED_WILL_BE_REMOVED_IN(VERSION) __attribute__((deprecated("This method has been deprecated and will be removed in MagicalRecord " VERSION ".")))
#define MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE(VERSION, METHOD) __attribute__((deprecated("This method has been deprecated and will be removed in MagicalRecord " VERSION ". Please use `" METHOD "` instead.")))

Просмотреть файл

@ -1,99 +0,0 @@
//
// MagicalRecord.h
//
// Created by Saul Mora on 3/11/10.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
/**
Defines current and historical version numbers for MagicalRecord.
@since Available in v2.3 and later.
*/
typedef NS_ENUM(NSUInteger, MagicalRecordVersionTag)
{
/** Version 2.2.0 */
MagicalRecordVersionTag2_2 = 220,
/** Version 2.3.0 */
MagicalRecordVersionTag2_3 = 230,
/** Version 3.0.0 */
MagicalRecordVersionTag3_0 = 300
};
// enable to use caches for the fetchedResultsControllers (iOS only)
// #define STORE_USE_CACHE
#ifdef NS_BLOCKS_AVAILABLE
OBJC_EXPORT NSString * __MR_nonnull const kMagicalRecordCleanedUpNotification;
@class NSManagedObjectContext;
typedef void (^CoreDataBlock)(NSManagedObjectContext * __MR_nonnull context);
#endif
/**
Provides class methods to help setup, save, handle errors and provide information about the currently loaded version of MagicalRecord.
@since Available in v1.0 and later.
*/
@interface MagicalRecord : NSObject
/**
Returns the current version of MagicalRecord. See the MagicalRecordVersionTag enumeration for valid current and historical values.
@return The current version as a double.
@since Available in v2.3 and later.
*/
+ (MagicalRecordVersionTag) version;
/**
Provides information about the current stack, including the model, coordinator, persistent store, the default context and any parent contexts of the default context.
@return Description of the current state of the stack.
@since Available in v2.3 and later.
*/
+ (MR_nonnull NSString *) currentStack;
/**
Cleans up the entire MagicalRecord stack. Sets the default model, store and context to nil before posting a kMagicalRecordCleanedUpNotification notification.
@since Available in v1.0 and later.
*/
+ (void) cleanUp;
/**
Calls NSBundle's -bundleForClass: to determine the bundle to search for the default model within.
@param modelClass Class to set the model from
@since Available in v2.0 and later.
*/
+ (void) setDefaultModelFromClass:(MR_nonnull Class)modelClass;
/**
Looks for a momd file with the specified name, and if found sets it as the default model.
@param modelName Model name as a string, including file extension
@since Available in v1.0 and later.
*/
+ (void) setDefaultModelNamed:(MR_nonnull NSString *)modelName;
/**
Determines the store file name your app should use. This method is used by the MagicalRecord SQLite stacks when a store file is not specified. The file name returned is in the form "<ApplicationName>.sqlite". `<ApplicationName>` is taken from the application's info dictionary, which is retrieved from the method [[NSBundle mainBundle] infoDictionary]. If no bundle name is available, "CoreDataStore.sqlite" will be used.
@return String of the form <ApplicationName>.sqlite
@since Available in v2.0 and later.
*/
+ (MR_nonnull NSString *) defaultStoreName;
@end

Просмотреть файл

@ -1,111 +0,0 @@
//
// MagicalRecord.m
//
// Created by Saul Mora on 3/11/10.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import "MagicalRecord.h"
NSString * const kMagicalRecordCleanedUpNotification = @"kMagicalRecordCleanedUpNotification";
@interface MagicalRecord (Internal)
+ (void) cleanUpStack;
+ (void) cleanUpErrorHanding;
@end
@interface NSManagedObjectContext (MagicalRecordInternal)
+ (void) MR_cleanUp;
@end
@implementation MagicalRecord
+ (MagicalRecordVersionTag) version
{
return MagicalRecordVersionTag2_3;
}
+ (void) cleanUp
{
[self cleanUpErrorHanding];
[self cleanUpStack];
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter postNotificationName:kMagicalRecordCleanedUpNotification
object:nil
userInfo:nil];
}
+ (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)modelClass;
{
NSBundle *bundle = [NSBundle bundleForClass:modelClass];
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])
{
[self setShouldAutoCreateManagedObjectModel:YES];
[self setShouldAutoCreateDefaultPersistentStoreCoordinator:NO];
#ifdef DEBUG
[self setShouldDeleteStoreOnModelMismatch:YES];
#else
[self setShouldDeleteStoreOnModelMismatch:NO];
#endif
}
}
@end

Просмотреть файл

@ -1,49 +0,0 @@
//
// MagicalRecordLogging.h
// MagicalRecord
//
// Created by Saul Mora on 10/4/13.
// Copyright (c) 2013 Magical Panda Software LLC. All rights reserved.
//
#import <MagicalRecord/MagicalRecord+Options.h>
#if MR_LOGGING_DISABLED
#define MRLogError(frmt, ...) ((void)0)
#define MRLogWarn(frmt, ...) ((void)0)
#define MRLogInfo(frmt, ...) ((void)0)
#define MRLogDebug(frmt, ...) ((void)0)
#define MRLogVerbose(frmt, ...) ((void)0)
#else
#ifndef MR_LOGGING_CONTEXT
#define MR_LOGGING_CONTEXT 0
#endif
#if __has_include("CocoaLumberjack.h") || __has_include("CocoaLumberjack/CocoaLumberjack.h")
#define MR_LOG_LEVEL_DEF (DDLogLevel)[MagicalRecord loggingLevel]
#define CAST (DDLogFlag)
#import <CocoaLumberjack/CocoaLumberjack.h>
#else
#define MR_LOG_LEVEL_DEF [MagicalRecord loggingLevel]
#define LOG_ASYNC_ENABLED YES
#define CAST
#define LOG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
do \
{ \
if ((lvl & flg) == flg) \
{ \
NSLog(frmt, ##__VA_ARGS__); \
} \
} while (0)
#endif
#define MRLogError(frmt, ...) LOG_MAYBE(NO, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskError, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define MRLogWarn(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskWarn, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define MRLogInfo(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskInfo, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define MRLogDebug(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskDebug, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define MRLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, MR_LOG_LEVEL_DEF, CAST MagicalRecordLoggingMaskVerbose, MR_LOGGING_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#endif

Просмотреть файл

@ -1,328 +0,0 @@
#import <MagicalRecord/MagicalRecord.h>
#import <MagicalRecord/MagicalRecordDeprecationMacros.h>
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
@interface NSManagedObject (MagicalAggregationShortHand)
+ (MR_nonnull NSNumber *) numberOfEntities;
+ (MR_nonnull NSNumber *) numberOfEntitiesWithContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSNumber *) numberOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSNumber *) numberOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (NSUInteger) countOfEntities;
+ (NSUInteger) countOfEntitiesWithContext:(MR_nonnull NSManagedObjectContext *)context;
+ (NSUInteger) countOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchFilter;
+ (NSUInteger) countOfEntitiesWithPredicate:(MR_nullable NSPredicate *)searchFilter inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (BOOL) hasAtLeastOneEntity;
+ (BOOL) hasAtLeastOneEntityInContext:(MR_nonnull NSManagedObjectContext *)context;
- (MR_nullable id) minValueFor:(MR_nonnull NSString *)property;
- (MR_nullable id) maxValueFor:(MR_nonnull NSString *)property;
+ (MR_nullable id) aggregateOperation:(MR_nonnull NSString *)function onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable id) aggregateOperation:(MR_nonnull NSString *)function onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate;
+ (MR_nullable NSArray *) aggregateOperation:(MR_nonnull NSString *)collectionOperator onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate groupBy:(MR_nullable NSString*)groupingKeyPath inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable NSArray *) aggregateOperation:(MR_nonnull NSString *)collectionOperator onAttribute:(MR_nonnull NSString *)attributeName withPredicate:(MR_nullable NSPredicate *)predicate groupBy:(MR_nullable NSString*)groupingKeyPath;
- (MR_nullable instancetype) objectWithMinValueFor:(MR_nonnull NSString *)property;
- (MR_nullable instancetype) objectWithMinValueFor:(MR_nonnull NSString *)property inContext:(MR_nonnull NSManagedObjectContext *)context;
@end
@interface NSManagedObject (MagicalRecord_DataImportShortHand)
- (BOOL) importValuesForKeysWithObject:(MR_nonnull id)objectData;
+ (MR_nonnull instancetype) importFromObject:(MR_nonnull id)data;
+ (MR_nonnull instancetype) importFromObject:(MR_nonnull id)data inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull MR_NSArrayOfNSManagedObjects) importFromArray:(MR_nonnull MR_GENERIC(NSArray, NSDictionary *) *)listOfObjectData;
+ (MR_nonnull MR_NSArrayOfNSManagedObjects) importFromArray:(MR_nonnull MR_GENERIC(NSArray, NSDictionary *) *)listOfObjectData inContext:(MR_nonnull NSManagedObjectContext *)context;
@end
@interface NSManagedObject (MagicalFindersShortHand)
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findAll;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findAllInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findAllWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findAllWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) findFirst;
+ (MR_nullable instancetype) findFirstInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nullable instancetype) findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) findFirstWithPredicate:(MR_nullable NSPredicate *)searchterm sortedBy:(MR_nullable NSString *)property ascending:(BOOL)ascending;
+ (MR_nullable instancetype) findFirstWithPredicate:(MR_nullable NSPredicate *)searchterm sortedBy:(MR_nullable NSString *)property ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm andRetrieveAttributes:(MR_nullable NSArray *)attributes;
+ (MR_nullable instancetype) findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm andRetrieveAttributes:(MR_nullable NSArray *)attributes inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(MR_nullable id)attributes, ...;
+ (MR_nullable instancetype) findFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortBy ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context andRetrieveAttributes:(MR_nullable id)attributes, ...;
+ (MR_nullable instancetype) findFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue;
+ (MR_nullable instancetype) findFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) findFirstOrderedByAttribute:(MR_nonnull NSString *)attribute ascending:(BOOL)ascending;
+ (MR_nullable instancetype) findFirstOrderedByAttribute:(MR_nonnull NSString *)attribute ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull instancetype) findFirstOrCreateByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue;
+ (MR_nonnull instancetype) findFirstOrCreateByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue andOrderBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) findByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nonnull id)searchValue andOrderBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) fetchController:(MR_nonnull NSFetchRequest *)request delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate useFileCache:(BOOL)useFileCache groupedBy:(MR_nullable NSString *)groupKeyPath inContext:(MR_nonnull NSManagedObjectContext *)context;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) fetchAllWithDelegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) fetchAllWithDelegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate inContext:(MR_nonnull NSManagedObjectContext *)context;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) fetchAllSortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm groupBy:(MR_nullable NSString *)groupingKeyPath delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) fetchAllSortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm groupBy:(MR_nullable NSString *)groupingKeyPath delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate inContext:(MR_nonnull NSManagedObjectContext *)context;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (MR_nonnull NSFetchedResultsController *) fetchAllGroupedBy:(MR_nullable NSString *)group withPredicate:(MR_nullable NSPredicate *)searchTerm sortedBy:(MR_nullable NSString *)sortTerm ascending:(BOOL)ascending delegate:(MR_nullable id<NSFetchedResultsControllerDelegate>)delegate inContext:(MR_nonnull NSManagedObjectContext *)context;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
@end
@interface NSManagedObject (MagicalRecordShortHand)
+ (MR_nonnull NSString *) entityName;
+ (NSUInteger) defaultBatchSize;
+ (void) setDefaultBatchSize:(NSUInteger)newBatchSize;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) executeFetchRequest:(MR_nonnull NSFetchRequest *)request;
+ (MR_nullable MR_NSArrayOfNSManagedObjects) executeFetchRequest:(MR_nonnull NSFetchRequest *)request inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) executeFetchRequestAndReturnFirstObject:(MR_nonnull NSFetchRequest *)request;
+ (MR_nullable instancetype) executeFetchRequestAndReturnFirstObject:(MR_nonnull NSFetchRequest *)request inContext:(MR_nonnull NSManagedObjectContext *)context;
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ (BOOL) performFetch:(MR_nonnull NSFetchedResultsController *)controller;
#endif /* TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR */
+ (MR_nullable NSEntityDescription *) entityDescription;
+ (MR_nullable NSEntityDescription *) entityDescriptionInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable MR_GENERIC(NSArray, NSPropertyDescription *) *) propertiesNamed:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)properties;
+ (MR_nullable MR_GENERIC(NSArray, NSPropertyDescription *) *) propertiesNamed:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)properties inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nullable instancetype) createEntity;
+ (MR_nullable instancetype) createEntityInContext:(MR_nonnull NSManagedObjectContext *)context;
- (BOOL) deleteEntity;
- (BOOL) deleteEntityInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (BOOL) deleteAllMatchingPredicate:(MR_nonnull NSPredicate *)predicate;
+ (BOOL) deleteAllMatchingPredicate:(MR_nonnull NSPredicate *)predicate inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (BOOL) truncateAll;
+ (BOOL) truncateAllInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull MR_GENERIC(NSArray, NSSortDescriptor *) *) ascendingSortDescriptors:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)attributesToSortBy;
+ (MR_nonnull MR_GENERIC(NSArray, NSSortDescriptor *) *) descendingSortDescriptors:(MR_nonnull MR_GENERIC(NSArray, NSString *) *)attributesToSortBy;
- (MR_nullable instancetype) inContext:(MR_nonnull NSManagedObjectContext *)otherContext;
- (MR_nullable instancetype) inThreadContext;
@end
@interface NSManagedObject (MagicalRecordDeprecatedShortHand)
+ (MR_nullable instancetype) createInContext:(MR_nonnull NSManagedObjectContext *)context MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_createEntityInContext:");
- (BOOL) deleteInContext:(MR_nonnull NSManagedObjectContext *)context MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_deleteEntityInContext:");
@end
@interface NSManagedObject (MagicalRequestsShortHand)
+ (MR_nonnull NSFetchRequest *) createFetchRequest;
+ (MR_nonnull NSFetchRequest *) createFetchRequestInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) requestAll;
+ (MR_nonnull NSFetchRequest *) requestAllInContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) requestAllWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSFetchRequest *) requestAllWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) requestAllWhere:(MR_nonnull NSString *)property isEqualTo:(MR_nonnull id)value;
+ (MR_nonnull NSFetchRequest *) requestAllWhere:(MR_nonnull NSString *)property isEqualTo:(MR_nonnull id)value inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) requestFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSFetchRequest *) requestFirstWithPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) requestFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nullable id)searchValue;
+ (MR_nonnull NSFetchRequest *) requestFirstByAttribute:(MR_nonnull NSString *)attribute withValue:(MR_nullable id)searchValue inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending;
+ (MR_nonnull NSFetchRequest *) requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending inContext:(MR_nonnull NSManagedObjectContext *)context;
+ (MR_nonnull NSFetchRequest *) requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm;
+ (MR_nonnull NSFetchRequest *) requestAllSortedBy:(MR_nonnull NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(MR_nullable NSPredicate *)searchTerm inContext:(MR_nonnull NSManagedObjectContext *)context;
@end
@interface NSManagedObjectContext (MagicalRecordChainSaveShortHand)
- (void)saveWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block;
- (void)saveWithBlock:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block completion:(MR_nullable MRSaveCompletionHandler)completion;
- (void)saveWithBlockAndWait:(void (^ __MR_nonnull)(NSManagedObjectContext * __MR_nonnull localContext))block;
@end
@interface NSManagedObjectContext (MagicalObservingShortHand)
- (void) observeContext:(MR_nonnull NSManagedObjectContext *)otherContext;
- (void) stopObservingContext:(MR_nonnull NSManagedObjectContext *)otherContext;
- (void) observeContextOnMainThread:(MR_nonnull NSManagedObjectContext *)otherContext;
- (void) observeiCloudChangesInCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
- (void) stopObservingiCloudChangesInCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
@end
@interface NSManagedObjectContext (MagicalRecordShortHand)
+ (void) initializeDefaultContextWithCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
+ (MR_nonnull NSManagedObjectContext *) rootSavingContext;
+ (MR_nonnull NSManagedObjectContext *) defaultContext;
+ (MR_nonnull NSManagedObjectContext *) context;
+ (MR_nonnull NSManagedObjectContext *) contextWithParent:(MR_nonnull NSManagedObjectContext *)parentContext;
+ (MR_nonnull NSManagedObjectContext *) contextWithStoreCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator;
+ (MR_nonnull NSManagedObjectContext *) newMainQueueContext NS_RETURNS_RETAINED;
+ (MR_nonnull NSManagedObjectContext *) newPrivateQueueContext NS_RETURNS_RETAINED;
- (void) setWorkingName:(MR_nonnull NSString *)workingName;
- (MR_nonnull NSString *) workingName;
- (MR_nonnull NSString *) description;
- (MR_nonnull NSString *) parentChain;
+ (void) resetDefaultContext;
- (void) deleteObjects:(MR_nonnull id <NSFastEnumeration>)objects;
@end
@interface NSManagedObjectContext (MagicalRecordDeprecatedShortHand)
+ (MR_nonnull NSManagedObjectContext *) contextWithoutParent MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_newPrivateQueueContext");
+ (MR_nonnull NSManagedObjectContext *) newContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_context");
+ (MR_nonnull NSManagedObjectContext *) newContextWithParent:(MR_nonnull NSManagedObjectContext *)parentContext MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithParent:");
+ (MR_nonnull NSManagedObjectContext *) newContextWithStoreCoordinator:(MR_nonnull NSPersistentStoreCoordinator *)coordinator MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "MR_contextWithStoreCoordinator:");
@end
@interface NSManagedObjectContext (MagicalSavesShortHand)
- (void) saveOnlySelfWithCompletion:(MR_nullable MRSaveCompletionHandler)completion;
- (void) saveToPersistentStoreWithCompletion:(MR_nullable MRSaveCompletionHandler)completion;
- (void) saveOnlySelfAndWait;
- (void) saveToPersistentStoreAndWait;
- (void) saveWithOptions:(MRSaveOptions)saveOptions completion:(MR_nullable MRSaveCompletionHandler)completion;
@end
@interface NSManagedObjectContext (MagicalSavesDeprecatedShortHand)
- (void) save MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreAndWait");
- (void) saveWithErrorCallback:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
- (void) saveInBackgroundCompletion:(void (^ __MR_nullable)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
- (void) saveInBackgroundErrorHandler:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
- (void) saveInBackgroundErrorHandler:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback completion:(void (^ __MR_nullable)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN("3.0");
- (void) saveNestedContexts MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:");
- (void) saveNestedContextsErrorHandler:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:");
- (void) saveNestedContextsErrorHandler:(void (^ __MR_nullable)(NSError * __MR_nullable error))errorCallback completion:(void (^ __MR_nullable)(void))completion MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("3.0", "MR_saveToPersistentStoreWithCompletion:");
@end
@interface NSManagedObjectContext (MagicalThreadingShortHand)
+ (MR_nonnull NSManagedObjectContext *) contextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0")));
+ (void) clearNonMainThreadContextsCache __attribute((deprecated("This method will be removed in MagicalRecord 3.0")));
+ (void) resetContextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0")));
+ (void) clearContextForCurrentThread __attribute((deprecated("This method will be removed in MagicalRecord 3.0")));
@end
@interface NSManagedObjectModel (MagicalRecordShortHand)
+ (MR_nullable NSManagedObjectModel *) defaultManagedObjectModel;
+ (void) setDefaultManagedObjectModel:(MR_nullable NSManagedObjectModel *)newDefaultModel;
+ (MR_nullable NSManagedObjectModel *) mergedObjectModelFromMainBundle;
+ (MR_nullable NSManagedObjectModel *) newManagedObjectModelNamed:(MR_nonnull NSString *)modelFileName NS_RETURNS_RETAINED;
+ (MR_nullable NSManagedObjectModel *) managedObjectModelNamed:(MR_nonnull NSString *)modelFileName;
+ (MR_nullable NSManagedObjectModel *) newModelNamed:(MR_nonnull NSString *) modelName inBundleNamed:(MR_nonnull NSString *) bundleName NS_RETURNS_RETAINED;
+ (MR_nullable NSManagedObjectModel *) newModelNamed:(MR_nonnull NSString *) modelName inBundle:(MR_nonnull NSBundle*) bundle NS_RETURNS_RETAINED;
@end
@interface NSPersistentStore (MagicalRecordShortHand)
+ (MR_nonnull NSURL *) defaultLocalStoreUrl;
+ (MR_nullable NSPersistentStore *) defaultPersistentStore;
+ (void) setDefaultPersistentStore:(MR_nullable NSPersistentStore *) store;
+ (MR_nullable NSURL *) urlForStoreName:(MR_nonnull NSString *)storeFileName;
+ (MR_nullable NSURL *) cloudURLForUbiquitousContainer:(MR_nonnull NSString *)bucketName;
+ (MR_nullable NSURL *) cloudURLForUbiqutiousContainer:(MR_nonnull NSString *)bucketName MR_DEPRECATED_WILL_BE_REMOVED_IN_PLEASE_USE("4.0", "cloudURLForUbiquitousContainer:");
@end
@interface NSPersistentStoreCoordinator (MagicalRecordShortHand)
+ (MR_nullable NSPersistentStoreCoordinator *) defaultStoreCoordinator;
+ (void) setDefaultStoreCoordinator:(MR_nullable NSPersistentStoreCoordinator *)coordinator;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithInMemoryStore;
+ (MR_nonnull NSPersistentStoreCoordinator *) newPersistentStoreCoordinator NS_RETURNS_RETAINED;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithSqliteStoreNamed:(MR_nonnull NSString *)storeFileName;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithAutoMigratingSqliteStoreNamed:(MR_nonnull NSString *)storeFileName;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithSqliteStoreAtURL:(MR_nonnull NSURL *)storeURL;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithAutoMigratingSqliteStoreAtURL:(MR_nonnull NSURL *)storeURL;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithPersistentStore:(MR_nonnull NSPersistentStore *)persistentStore;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreNamed:(MR_nonnull NSString *)localStoreName cloudStorePathComponent:(MR_nullable NSString *)subPathComponent;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreAtURL:(MR_nonnull NSURL *)storeURL cloudStorePathComponent:(MR_nullable NSString *)subPathComponent;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreNamed:(MR_nonnull NSString *)localStoreName cloudStorePathComponent:(MR_nullable NSString *)subPathComponent completion:(void (^ __MR_nullable)(void))completionHandler;
+ (MR_nonnull NSPersistentStoreCoordinator *) coordinatorWithiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreAtURL:(MR_nonnull NSURL *)storeURL cloudStorePathComponent:(MR_nullable NSString *)subPathComponent completion:(void (^ __MR_nullable)(void))completionHandler;
- (MR_nullable NSPersistentStore *) addInMemoryStore;
- (MR_nullable NSPersistentStore *) addAutoMigratingSqliteStoreNamed:(MR_nonnull NSString *) storeFileName;
- (MR_nullable NSPersistentStore *) addAutoMigratingSqliteStoreAtURL:(MR_nonnull NSURL *)storeURL;
- (MR_nullable NSPersistentStore *) addSqliteStoreNamed:(MR_nonnull id)storeFileName withOptions:(MR_nullable __autoreleasing NSDictionary *)options;
- (MR_nullable NSPersistentStore *) addSqliteStoreNamed:(MR_nonnull id)storeFileName configuration:(MR_nullable NSString *)configuration withOptions:(MR_nullable __autoreleasing NSDictionary *)options;
- (void) addiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreNamed:(MR_nonnull NSString *)localStoreName cloudStorePathComponent:(MR_nullable NSString *)subPathComponent;
- (void) addiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreAtURL:(MR_nonnull NSURL *)storeURL cloudStorePathComponent:(MR_nullable NSString *)subPathComponent;
- (void) addiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreNamed:(MR_nonnull NSString *)localStoreName cloudStorePathComponent:(MR_nullable NSString *)subPathComponent completion:(void (^ __MR_nullable)(void))completionBlock;
- (void) addiCloudContainerID:(MR_nonnull NSString *)containerID contentNameKey:(MR_nullable NSString *)contentNameKey localStoreAtURL:(MR_nonnull NSURL *)storeURL cloudStorePathComponent:(MR_nullable NSString *)subPathComponent completion:(void (^ __MR_nullable)(void))completionBlock;
@end

Просмотреть файл

@ -1,41 +0,0 @@
//
// Copyright © 2015 Magical Panda Software LLC. All rights reserved.
//
// The following preprocessor macros can be used to adopt the new nullability annotations and generics
// features available in Xcode 7, while maintaining backwards compatibility with earlier versions of
// Xcode that do not support these features.
//
// Originally taken from https://gist.github.com/smileyborg/d513754bc1cf41678054
#ifndef MagicalRecordXcode7CompatibilityMacros_h
#define MagicalRecordXcode7CompatibilityMacros_h
#if __has_feature(nullability)
#define MR_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
#define MR_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
#define MR_nullable nullable
#define MR_nonnull nonnull
#define __MR_nullable __nullable
#define __MR_nonnull __nonnull
#else
#define MR_ASSUME_NONNULL_BEGIN
#define MR_ASSUME_NONNULL_END
#define MR_nullable
#define MR_nonnull
#define __MR_nullable
#define __MR_nonnull
#endif
#if __has_feature(objc_generics)
#define MR_GENERIC(class, ...) class<__VA_ARGS__>
#define MR_GENERIC_TYPE(type) type
#define __MR_kindof(class) __kindof class
#else
#define MR_GENERIC(class, ...) class
#define MR_GENERIC_TYPE(type) id
#define __MR_kindof(class) id
#endif
#define MR_NSArrayOfNSManagedObjects MR_GENERIC(NSArray, __MR_kindof(NSManagedObject) *) *
#endif /* MagicalRecordXcode7CompatibilityMacros_h */

Просмотреть файл

@ -1,47 +0,0 @@
//
// MagicalRecord.h
//
// Created by Saul Mora on 28/07/10.
// Copyright 2010 Magical Panda Software, LLC All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
//! Project version number for MagicalRecord.
FOUNDATION_EXPORT double MagicalRecordVersionNumber;
//! Project version string for MagicalRecord.
FOUNDATION_EXPORT const unsigned char MagicalRecordVersionString[];
#import <MagicalRecord/MagicalRecordXcode7CompatibilityMacros.h>
#import <MagicalRecord/MagicalRecordInternal.h>
#import <MagicalRecord/MagicalRecordLogging.h>
#import <MagicalRecord/MagicalRecord+Actions.h>
#import <MagicalRecord/MagicalRecord+ErrorHandling.h>
#import <MagicalRecord/MagicalRecord+Options.h>
#import <MagicalRecord/MagicalRecord+Setup.h>
#import <MagicalRecord/MagicalRecord+iCloud.h>
#import <MagicalRecord/NSManagedObject+MagicalRecord.h>
#import <MagicalRecord/NSManagedObject+MagicalRequests.h>
#import <MagicalRecord/NSManagedObject+MagicalFinders.h>
#import <MagicalRecord/NSManagedObject+MagicalAggregation.h>
#import <MagicalRecord/NSManagedObjectContext+MagicalRecord.h>
#import <MagicalRecord/NSManagedObjectContext+MagicalChainSave.h>
#import <MagicalRecord/NSManagedObjectContext+MagicalObserving.h>
#import <MagicalRecord/NSManagedObjectContext+MagicalSaves.h>
#import <MagicalRecord/NSManagedObjectContext+MagicalThreading.h>
#import <MagicalRecord/NSPersistentStoreCoordinator+MagicalRecord.h>
#import <MagicalRecord/NSManagedObjectModel+MagicalRecord.h>
#import <MagicalRecord/NSPersistentStore+MagicalRecord.h>
#import <MagicalRecord/MagicalImportFunctions.h>
#import <MagicalRecord/NSManagedObject+MagicalDataImport.h>
#import <MagicalRecord/NSNumber+MagicalDataImport.h>
#import <MagicalRecord/NSObject+MagicalDataImport.h>
#import <MagicalRecord/NSString+MagicalDataImport.h>
#import <MagicalRecord/NSAttributeDescription+MagicalDataImport.h>
#import <MagicalRecord/NSRelationshipDescription+MagicalDataImport.h>
#import <MagicalRecord/NSEntityDescription+MagicalDataImport.h>

Просмотреть файл

@ -1,41 +0,0 @@
# ![Awesome](https://github.com/magicalpanda/magicalpanda.github.com/blob/master/images/awesome_logo_small.png?raw=true) MagicalRecord
[![Circle CI](https://circleci.com/gh/magicalpanda/MagicalRecord/tree/develop.svg?style=svg)](https://circleci.com/gh/magicalpanda/MagicalRecord/tree/develop)
In software engineering, the active record pattern is a design pattern found in software that stores its data in relational databases. It was named by Martin Fowler in his book Patterns of Enterprise Application Architecture. The interface to such an object would include functions such as Insert, Update, and Delete, plus properties that correspond more-or-less directly to the columns in the underlying database table.
> Active record is an approach to accessing data in a database. A database table or view is wrapped into a class; thus an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save. Any object loaded gets its information from the database; when an object is updated, the corresponding row in the table is also updated. The wrapper class implements accessor methods or properties for each column in the table or view.
> *- [Wikipedia]("http://en.wikipedia.org/wiki/Active_record_pattern")*
MagicalRecord was inspired by the ease of Ruby on Rails' Active Record fetching. The goals of this code are:
* Clean up my Core Data related code
* Allow for clear, simple, one-line fetches
* Still allow the modification of the NSFetchRequest when request optimizations are needed
## Documentation
- [Installation](Docs/Installing-MagicalRecord.md)
- [Getting Started](Docs/Getting-Started.md)
- [Working with Managed Object Contexts](Docs/Working-with-Managed-Object-Contexts.md)
- [Creating Entities](Docs/Creating-Entities.md)
- [Deleting Entities](Docs/Deleting-Entities.md)
- [Fetching Entities](Docs/Fetching-Entities.md)
- [Saving Entities](Docs/Saving-Entities.md)
- [Importing Data](Docs/Importing-Data.md)
- [Logging](Docs/Logging.md)
* [Other Resources](Docs/Other-Resources.md)
## Support
MagicalRecord is provided as-is, free of charge. For support, you have a few choices:
- Ask your support question on [Stackoverflow.com](http://stackoverflow.com), and tag your question with **MagicalRecord**. The core team will be notified of your question only if you mark your question with this tag. The general Stack Overflow community is provided the opportunity to answer the question to help you faster, and to reap the reputation points. If the community is unable to answer, we'll try to step in and answer your question.
- If you believe you have found a bug in MagicalRecord, please submit a support ticket on the [Github Issues page for MagicalRecord](http://github.com/magicalpanda/magicalrecord/issues). We'll get to them as soon as we can. Please do **NOT** ask general questions on the issue tracker. Support questions will be closed unanswered.
- For more personal or immediate support, [MagicalPanda](http://magicalpanda.com/) is available for hire to consult on your project.
## Twitter
Follow [@MagicalRecord](http://twitter.com/magicalrecord) on twitter to stay up to date with the latest updates relating to MagicalRecord.

Просмотреть файл

@ -1,13 +0,0 @@
//
// ImageToDataTransformer.h
// MagicalRecordRecipes
//
// Created by Saul Mora on 5/19/13.
//
//
#import <Foundation/Foundation.h>
@interface ImageToDataTransformer : NSValueTransformer
@end

Просмотреть файл

@ -1,35 +0,0 @@
//
// ImageToDataTransformer.m
// MagicalRecordRecipes
//
// Created by Saul Mora on 5/19/13.
//
//
#import "ImageToDataTransformer.h"
@implementation ImageToDataTransformer
+ (BOOL)allowsReverseTransformation {
return YES;
}
+ (Class)transformedValueClass {
return [NSData class];
}
- (id)transformedValue:(id)value {
NSData *data = UIImagePNGRepresentation(value);
return data;
}
- (id)reverseTransformedValue:(id)value {
UIImage *uiImage = [[UIImage alloc] initWithData:value];
return uiImage;
}
@end

Просмотреть файл

@ -1,12 +0,0 @@
//
// Prefix header for all source files of the 'AddressBook' target in the 'AddressBook' project
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#endif
#ifndef __ADDRESS_BOOK_FOR_IPHONE__
#define __ADDRESS_BOOK_FOR_IPHONE__ 1
#endif

Просмотреть файл

@ -1,54 +0,0 @@
/*
File: EditingTableViewCell.h
Abstract: A table view cell that displays a label and a text field so that a value can be edited. The user interface is loaded from a nib file.
Version: 1.4
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2010 Apple Inc. All Rights Reserved.
*/
@interface EditingTableViewCell : UITableViewCell
@property (nonatomic, retain) IBOutlet UILabel *label;
@property (nonatomic, retain) IBOutlet UITextField *textField;
@end

Просмотреть файл

@ -1,54 +0,0 @@
/*
File: EditingTableViewCell.m
Abstract: A table view cell that displays a label and a text field so that a value can be edited. The user interface is loaded from a nib file.
Version: 1.4
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Inc. ("Apple") in consideration of your agreement to the following
terms, and your use, installation, modification or redistribution of
this Apple software constitutes acceptance of these terms. If you do
not agree with these terms, please do not use, install, modify or
redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc. may
be used to endorse or promote products derived from the Apple Software
without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or
implied, are granted by Apple herein, including but not limited to any
patent rights that may be infringed by your derivative works or by other
works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright (C) 2010 Apple Inc. All Rights Reserved.
*/
#import "EditingTableViewCell.h"
@implementation EditingTableViewCell
@end

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше