I managed to successfully send a file from iphone to spark. Now I want to send a file from iphone to iphone, unfortunately I always get this error code: Printing description of error: Error Domain = XMPPOutgoingFileTransferErrorDomain Code = -1 "Unable to send SI offer; the recipient does not have the required features." UserInfo = {0x1a9773d0 NSLocalizedDescription = Unable to send SI offer; the recipient does not have the required features.}
The code I'm using for the transfer and the following:
-(void)elaborazioneInvioTraferimentoFile{
XMPPOutgoingFileTransfer *xmppIncomingFileTransfer= [XMPPOutgoingFileTransfer new];
[xmppIncomingFileTransfer activate:self.xmppStream];
[xmppIncomingFileTransfer addDelegate:self delegateQueue:dispatch_get_main_queue()];
UIImage *img=[UIImage imageNamed:@"ico.png"];
NSData *pngData = UIImagePNGRepresentation(img);
NSArray *paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths1 objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"ico.png"]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file
// do error checking fun stuxmppIncomingFileTransferff...
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *fullPath = [[paths lastObject] stringByAppendingPathComponent:@"ico.png"];
NSData *data = [NSData dataWithContentsOfFile:fullPath];
NSLog(@"******%@",self.senderId);
NSError *err;
if (![xmppIncomingFileTransfer sendData:data
named:@"ico.png"
toRecipient:[XMPPJID jidWithString:self.senderId]
description:@"Baal's Soulstone, obviously."
error:&err]) {
DDLogInfo(@"You messed something up: %@", err);
}}
Where am I doing wrong? thanks for your help
--
You received this message because you are subscribed to the Google Groups "XMPPFramework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to xmppframewor...@googlegroups.com.
To post to this group, send email to xmppfr...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/xmppframework/4eb3c852-5537-485b-829e-5157ac4e524d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
#import "AppDelegate.h"
#import "RootViewController.h"
#import "SettingsViewController.h"
#import "GCDAsyncSocket.h"
#import "XMPP.h"
#import "XMPPLogging.h"
#import "XMPPReconnect.h"
#import "XMPPCapabilitiesCoreDataStorage.h"
#import "XMPPRosterCoreDataStorage.h"
#import "XMPPvCardAvatarModule.h"
#import "XMPPvCardCoreDataStorage.h"
#import "DDLog.h"
#import "DDTTYLogger.h"
#import <CFNetwork/CFNetwork.h>
#import "SingletonDati.h"
// Log levels: off, error, warn, info, verbose
#if DEBUG
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#else
static const int ddLogLevel = LOG_LEVEL_INFO;
#endif
@interface AppDelegate(){
XMPPIncomingFileTransfer *_xmppIncomingFileTransfer;
}
- (void)setupStream;
- (void)teardownStream;
- (void)goOnline;
- (void)goOffline;
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation AppDelegate
@synthesize xmppStream;
@synthesize xmppReconnect;
@synthesize xmppRoster;
@synthesize xmppRosterStorage;
@synthesize xmppvCardTempModule;
@synthesize xmppvCardAvatarModule;
@synthesize xmppCapabilities;
@synthesize xmppCapabilitiesStorage;
@synthesize window;
@synthesize navigationController;
@synthesize settingsViewController;
@synthesize loginButton;
@synthesize password;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Configure logging framework
[DDLog addLogger:[DDTTYLogger sharedInstance]
withLogLevel:XMPP_LOG_LEVEL_VERBOSE | XMPP_LOG_FLAG_TRACE | XMPP_LOG_FLAG_SEND_RECV];
/// [DDLog addLogger:[DDTTYLogger sharedInstance] withLogLevel:XMPP_LOG_FLAG_SEND_RECV];
// Setup the XMPP stream
[self setupStream];
// Setup the view controllers
/// [window setRootViewController:navigationController];
[window makeKeyAndVisible];
if (![self connect])
{
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.0 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[navigationController presentViewController:settingsViewController animated:YES completion:NULL];
});
}
return YES;
}
- (void)dealloc
{
[self teardownStream];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Core Data
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (NSManagedObjectContext *)managedObjectContext_roster
{
return [xmppRosterStorage mainThreadManagedObjectContext];
}
- (NSManagedObjectContext *)managedObjectContext_capabilities
{
return [xmppCapabilitiesStorage mainThreadManagedObjectContext];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Private
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)setupStream
{
NSAssert(xmppStream == nil, @"Method setupStream invoked multiple times");
// Setup xmpp stream
//
// The XMPPStream is the base class for all activity.
// Everything else plugs into the xmppStream, such as modules/extensions and delegates.
xmppStream = [[XMPPStream alloc] init];
#if !TARGET_IPHONE_SIMULATOR
{
// Want xmpp to run in the background?
//
// P.S. - The simulator doesn't support backgrounding yet.
// When you try to set the associated property on the simulator, it simply fails.
// And when you background an app on the simulator,
// it just queues network traffic til the app is foregrounded again.
// We are patiently waiting for a fix from Apple.
// If you do enableBackgroundingOnSocket on the simulator,
// you will simply see an error message from the xmpp stack when it fails to set the property.
xmppStream.enableBackgroundingOnSocket = YES;
}
#endif
// Setup reconnect
//
// The XMPPReconnect module monitors for "accidental disconnections" and
// automatically reconnects the stream for you.
// There's a bunch more information in the XMPPReconnect header file.
xmppReconnect = [[XMPPReconnect alloc] init];
// Setup roster
//
// The XMPPRoster handles the xmpp protocol stuff related to the roster.
// The storage for the roster is abstracted.
// So you can use any storage mechanism you want.
// You can store it all in memory, or use core data and store it on disk, or use core data with an in-memory store,
// or setup your own using raw SQLite, or create your own storage mechanism.
// You can do it however you like! It's your application.
// But you do need to provide the roster with some storage facility.
xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
/// xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] initWithInMemoryStore];
xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];
xmppRoster.autoFetchRoster = YES;
xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;
// Setup vCard support
//
// The vCard Avatar module works in conjuction with the standard vCard Temp module to download user avatars.
// The XMPPRoster will automatically integrate with XMPPvCardAvatarModule to cache roster photos in the roster.
xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];
xmppvCardAvatarModule = [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:xmppvCardTempModule];
// Setup capabilities
//
// The XMPPCapabilities module handles all the complex hashing of the caps protocol (XEP-0115).
// Basically, when other clients broadcast their presence on the network
// they include information about what capabilities their client supports (audio, video, file transfer, etc).
// But as you can imagine, this list starts to get pretty big.
// This is where the hashing stuff comes into play.
// Most people running the same version of the same client are going to have the same list of capabilities.
// So the protocol defines a standardized way to hash the list of capabilities.
// Clients then broadcast the tiny hash instead of the big list.
// The XMPPCapabilities protocol automatically handles figuring out what these hashes mean,
// and also persistently storing the hashes so lookups aren't needed in the future.
//
// Similarly to the roster, the storage of the module is abstracted.
// You are strongly encouraged to persist caps information across sessions.
//
// The XMPPCapabilitiesCoreDataStorage is an ideal solution.
// It can also be shared amongst multiple streams to further reduce hash lookups.
xmppCapabilitiesStorage = [XMPPCapabilitiesCoreDataStorage sharedInstance];
xmppCapabilities = [[XMPPCapabilities alloc] initWithCapabilitiesStorage:xmppCapabilitiesStorage];
xmppCapabilities.autoFetchHashedCapabilities = YES;
xmppCapabilities.autoFetchNonHashedCapabilities = NO;
// Activate xmpp modules
[xmppReconnect activate:xmppStream];
[xmppRoster activate:xmppStream];
// [xmppvCardTempModule activate:xmppStream];
/// [xmppvCardAvatarModule activate:xmppStream];
[xmppCapabilities activate:xmppStream];
// Add ourself as a delegate to anything we may be interested in
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
_xmppIncomingFileTransfer = [XMPPIncomingFileTransfer new];
[_xmppIncomingFileTransfer activate:xmppStream];
// Add ourselves as delegate to necessary methods
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppIncomingFileTransfer addDelegate:self delegateQueue:dispatch_get_main_queue()];
// Optional:
//
// Replace me with the proper domain and port.
// The example below is setup for a typical google talk account.
//
// If you don't supply a hostName, then it will be automatically resolved using the JID (below).
// For example, if you supply a JID like 'us...@quack.com/rsrc'
// then the xmpp framework will follow the xmpp specification, and do a SRV lookup for quack.com.
//
// If you don't specify a hostPort, then the default (5222) will be used.
[xmppStream setHostName:@"ip"];
[xmppStream setHostPort:5222];
// You may need to alter these settings depending on the server you're connecting to
customCertEvaluation = YES;
}
- (void)teardownStream
{
[xmppStream removeDelegate:self];
[xmppRoster removeDelegate:self];
[xmppReconnect deactivate];
[xmppRoster deactivate];
[xmppvCardTempModule deactivate];
[xmppvCardAvatarModule deactivate];
[xmppCapabilities deactivate];
[xmppStream disconnect];
xmppStream = nil;
xmppReconnect = nil;
xmppRoster = nil;
xmppRosterStorage = nil;
xmppvCardStorage = nil;
xmppvCardTempModule = nil;
xmppvCardAvatarModule = nil;
xmppCapabilities = nil;
xmppCapabilitiesStorage = nil;
}
// It's easy to create XML elments to send and to read received XML elements.
// You have the entire NSXMLElement and NSXMLNode API's.
//
// In addition to this, the NSXMLElement+XMPP category provides some very handy methods for working with XMPP.
//
// On the iPhone, Apple chose not to include the full NSXML suite.
// No problem - we use the KissXML library as a drop in replacement.
//
// For more information on working with XML elements, see the Wiki article:
// https://github.com/robbiehanson/XMPPFramework/wiki/WorkingWithElements
- (void)goOnline
{
XMPPPresence *presence = [XMPPPresence presence]; // type="available" is implicit
NSString *domain = [xmppStream.myJID domain];
//Google set their presence priority to 24, so we do the same to be compatible.
if([domain isEqualToString:@"gmail.com"]
|| [domain isEqualToString:@"gtalk.com"]
|| [domain isEqualToString:@"talk.google.com"])
{
NSXMLElement *priority = [NSXMLElement elementWithName:@"priority" stringValue:@"24"];
[presence addChild:priority];
}
[[self xmppStream] sendElement:presence];
}
- (void)goOffline
{
XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
[[self xmppStream] sendElement:presence];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Connect/disconnect
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)connect
{
if (![xmppStream isDisconnected]) {
return YES;
}
NSString *myJID = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyJID];
NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyPassword];
//
// If you don't want to use the Settings view to set the JID,
// uncomment the section below to hard code a JID and password.
//
// myJID = @"us...@gmail.com/xmppframework";
// myPassword = @"";
if (myJID == nil || myPassword == nil) {
return NO;
}
[xmppStream setMyJID:[XMPPJID jidWithString:myJID]];
password = myPassword;
NSError *error = nil;
if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error connecting"
message:@"See console for error details."
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alertView show];
DDLogError(@"Error connecting: %@", error);
return NO;
}
return YES;
}
- (void)disconnect
{
[self goOffline];
[xmppStream disconnect];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark UIApplicationDelegate
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store
// enough application state information to restore your application to its current state in case
// it is terminated later.
//
// If your application supports background execution,
// called instead of applicationWillTerminate: when the user quits.
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
#if TARGET_IPHONE_SIMULATOR
DDLogError(@"The iPhone simulator does not process background network traffic. "
@"Inbound traffic is queued until the keepAliveTimeout:handler: fires.");
#endif
if ([application respondsToSelector:@selector(setKeepAliveTimeout:handler:)])
{
[application setKeepAliveTimeout:600 handler:^{
DDLogVerbose(@"KeepAliveHandler");
// Do other keep alive stuff here.
}];
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)applicationWillTerminate:(UIApplication *)application
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
[self teardownStream];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark XMPPStream Delegate
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
NSLog(@"*** connessione SOCKET RIUSCITA");
}
- (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
NSString *expectedCertName = [xmppStream.myJID domain];
if (expectedCertName)
{
[settings setObject:expectedCertName forKey:(NSString *)kCFStreamSSLPeerName];
}
if (customCertEvaluation)
{
[settings setObject:@(YES) forKey:GCDAsyncSocketManuallyEvaluateTrust];
}
}
/**
* Allows a delegate to hook into the TLS handshake and manually validate the peer it's connecting to.
*
* This is only called if the stream is secured with settings that include:
* - GCDAsyncSocketManuallyEvaluateTrust == YES
* That is, if a delegate implements xmppStream:willSecureWithSettings:, and plugs in that key/value pair.
*
* Thus this delegate method is forwarding the TLS evaluation callback from the underlying GCDAsyncSocket.
*
* Typically the delegate will use SecTrustEvaluate (and related functions) to properly validate the peer.
*
* Note from Apple's documentation:
* Because [SecTrustEvaluate] might look on the network for certificates in the certificate chain,
* [it] might block while attempting network access. You should never call it from your main thread;
* call it only from within a function running on a dispatch queue or on a separate thread.
*
* This is why this method uses a completionHandler block rather than a normal return value.
* The idea is that you should be performing SecTrustEvaluate on a background thread.
* The completionHandler block is thread-safe, and may be invoked from a background queue/thread.
* It is safe to invoke the completionHandler block even if the socket has been closed.
*
* Keep in mind that you can do all kinds of cool stuff here.
* For example:
*
* If your development server is using a self-signed certificate,
* then you could embed info about the self-signed cert within your app, and use this callback to ensure that
* you're actually connecting to the expected dev server.
*
* Also, you could present certificates that don't pass SecTrustEvaluate to the client.
* That is, if SecTrustEvaluate comes back with problems, you could invoke the completionHandler with NO,
* and then ask the client if the cert can be trusted. This is similar to how most browsers act.
*
* Generally, only one delegate should implement this method.
* However, if multiple delegates implement this method, then the first to invoke the completionHandler "wins".
* And subsequent invocations of the completionHandler are ignored.
**/
- (void)xmppStream:(XMPPStream *)sender didReceiveTrust:(SecTrustRef)trust
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
// The delegate method should likely have code similar to this,
// but will presumably perform some extra security code stuff.
// For example, allowing a specific self-signed certificate that is known to the app.
dispatch_queue_t bgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(bgQueue, ^{
SecTrustResultType result = kSecTrustResultDeny;
OSStatus status = SecTrustEvaluate(trust, &result);
if (status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)) {
completionHandler(YES);
}
else {
completionHandler(NO);
}
});
}
- (void)xmppStreamDidSecure:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
isXmppConnected = YES;
NSError *error = nil;
if (![[self xmppStream] authenticateWithPassword:password error:&error])
{
DDLogError(@"Error authenticating: %@", error);
}
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
[self goOnline];
}
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
return NO;
}
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
// A simple example of inbound message handling.
if ([message isChatMessageWithBody])
{
XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[message from]
xmppStream:xmppStream
managedObjectContext:[self managedObjectContext_roster]];
NSString *body = [[message elementForName:@"body"] stringValue];
NSString *displayName = [user displayName];
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
{
/* UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:displayName
message:body
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alertView show];
*/
NSMutableDictionary *dati=[[NSMutableDictionary alloc]init];
[dati setObject:(body) forKey:@"messaggioRicevuto"];
[dati setObject:displayName forKey:@"remoteUser"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"RiceviMessaggio" object:self userInfo:dati];
}
else
{
// We are not active, so use a local notification instead
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertAction = @"Ok";
localNotification.alertBody = [NSString stringWithFormat:@"From: %@\n\n%@",displayName,body];
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
}
}
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [presence fromStr]);
}
- (void)xmppStream:(XMPPStream *)sender didReceiveError:(id)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
if (!isXmppConnected)
{
DDLogError(@"Unable to connect to server. Check xmppStream.hostName");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark XMPPRosterDelegate
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)xmppRoster:(XMPPRoster *)sender didReceiveBuddyRequest:(XMPPPresence *)presence
{
DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[presence from]
xmppStream:xmppStream
managedObjectContext:[self managedObjectContext_roster]];
NSString *displayName = [user displayName];
NSString *jidStrBare = [presence fromStr];
NSString *body = nil;
if (![displayName isEqualToString:jidStrBare])
{
body = [NSString stringWithFormat:@"Buddy request from %@ <%@>", displayName, jidStrBare];
}
else
{
body = [NSString stringWithFormat:@"Buddy request from %@", displayName];
}
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:displayName
message:body
delegate:nil
cancelButtonTitle:@"Not implemented"
otherButtonTitles:nil];
[alertView show];
}
else
{
// We are not active, so use a local notification instead
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertAction = @"Not implemented";
localNotification.alertBody = body;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
}
//IN ARRIVO
#pragma mark - XMPPIncomingFileTransferDelegate Methods
- (void)xmppIncomingFileTransfer:(XMPPIncomingFileTransfer *)sender
didFailWithError:(NSError *)error
{
DDLogVerbose(@"%@: Incoming file transfer failed with error: %@", THIS_FILE, error);
}
- (void)xmppIncomingFileTransfer:(XMPPIncomingFileTransfer *)sender
didReceiveSIOffer:(XMPPIQ *)offer
{
DDLogVerbose(@"%@: Incoming file transfer did receive SI offer. Accepting...", THIS_FILE);
[sender acceptSIOffer:offer];
}
- (void)xmppIncomingFileTransfer:(XMPPIncomingFileTransfer *)sender
didSucceedWithData:(NSData *)data
named:(NSString *)name
{
DDLogVerbose(@"%@: Incoming file transfer did succeed.", THIS_FILE);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *fullPath = [[paths lastObject] stringByAppendingPathComponent:name];
[data writeToFile:fullPath options:0 error:nil];
DDLogVerbose(@"%@: Data was written to the path: %@", THIS_FILE, fullPath);
}
////test--------------
///INVIO
- (void)xmppOutgoingFileTransfer:(XMPPOutgoingFileTransfer *)sender
didFailWithError:(NSError *)error
{
DDLogInfo(@"Outgoing file transfer failed with error: %@", error);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"There was an error sending your file. See the logs."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
- (void)xmppOutgoingFileTransferDidSucceed:(XMPPOutgoingFileTransfer *)sender
{
DDLogVerbose(@"File transfer successful.");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!"
message:@"Your file was sent successfully."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
#pragma mark - Public Methods
- (void)prepareStreamAndLogInWithJID:(XMPPJID *)jid password:(NSString *)password
{
DDLogVerbose(@"Preparing the stream and logging in as %@", jid.full);
xmppStream = [XMPPStream new];
xmppStream.myJID = jid;
xmppRosterStorage = [XMPPRosterCoreDataStorage new];
xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];
xmppRoster.autoFetchRoster = YES;
_xmppIncomingFileTransfer = [XMPPIncomingFileTransfer new];
// Activate all modules
[xmppRoster activate:xmppStream];
[_xmppIncomingFileTransfer activate:xmppStream];
// Add ourselves as delegate to necessary methods
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppIncomingFileTransfer addDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *err;
if (![xmppStream connectWithTimeout:30 error:&err]) {
DDLogInfo(@"%@: Error connecting: %@", THIS_FILE, err);
} else {
password = password;
}
}
#pragma mark - Private Methods
- (void)tearDownStream
{
[xmppStream removeDelegate:self];
[_xmppIncomingFileTransfer removeDelegate:self];
[xmppRoster deactivate];
[_xmppIncomingFileTransfer deactivate];
[xmppStream disconnect];
xmppStream = nil;
xmppRoster = nil;
xmppRosterStorage = nil;
_xmppIncomingFileTransfer = nil;
}
#pragma mark - XMPPStreamDelegate Methods
@end