This commit is contained in:
giuseppenuc committed 2016-02-24 16:56:39 +01:00
1 parent d281d765ea
commit 5b074a5176
1261 files changed
+199158 -7303

No files matched your search

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>XMPPvCard.xcdatamodel</string>
</dict>
</plist>
@@ -0,0 +1,20 @@
//
// XMPPvCardAvatarCoreDataStorageObject.h
// XEP-0054 vCard-temp
//
// Originally created by Eric Chamberlain on 3/18/11.
//
// This class is so that we don't load the photoData each time we need to touch the XMPPvCardCoreDataStorageObject.
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class XMPPvCardCoreDataStorageObject;
@interface XMPPvCardAvatarCoreDataStorageObject : NSManagedObject
@property (nonatomic, strong) NSData * photoData;
@property (nonatomic, strong) XMPPvCardCoreDataStorageObject * vCard;
@end
@@ -0,0 +1,17 @@
//
// XMPPvCardAvatarCoreDataStorageObject.m
// XEP-0054 vCard-temp
//
// Originally created by Eric Chamberlain on 3/18/11.
//
#import "XMPPvCardAvatarCoreDataStorageObject.h"
#import "XMPPvCardCoreDataStorageObject.h"
@implementation XMPPvCardAvatarCoreDataStorageObject
@dynamic photoData;
@dynamic vCard;
@end
@@ -0,0 +1,47 @@
//
// XMPPvCardCoreDataStorage.h
// XEP-0054 vCard-temp
//
// Originally created by Eric Chamberlain on 3/18/11.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "XMPPCoreDataStorage.h"
#import "XMPPvCardTempModule.h"
#import "XMPPvCardAvatarModule.h"
/**
* This class is an example implementation of XMPPCapabilitiesStorage using core data.
* You are free to substitute your own storage class.
**/
@interface XMPPvCardCoreDataStorage : XMPPCoreDataStorage <
XMPPvCardAvatarStorage,
XMPPvCardTempModuleStorage
> {
// Inherits protected variables from XMPPCoreDataStorage
}
/**
* XEP-0054 provides a mechanism for transmitting vCards via XMPP.
* Because the JID doesn't change very often and can be large with image data,
* it is safe to persistently store the JID and wait for a user to explicity ask for an update,
* or use XEP-0153 to monitor for JID changes.
*
* For this reason, it is recommended you use this sharedInstance across all your xmppStreams.
* This way all streams can shared a knowledgebase concerning known JIDs and Avatar photos.
*
* All other aspects of vCard handling (such as lookup failures, etc) are kept separate between streams.
**/
+ (instancetype)sharedInstance;
//
// This class inherits from XMPPCoreDataStorage.
//
// Please see the XMPPCoreDataStorage header file for more information.
//
@end
@@ -0,0 +1,235 @@
//
// XMPPvCardCoreDataStorage.m
// XEP-0054 vCard-temp
//
// Originally created by Eric Chamberlain on 3/18/11.
//
#import "XMPPvCardCoreDataStorage.h"
#import "XMPPvCardCoreDataStorageObject.h"
#import "XMPPvCardTempCoreDataStorageObject.h"
#import "XMPPvCardAvatarCoreDataStorageObject.h"
#import "XMPP.h"
#import "XMPPCoreDataStorageProtected.h"
#import "XMPPLogging.h"
#if ! __has_feature(objc_arc)
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
#endif
// Log levels: off, error, warn, info, verbose
#if DEBUG
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN; // | XMPP_LOG_FLAG_TRACE;
#else
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
#endif
enum {
kXMPPvCardTempNetworkFetchTimeout = 10,
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation XMPPvCardCoreDataStorage
static XMPPvCardCoreDataStorage *sharedInstance;
+ (instancetype)sharedInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[XMPPvCardCoreDataStorage alloc] initWithDatabaseFilename:nil storeOptions:nil];
});
return sharedInstance;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Setup
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)configureWithParent:(XMPPvCardTempModule *)aParent queue:(dispatch_queue_t)queue
{
return [super configureWithParent:aParent queue:queue];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Overrides
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)commonInit
{
autoAllowExternalBinaryDataStorage = YES;
autoRecreateDatabaseFile = YES;
[super commonInit];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark XMPPvCardAvatarStorage protocol
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (NSData *)photoDataForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
// This is a public method.
// It may be invoked on any thread/queue.
XMPPLogTrace();
__block NSData *result;
[self executeBlock:^{
XMPPvCardCoreDataStorageObject *vCard;
vCard = [XMPPvCardCoreDataStorageObject fetchOrInsertvCardForJID:jid
inManagedObjectContext:[self managedObjectContext]];
result = vCard.photoData;
}];
return result;
}
- (NSString *)photoHashForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
// This is a public method.
// It may be invoked on any thread/queue.
XMPPLogTrace();
__block NSString *result;
[self executeBlock:^{
XMPPvCardCoreDataStorageObject *vCard;
vCard = [XMPPvCardCoreDataStorageObject fetchOrInsertvCardForJID:jid
inManagedObjectContext:[self managedObjectContext]];
result = vCard.photoHash;
}];
return result;
}
- (void)clearvCardTempForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
// This is a public method.
// It may be invoked on any thread/queue.
XMPPLogTrace();
[self scheduleBlock:^{
XMPPvCardCoreDataStorageObject *vCard;
vCard = [XMPPvCardCoreDataStorageObject fetchOrInsertvCardForJID:jid
inManagedObjectContext:[self managedObjectContext]];
vCard.vCardTemp = nil;
vCard.lastUpdated = [NSDate date];
}];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark XMPPvCardTempModuleStorage protocol
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (XMPPvCardTemp *)vCardTempForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
// This is a public method.
// It may be invoked on any thread/queue.
XMPPLogTrace();
__block XMPPvCardTemp *result;
[self executeBlock:^{
XMPPvCardCoreDataStorageObject *vCard;
vCard = [XMPPvCardCoreDataStorageObject fetchOrInsertvCardForJID:jid
inManagedObjectContext:[self managedObjectContext]];
result = vCard.vCardTemp;
}];
return result;
}
- (void)setvCardTemp:(XMPPvCardTemp *)vCardTemp forJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
// This is a public method.
// It may be invoked on any thread/queue.
XMPPLogTrace();
[self scheduleBlock:^{
XMPPvCardCoreDataStorageObject *vCard;
vCard = [XMPPvCardCoreDataStorageObject fetchOrInsertvCardForJID:jid
inManagedObjectContext:[self managedObjectContext]];
vCard.waitingForFetch = @NO;
vCard.vCardTemp = vCardTemp;
// Update photo and photo hash
vCard.photoData = vCardTemp.photo;
vCard.lastUpdated = [NSDate date];
}];
}
- (XMPPvCardTemp *)myvCardTempForXMPPStream:(XMPPStream *)stream
{
if(!stream) return nil;
return [self vCardTempForJID:[[stream myJID] bareJID] xmppStream:stream];
}
- (BOOL)shouldFetchvCardTempForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
// This is a public method.
// It may be invoked on any thread/queue.
XMPPLogTrace();
__block BOOL result;
[self executeBlock:^{
XMPPvCardCoreDataStorageObject *vCard;
vCard = [XMPPvCardCoreDataStorageObject fetchOrInsertvCardForJID:jid
inManagedObjectContext:[self managedObjectContext]];
BOOL waitingForFetch = [vCard.waitingForFetch boolValue];
if(![stream isAuthenticated])
{
result = NO;
}
else if (!waitingForFetch)
{
vCard.waitingForFetch = @YES;
vCard.lastUpdated = [NSDate date];
result = YES;
}
else if ([vCard.lastUpdated timeIntervalSinceNow] < -kXMPPvCardTempNetworkFetchTimeout)
{
// Our last request exceeded the timeout, send a new one
vCard.lastUpdated = [NSDate date];
result = YES;
}
else
{
// We already have an outstanding request, no need to send another one.
result = NO;
}
}];
return result;
}
@end
@@ -0,0 +1,73 @@
//
// XMPPvCardCoreDataStorageObject.h
// XEP-0054 vCard-temp
//
// Originally created by Eric Chamberlain on 3/18/11.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class XMPPJID;
@class XMPPvCardTemp;
@class XMPPvCardTempCoreDataStorageObject;
@class XMPPvCardAvatarCoreDataStorageObject;
@interface XMPPvCardCoreDataStorageObject : NSManagedObject
/*
* User's JID, indexed for lookups
*/
@property (nonatomic, strong) NSString * jidStr;
/*
* User's photoHash used by XEP-0153
*/
@property (nonatomic, strong, readonly) NSString * photoHash;
/*
* The last time the record was modified, also used to determine if we need to fetch again
*/
@property (nonatomic, strong) NSDate * lastUpdated;
/*
* Flag indicating whether a get request is already pending, used in conjunction with lastUpdated
*/
@property (nonatomic, strong) NSNumber * waitingForFetch;
/*
* Relationship to the vCardTemp record.
* We use a relationship, so the vCardTemp stays faulted until we really need it.
*/
@property (nonatomic, strong) XMPPvCardTempCoreDataStorageObject * vCardTempRel;
/*
* Relationship to the vCardAvatar record.
* We use a relationship, so the vCardAvatar stays faulted until we really need it.
*/
@property (nonatomic, strong) XMPPvCardAvatarCoreDataStorageObject * vCardAvatarRel;
/*
* Accessor to retrieve photoData, so we can hide the underlying relationship implementation.
*/
@property (nonatomic, strong) NSData *photoData;
/*
* Accessor to retrieve vCardTemp, so we can hide the underlying relationship implementation.
*/
@property (nonatomic, strong) XMPPvCardTemp *vCardTemp;
+ (XMPPvCardCoreDataStorageObject *)fetchOrInsertvCardForJID:(XMPPJID *)jid
inManagedObjectContext:(NSManagedObjectContext *)moc;
@end
@@ -0,0 +1,180 @@
//
// XMPPvCardCoreDataStorageObject.m
// XEP-0054 vCard-temp
//
// Originally created by Eric Chamberlain on 3/18/11.
//
#import "XMPPvCardCoreDataStorageObject.h"
#import "XMPPvCardTempCoreDataStorageObject.h"
#import "XMPPvCardAvatarCoreDataStorageObject.h"
#import "XMPPJID.h"
#import "XMPPStream.h"
#import "NSNumber+XMPP.h"
#import "NSData+XMPP.h"
#if ! __has_feature(objc_arc)
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
#endif
@implementation XMPPvCardCoreDataStorageObject
+ (XMPPvCardCoreDataStorageObject *)fetchvCardForJID:(XMPPJID *)jid
inManagedObjectContext:(NSManagedObjectContext *)moc
{
NSString *entityName = NSStringFromClass([XMPPvCardCoreDataStorageObject class]);
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName
inManagedObjectContext:moc];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"jidStr == %@", [jid bare]];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
[fetchRequest setIncludesPendingChanges:YES];
[fetchRequest setFetchLimit:1];
NSArray *results = [moc executeFetchRequest:fetchRequest error:nil];
return (XMPPvCardCoreDataStorageObject *)[results lastObject];
}
+ (XMPPvCardCoreDataStorageObject *)insertEmptyvCardForJID:(XMPPJID *)jid
inManagedObjectContext:(NSManagedObjectContext *)moc
{
NSString *entityName = NSStringFromClass([XMPPvCardCoreDataStorageObject class]);
XMPPvCardCoreDataStorageObject *vCard = [NSEntityDescription insertNewObjectForEntityForName:entityName
inManagedObjectContext:moc];
vCard.jidStr = [jid bare];
return vCard;
}
+ (XMPPvCardCoreDataStorageObject *)fetchOrInsertvCardForJID:(XMPPJID *)jid
inManagedObjectContext:(NSManagedObjectContext *)moc
{
XMPPvCardCoreDataStorageObject *vCard = [self fetchvCardForJID:jid inManagedObjectContext:moc];
if (vCard == nil)
{
vCard = [self insertEmptyvCardForJID:jid inManagedObjectContext:moc];
}
return vCard;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark NSManagedObject methods
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)awakeFromInsert
{
[super awakeFromInsert];
[self setPrimitiveValue:[NSDate date] forKey:@"lastUpdated"];
}
- (void)willSave
{
/*
if (![self isDeleted] && [self isUpdated]) {
[self setPrimitiveValue:[NSDate date] forKey:@"lastUpdated"];
}
*/
[super willSave];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Getter/setter methods
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@dynamic jidStr;
@dynamic photoHash;
@dynamic lastUpdated;
@dynamic waitingForFetch;
@dynamic vCardTempRel;
@dynamic vCardAvatarRel;
- (NSData *)photoData {
return self.vCardAvatarRel.photoData;
}
- (void)setPhotoData:(NSData *)photoData
{
if ([photoData length] == 0)
{
if (self.vCardAvatarRel != nil)
{
[[self managedObjectContext] deleteObject:self.vCardAvatarRel];
[self setPrimitiveValue:nil forKey:@"photoHash"];
}
return;
}
if (self.vCardAvatarRel == nil)
{
NSString *entityName = NSStringFromClass([XMPPvCardAvatarCoreDataStorageObject class]);
self.vCardAvatarRel = [NSEntityDescription insertNewObjectForEntityForName:entityName
inManagedObjectContext:[self managedObjectContext]];
}
[self willChangeValueForKey:@"photoData"];
self.vCardAvatarRel.photoData = photoData;
[self didChangeValueForKey:@"photoData"];
[self setPrimitiveValue:[[photoData xmpp_sha1Digest] xmpp_hexStringValue] forKey:@"photoHash"];
}
- (XMPPvCardTemp *)vCardTemp {
return self.vCardTempRel.vCardTemp;
}
- (void)setVCardTemp:(XMPPvCardTemp *)vCardTemp
{
if (vCardTemp == nil && self.vCardTempRel != nil)
{
[[self managedObjectContext] deleteObject:self.vCardTempRel];
return;
}
if (self.vCardTempRel == nil)
{
NSString *entityName = NSStringFromClass([XMPPvCardTempCoreDataStorageObject class]);
self.vCardTempRel = [NSEntityDescription insertNewObjectForEntityForName:entityName
inManagedObjectContext:[self managedObjectContext]];
}
[self willChangeValueForKey:@"vCardTemp"];
self.vCardTempRel.vCardTemp = vCardTemp;
[self didChangeValueForKey:@"vCardTemp"];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark KVO methods
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ (NSSet *)keyPathsForValuesAffectingPhotoHash
{
return [NSSet setWithObjects:@"vCardAvatarRel", @"photoData", nil];
}
+ (NSSet *)keyPathsForValuesAffectingVCardTemp
{
return [NSSet setWithObject:@"vCardTempRel"];
}
@end
@@ -0,0 +1,23 @@
//
// XMPPvCardTempCoreDataStorageObject.h
// XEP-0054 vCard-temp
//
// Oringally created by Eric Chamberlain on 3/18/11.
//
// This class is so that we don't load the vCardTemp each time we need to touch the XMPPvCardCoreDataStorageObject.
// The vCardTemp abstraction also makes it easier to eventually add support for vCard4 over XMPP (XEP-0292).
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "XMPPvcardTemp.h"
@class XMPPvCardCoreDataStorageObject;
@interface XMPPvCardTempCoreDataStorageObject : NSManagedObject
@property (nonatomic, strong) XMPPvCardTemp * vCardTemp;
@property (nonatomic, strong) XMPPvCardCoreDataStorageObject * vCard;
@end
@@ -0,0 +1,17 @@
//
// XMPPvCardTempCoreDataStorageObject.m
// XEP-0054 vCard-temp
//
// Originally created by Eric Chamberlain on 3/18/11.
//
#import "XMPPvCardTempCoreDataStorageObject.h"
#import "XMPPvCardCoreDataStorageObject.h"
@implementation XMPPvCardTempCoreDataStorageObject
@dynamic vCardTemp;
@dynamic vCard;
@end