Skip to content

Commit

Permalink
Merge pull request #523 from ChatSecure/vcard_nickname
Browse files Browse the repository at this point in the history
Add support for setting & getting vCard nickname
  • Loading branch information
chrisballinger committed Jul 4, 2016
2 parents 3513e27 + 92e5b95 commit 6dcd8ea
Show file tree
Hide file tree
Showing 16 changed files with 245 additions and 59 deletions.
4 changes: 4 additions & 0 deletions ChatSecure.xcodeproj/project.pbxproj
Expand Up @@ -374,6 +374,7 @@
D9AE3A341BA8DAB600255537 /* OTRLanguageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6331051B1A16D1A300C17BAE /* OTRLanguageManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
D9AE3A351BA8DAB600255537 /* OTRLanguageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6331051C1A16D1A300C17BAE /* OTRLanguageManager.m */; };
D9CBBC581C642BAA005CD715 /* EnablePushViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CBBC571C642BAA005CD715 /* EnablePushViewController.swift */; };
D9EEEDD31D2739A800B8BC54 /* OTRvCard.h in Headers */ = {isa = PBXBuildFile; fileRef = D9EEEDD11D27388600B8BC54 /* OTRvCard.h */; settings = {ATTRIBUTES = (Public, ); }; };
EE22362CF225156043E19FA7 /* Pods_ChatSecureCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B353F12AE2FDB52438B426D /* Pods_ChatSecureCore.framework */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -840,6 +841,7 @@
D9C6E69D1B7148EF00572273 /* OTRUsernameCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = OTRUsernameCell.xib; path = Interface/OTRUsernameCell.xib; sourceTree = "<group>"; };
D9C6E6A01B71575300572273 /* OTRUsernameCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OTRUsernameCell.swift; sourceTree = "<group>"; };
D9CBBC571C642BAA005CD715 /* EnablePushViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnablePushViewController.swift; path = "ChatSecure/Classes/View Controllers/Onboarding/EnablePushViewController.swift"; sourceTree = SOURCE_ROOT; };
D9EEEDD11D27388600B8BC54 /* OTRvCard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTRvCard.h; path = "Yap Storage/OTRvCard.h"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -1030,6 +1032,7 @@
633105401A16D1A300C17BAE /* Model */ = {
isa = PBXGroup;
children = (
D9EEEDD11D27388600B8BC54 /* OTRvCard.h */,
63C7E64C1B20F69F0085FA06 /* OTRXMPPServerInfo.h */,
63C7E64D1B20F69F0085FA06 /* OTRXMPPServerInfo.m */,
6331058D1A16D1A300C17BAE /* OTRActivityItemProvider.h */,
Expand Down Expand Up @@ -1715,6 +1718,7 @@
D93DDBD71BA79AEC00CD8331 /* OTRLockButton.h in Headers */,
D93DDBD81BA79AEE00CD8331 /* OTRPasswordStrengthView.h in Headers */,
D93DDBD91BA79AF000CD8331 /* OTRRememberPasswordView.h in Headers */,
D9EEEDD31D2739A800B8BC54 /* OTRvCard.h in Headers */,
D93DDBDA1BA79AF100CD8331 /* OTRSocialButtonsView.h in Headers */,
D93DDBDB1BA79AF300CD8331 /* OTRTitleSubtitleView.h in Headers */,
D93DDBDC1BA79AF500CD8331 /* OTRHoldToTalkView.h in Headers */,
Expand Down
1 change: 0 additions & 1 deletion ChatSecure/Classes/Controllers/XMPP/OTRXMPPManager.h
Expand Up @@ -80,7 +80,6 @@ extern NSString *const OTRXMPPLoginErrorKey;
@property BOOL didSecure;

@property (nonatomic, strong, readonly) OTRXMPPAccount *account;
@property (nonatomic, strong, readonly) NSString *accountUniqueId;
@property (nonatomic, weak) id <PushControllerProtocol> pushController;

- (BOOL)connectWithJID:(NSString*) myJID password:(NSString*)myPassword;
Expand Down
98 changes: 92 additions & 6 deletions ChatSecure/Classes/Controllers/XMPP/OTRXMPPManager.m
Expand Up @@ -32,6 +32,7 @@
#import "XMPPMessage+XEP_0085.h"
#import "XMPPMessage+XEP_0280.h"
#import "NSXMLElement+XEP_0203.h"
#import "XMPPvCardTemp.h"
#import "XMPPMessageDeliveryReceipts.h"
#import "OTRYapDatabaseRosterStorage.h"

Expand Down Expand Up @@ -272,6 +273,7 @@ - (void)setupStream
[self.xmppStream addDelegate:self delegateQueue:self.workQueue];
[self.xmppRoster addDelegate:self delegateQueue:self.workQueue];
[self.xmppCapabilities addDelegate:self delegateQueue:self.workQueue];
[self.xmppvCardTempModule addDelegate:self delegateQueue:self.workQueue];

// Message Carbons
self.messageCarbons = [[XMPPMessageCarbons alloc] init];
Expand Down Expand Up @@ -308,6 +310,7 @@ - (void)teardownStream
[_xmppStream removeDelegate:self];
[_xmppRoster removeDelegate:self];
[_xmppCapabilities removeDelegate:self];
[_xmppvCardTempModule removeDelegate:self];

[_xmppReconnect deactivate];
[_xmppRoster deactivate];
Expand Down Expand Up @@ -622,6 +625,7 @@ - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
[allBuddies enumerateObjectsUsingBlock:^(OTRXMPPBuddy *buddy, NSUInteger idx, BOOL *stop) {
buddy.status = OTRThreadStatusOffline;
buddy.statusMessage = nil;
buddy.waitingForvCardTempFetch = NO;
[transaction setObject:buddy forKey:buddy.uniqueId inCollection:[OTRXMPPBuddy collection]];
}];

Expand All @@ -644,6 +648,9 @@ - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
// Refetch capabilities to check for XEP-0357 support
XMPPJID *jid = [XMPPJID jidWithString:[self.JID bare]];
[self.xmppCapabilities fetchCapabilitiesForJID:jid];

// Fetch latest vCard from server so we can update nickname
//[self.xmppvCardTempModule fetchvCardTempForJID:self.JID ignoreStorage:YES];
}

- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
Expand All @@ -658,7 +665,7 @@ - (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error

- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [iq elementID]);
DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, iq);
return NO;
}

Expand Down Expand Up @@ -694,16 +701,18 @@ - (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)prese

- (void)xmppStream:(XMPPStream *)sender didReceiveError:(id)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
DDLogVerbose(@"%@: %@ %@", THIS_FILE, THIS_METHOD, error);
}

- (void)xmppStream:(XMPPStream *)sender didFailToSendIQ:(XMPPIQ *)iq error:(NSError *)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
DDLogVerbose(@"%@: %@ %@ %@", THIS_FILE, THIS_METHOD, iq, error);
}

- (void)xmppStream:(XMPPStream *)sender didFailToSendMessage:(XMPPMessage *)message error:(NSError *)error
{
DDLogVerbose(@"%@: %@ %@ %@", THIS_FILE, THIS_METHOD, message, error);

if ([message.elementID length]) {
[self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction enumerateMessagesWithId:message.elementID block:^(id<OTRMessageProtocol> _Nonnull databaseMessage, BOOL * _Null_unspecified stop) {
Expand All @@ -721,16 +730,93 @@ - (void)xmppStream:(XMPPStream *)sender didFailToSendMessage:(XMPPMessage *)mess
}
- (void)xmppStream:(XMPPStream *)sender didFailToSendPresence:(XMPPPresence *)presence error:(NSError *)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
DDLogVerbose(@"%@: %@ %@ %@", THIS_FILE, THIS_METHOD, presence, error);
}

#pragma mark XMPPvCardTempModuleDelegate

- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule
didReceivevCardTemp:(XMPPvCardTemp *)vCardTemp
forJID:(XMPPJID *)jid {
DDLogVerbose(@"%@: %@ %@ %@ %@", THIS_FILE, THIS_METHOD, vCardTempModule, vCardTemp, jid);

// update my vCard to local nickname setting
// currently this will clobber whatever you have on the server
if ([self.JID isEqualToJID:jid options:XMPPJIDCompareBare]) {
if (self.account.displayName.length &&
vCardTemp.nickname.length &&
![vCardTemp.nickname isEqualToString:self.account.displayName]) {
vCardTemp.nickname = self.account.displayName;
[vCardTempModule updateMyvCardTemp:vCardTemp];
} else if (vCardTemp.nickname.length) {
[self.databaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) {
NSString *collection = [self.account.class collection];
NSString *key = self.account.uniqueId;
OTRXMPPAccount *account = [[transaction objectForKey:key inCollection:collection] copy];
account.displayName = vCardTemp.nickname;
[transaction setObject:account forKey:key inCollection:collection];
}];
}
} else {
// this is someone elses vCard
DDLogVerbose(@"%@: other's vCard %@ %@ %@ %@", THIS_FILE, THIS_METHOD, vCardTempModule, vCardTemp, jid);
}
}

- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule
failedToFetchvCardForJID:(XMPPJID *)jid
error:(NSXMLElement*)error {
DDLogVerbose(@"%@: %@ %@ %@ %@", THIS_FILE, THIS_METHOD, vCardTempModule, jid, error);

// update my vCard to local nickname setting
if ([self.JID isEqualToJID:jid options:XMPPJIDCompareBare] &&
self.account.displayName.length) {
XMPPvCardTemp *vCardTemp = [XMPPvCardTemp vCardTemp];
vCardTemp.nickname = self.account.displayName;
[vCardTempModule updateMyvCardTemp:vCardTemp];
}
}

- (void)xmppvCardTempModuleDidUpdateMyvCard:(XMPPvCardTempModule *)vCardTempModule {
DDLogVerbose(@"%@: %@ %@", THIS_FILE, THIS_METHOD, vCardTempModule);
}

- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule failedToUpdateMyvCard:(NSXMLElement *)error {
DDLogVerbose(@"%@: %@ %@ %@", THIS_FILE, THIS_METHOD, vCardTempModule, error);
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark XMPPRosterDelegate
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(NSXMLElement *)item {
DDLogVerbose(@"%@: %@ %@", THIS_FILE, THIS_METHOD, item);

// Because XMPP sucks, there's no way to know if a vCard has changed without fetching all of them again
// To preserve user mobile data, just fetch each vCard once, only if it's never been fetched
// Otherwise you'll only receive vCard updates if someone updates their avatar
NSString *jidStr = [item attributeStringValueForName:@"jid"];
XMPPJID *jid = [[XMPPJID jidWithString:jidStr] bareJID];
__block OTRXMPPBuddy *buddy = nil;
[self.databaseConnection readWithBlock:^(YapDatabaseReadTransaction * _Nonnull transaction) {
buddy = [OTRXMPPBuddy fetchBuddyWithUsername:[jid bare] withAccountUniqueId:self.account.uniqueId transaction:transaction];
}];
if (!buddy.vCardTemp) {
XMPPvCardTemp *vCard = [self.xmppvCardTempModule vCardTempForJID:jid shouldFetch:YES];
if (vCard) {
buddy = [buddy copy];
buddy.vCardTemp = vCard;
[self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) {
[transaction setObject:buddy forKey:buddy.uniqueId inCollection:[[buddy class] collection]];
}];
}
}
}

-(void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
DDLogVerbose(@"%@: %@ %@", THIS_FILE, THIS_METHOD, presence);

NSString *jidStrBare = [presence fromStr];

Expand All @@ -749,7 +835,7 @@ -(void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XM

- (void)xmppRoster:(XMPPRoster *)sender didReceiveRosterPush:(XMPPIQ *)iq
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
DDLogVerbose(@"%@: %@ %@", THIS_FILE, THIS_METHOD, iq);
//verry unclear what this delegate call is supposed to do with jabber.ccc.de it seems to have all the subscription=both,none and jid
/*
if ([iq isSetIQ] && [[[[[[iq elementsForName:@"query"] firstObject] elementsForName:@"item"] firstObject] attributeStringValueForName:@"subscription"] isEqualToString:@"from"]) {
Expand Down
Expand Up @@ -118,7 +118,11 @@ - (void)updateBuddy:(OTRXMPPBuddy *)buddy withItem:(NSXMLElement *)item
localBuddy = xmppBuddy;
}

localBuddy.displayName = [item attributeStringValueForName:@"name"];
NSString *name = [item attributeStringValueForName:@"name"];

if (name.length) {
localBuddy.displayName = name;
}

if ([self isPendingApprovalElement:item]) {
localBuddy.pendingApproval = YES;
Expand Down
99 changes: 60 additions & 39 deletions ChatSecure/Classes/Controllers/XMPP/OTRvCardYapDatabaseStorage.m
Expand Up @@ -38,7 +38,6 @@ - (OTRXMPPBuddy *)buddyWithJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream tr
return [OTRXMPPBuddy fetchBuddyWithUsername:[jid bare] withAccountUniqueId:account.uniqueId transaction:transaction];
}


- (OTRXMPPBuddy *)buddyWithJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream;
{
__block OTRXMPPBuddy *buddy = nil;
Expand All @@ -48,17 +47,38 @@ - (OTRXMPPBuddy *)buddyWithJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream;
return buddy;
}


- (OTRXMPPAccount*)accountWithStream:(XMPPStream*)stream {
__block OTRXMPPAccount *account = nil;
[self.databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
account = [OTRXMPPAccount accountForStream:stream transaction:transaction];
}];
return account;
}

#pragma - mark XMPPvCardAvatarStorage Methods

- (NSData *)photoDataForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
return [self buddyWithJID:jid xmppStream:stream].avatarData;
NSData *photoData = nil;
if ([jid isEqualToJID:stream.myJID options:XMPPJIDCompareBare]) {
photoData = [self accountWithStream:stream].avatarData;
} else {
photoData = [self buddyWithJID:jid xmppStream:stream].avatarData;
}
return photoData;

}

- (NSString *)photoHashForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
return [self buddyWithJID:jid xmppStream:stream].photoHash;
NSString *photoHash = nil;
if ([jid isEqualToJID:stream.myJID options:XMPPJIDCompareBare]) {
photoHash = [self accountWithStream:stream].photoHash;
} else {
photoHash = [self buddyWithJID:jid xmppStream:stream].photoHash;
}
return photoHash;
}

/**
Expand All @@ -68,10 +88,14 @@ - (NSString *)photoHashForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
- (void)clearvCardTempForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
[self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
OTRXMPPBuddy *buddy = [[self buddyWithJID:jid xmppStream:stream transaction:transaction] copy];
buddy.vCardTemp = nil;

[transaction setObject:buddy forKey:buddy.uniqueId inCollection:[OTRXMPPBuddy collection]];
id<OTRvCard> vCard = nil;
if ([jid isEqualToJID:stream.myJID options:XMPPJIDCompareBare]) {
vCard = [OTRXMPPAccount accountForStream:stream transaction:transaction];
} else {
vCard = [[self buddyWithJID:jid xmppStream:stream transaction:transaction] copy];
}
vCard.vCardTemp = nil;
[vCard saveWithTransaction:transaction];
}];
}

Expand Down Expand Up @@ -101,8 +125,13 @@ - (BOOL)configureWithParent:(XMPPvCardTempModule *)aParent queue:(dispatch_queue
**/
- (XMPPvCardTemp *)vCardTempForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
OTRXMPPBuddy *buddy = [self buddyWithJID:jid xmppStream:stream];
return buddy.vCardTemp;
XMPPvCardTemp *vCardTemp = nil;
if ([jid isEqualToJID:stream.myJID options:XMPPJIDCompareBare]) {
vCardTemp = [self accountWithStream:stream].vCardTemp;
} else {
vCardTemp = [self buddyWithJID:jid xmppStream:stream].vCardTemp;
}
return vCardTemp;
}

/**
Expand All @@ -111,20 +140,16 @@ - (XMPPvCardTemp *)vCardTempForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)strea
- (void)setvCardTemp:(XMPPvCardTemp *)vCardTemp forJID:(XMPPJID *)jid xmppStream:(XMPPStream *)stream
{
[self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
OTRXMPPBuddy *buddy = [[self buddyWithJID:jid xmppStream:stream transaction:transaction] copy];

id<OTRvCard> vCard = nil;
if ([stream.myJID isEqualToJID:jid options:XMPPJIDCompareBare]) {
//this is the self buddy
OTRXMPPAccount *account = [[OTRXMPPAccount accountForStream:stream transaction:transaction] copy];
account.avatarData = vCardTemp.photo;
[account saveWithTransaction:transaction];
vCard = [[OTRXMPPAccount accountForStream:stream transaction:transaction] copy];
} else {
vCard = [[self buddyWithJID:jid xmppStream:stream transaction:transaction] copy];
}

buddy.vCardTemp = vCardTemp;
buddy.waitingForvCardTempFetch = NO;
buddy.lastUpdatedvCardTemp = [NSDate date];

[buddy saveWithTransaction:transaction];
vCard.vCardTemp = vCardTemp;
vCard.waitingForvCardTempFetch = NO;
vCard.lastUpdatedvCardTemp = [NSDate date];
[vCard saveWithTransaction:transaction];
}];

}
Expand All @@ -138,7 +163,7 @@ - (XMPPvCardTemp *)myvCardTempForXMPPStream:(XMPPStream *)stream
return nil;
}

return [self buddyWithJID:stream.myJID xmppStream:stream].vCardTemp;
return [self accountWithStream:stream].vCardTemp;
}

/**
Expand All @@ -151,28 +176,24 @@ - (BOOL)shouldFetchvCardTempForJID:(XMPPJID *)jid xmppStream:(XMPPStream *)strea
if (![stream isAuthenticated]) {
return NO;
}

__block BOOL result = NO;

[self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {

OTRXMPPBuddy * buddy = [[self buddyWithJID:jid xmppStream:stream transaction:transaction] copy];
if (!buddy.isWaitingForvCardTempFetch) {

buddy.waitingForvCardTempFetch = YES;
buddy.lastUpdatedvCardTemp = [NSDate date];

result = YES;
}
else if ([buddy.lastUpdatedvCardTemp timeIntervalSinceNow] <= -10) {

buddy.lastUpdatedvCardTemp = [NSDate date];

result = YES;
id<OTRvCard> vCard = nil;
if ([jid isEqualToJID:stream.myJID options:XMPPJIDCompareBare]) {
vCard = [[OTRXMPPAccount accountForStream:stream transaction:transaction] copy];
} else {
vCard = [[self buddyWithJID:jid xmppStream:stream transaction:transaction] copy];
}


if (result) {
[buddy saveWithTransaction:transaction];
if (vCard.waitingForvCardTempFetch) {
result = NO;
} else if ([vCard.lastUpdatedvCardTemp timeIntervalSinceNow] <= -24*60*60 ||
!vCard.vCardTemp) {
vCard.waitingForvCardTempFetch = YES;
[vCard saveWithTransaction:transaction];
result = YES;
}
}];

Expand Down

0 comments on commit 6dcd8ea

Please sign in to comment.