I'm currently developing a small chat application using iOS and XMPPFramework.
I registered two users on a XMPP client on a public XMPP server.
However, when I send messages to the bare JIDs via my iOS app, users connected on the app would not receive the message because the XMPP client had sent a presence with a higher priority.
To fix that, I just have the users send their presence with the highest priority, so that when I send a message to their bare JID, the messages are routed to the proper resource. However, I feel like this is not a good way to go about it. I would like to send the message directly to the full JID, but I'm not sure how to get it.
What is the proper way to send or receive the full JID of a user without subscribing? Is it possible or is it just bad practice? Am I supposed to send it in the presence?
AppDelegate.h
+ (AppDelegate*)instance;
AppDelegate.m
+ (AppDelegate*)instance {
return (AppDelegate*)[[UIApplication sharedApplication] delegate];
}
Then in your ViewController.m
XMPPJID *myJID = [[AppDelegate instance] xmppStream].myJID;
This will give you the full JID. Hope this is what you asked.. let me know if not or anything else regarding this.
Related
I am working on sending SMS demo. I want to send how to send the SMS and how to set the delegate to MessageComposeViewController. and in order to send the message we have below line
[self presentViewController:messageController animated:NO completion:nil];
This line will present the MessageComposeView on screen with SEND button. And Once we click on send button it sends the message. What I want is to send the message directly without presenting this MessageController on screen. Please help how can I do this.
In this related question, Apple has restrictions in place on being able to send a SMS message without the user clicking the SEND button.
Apple really wants the user to be in control of the SMS functionality of their phone. Otherwise all sorts of data could be flying off some random app (e.g. spamming your contacts with "try this app out!", which would not be very friendly nor very nice).
One of the answers in this question does have a potential non-MFMessageComposeViewController solution, however I have a feeling that if Apple catches you doing this they might deny your app from being approved for the app store.
You could send the message using some webservice on the internet. http://client.suresms.com/ProjectInfo.aspx?Info=3 or www.clickatell.com. They have bunches of API for sending messages.
In SureSMS simply create an account and make a http request to
http://suresms.com/Script/GlobalSendSMS.aspx?login=[youraccountnumber]&password=[yourpassword]&to=[phonenumber]&Text=Hallo.
Remember to URL encode the message text and use countrycodes. Thats it.
You have to present MessageComposeViewController.It's not possible to send without presenting it.
MFMessageComposeViewController has delegate method while delete/send/save. which only perform while we present it.
(void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
You can't do it without MFMessageComposeViewController. Apple won't allow to send SMS without user interaction.
As per document
You must not modify the view hierarchy presented by this view
controller. You can, however, customize the appearance of the
interface using the UIAppearance protocol.
I've alternate solution of this, Alternative way can be Using web service API. Create a web service at server side that send a message to specific number(s) that accept numbers as parameters with request.(according to your requirement)
As using Web server or external sms provider can do it.
It is NOT possible . Apple willn't accept your App. Apple will reject your App if you do like that. Human interface guidelines should be followed up.
For fun I've built a little socket based chat application. It is speaking over tcp socket with a nodejs server. Its successfully sending messages back and forth. However, the problem occurs when i press the home button and put my app in the background - at this point the socket seems to be "paused" and all messages that are sent during this time are lost.
I've got push notifications setup for when the app is in the background but since the socket is not active in the app the message never really reaches the app.
How should i handle this? What are my options?
Ive got a few ideas but id love some input here on how people are handling this.
My ideas:
Add a "loadHistory" method on my nodejs server that sends all the history of a channel. So that my app can call a certain URL and get a
JSON formated response with all the messages. Maybe this should be done each time a table item is touched?
Make use of the new iOS7 background running features? (Im not to sure its possible to keep the socket alive with that)
Implement a way for the server to know if a message has been delivered, if it could not be delivered it stores the message on the
database. As soon as the client goes online again it sends the
messages over tcp. This would require a lot of added functionality to
the server so id like to avoid this if possible.
if you want offline message , the third way is needed, for every message you get, you need to send a notify to the server to tell it the message is delivered , and when you get connected , you should fetch the lost message.
you could use voip, but your app can not receive message if it was killed.
(if you add voip mode but your app is not about voice, apple will block your app)
I have also done some work over TCP socket. I gave background support by these steps :
Add "Required background modes" key in your plist file.
Add this code in your AppDelegate.m file
- (void)applicationDidEnterBackground:(UIApplication *)application
{
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 40000
if([[UIDevice currentDevice] respondsToSelector:#selector(isMultitaskingSupported)] && [[UIDevice currentDevice] isMultitaskingSupported])
{
NSLog(#"Keep timeout alive");
[application setKeepAliveTimeout:600 handler: ^{
NSLog(#"applicationDidEnterBackground:: setKeepAliveTimeout:handler^");//task as you want to do
}];
}
#else
LogInfo(#"applicationDidEnterBackground (Not supported)");
#endif
}
When you get your read and write CFStream socket object after a successful TCP connection, add this code
CFReadStreamSetProperty(yourCFReadStreamObj, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
CFWriteStreamSetProperty(yourCFWriteStreamObj, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
After flowwing these steps your socket should receive message in background too and connection will be active till the time you give in "applicationDidEnterBackground".
I hope this will help. Thanks
I am writing an iOS app with a Rails API backend. The Rails backend will serve JSON data to the app. I have the following requirements.
The app will be a free download
The app will show data on a map
The app will show data in the vicinity of the user
Upon loading the app the device should send some unique identifier to the server identifying itself as a device that is running this app.
There will be no authentication for the user as it is not required. The data is available to anyone who downloads the app. All the server needs to know is that the client is a device running the app. The server cannot serve data to any other client
I would like to run the data using SSL between the device and server
The user location will be sent to the server and the server returns the corresponding pieces of data that are in the vicinity of the user
The client receives the JSON and caches the data locally.
Question: Given these requirements, how to set up steps 4 & 5?
Also: If I want to search more on this topic what keywords should I be googling for?
Consider using OpenUDID or SecureUDID.
I give you 2 options.
First of all, the easy way. From some time, apple forbids access to the device ID. However, they give you a device token instead.
To get this unique token, the user must register for remote notification.
Upon application launching, call the following function:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
Then this callback will be called:
- (void)application:didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken.
Send the token to your server and you're done. Problems with this approach are obvious. Your user will have to register for remote notification.
Another approach is to use the MAC address of the wi-fi board.
To do this:
IPAddress.h
IPAddress.c
Import this files into your project.
Then use this function:
InitAddresses();
GetHWAddresses();
for (int i=0; i<MAXADDRS; ++i)
{
//There is a way you can obtain more info about the hw_addrs, but in general, it's the first.
NSLog(#"MAC: %s", hw_addrs[i]);
}
FreeAddresses();
Create a hash using the mac address above and you're done.
Hope it helps.
Upon first launch, the app sends a request to the server saying Hi, I'm a new client, give me an id! The server generates a new, random id and sends it back. The app saves the id locally and uses it henceforth to uniquely identify itself.
I am developing a chat application using XMPPFramework and Openfire as the server. Users of my app are registering themselves in a different server. I use the Openfire server solely for chat communication.
Right now, I have doubts in the architecture of my chat app.
I wish to add a user into Openfire every time a user registers on my server. For this, I have to write a service in my server to insert registered details into Openfire. Is this structure is okay?.
Another question - is it possible to insert/create a user in Openfire server using Objective-C in iPhone?. Does Openfire have any API for this, or do I have to write an external query for this to insert into Openfire database?
If insertion is possible through iPhone app instead of using external service, could anyone provide me a link to the methodology and codes to use?
In-band registration is surely the best way to do this with XMPP.
First check whether initiated xmpstream supports registration via method, 'supportsInBandRegistration'. Basic requirement for registration is that a valid xmpp connection should be present.
If registration is supported, create the below array with elements
NSMutableArray *elements = [NSMutableArray array];
[elements addObject:[NSXMLElement elementWithName:#"username" stringValue:#"userName"]];
[elements addObject:[NSXMLElement elementWithName:#"password" stringValue:[[NSUserDefaults standardUserDefaults] valueForKey:userPassword]]];
and pass through XMPPStream method,
- (BOOL)registerWithElements:(NSArray *)elements error:(NSError **)errPtr
Registration success can be checked with the following delegate method.
- (void)xmppStreamDidRegister:(XMPPStream *)sender
I am working on a simple application in which I need send sms programmatically to my friends.
so write below code for sending sms .
MFMessageComposeViewController *picker = [[[MFMessageComposeViewController alloc] init]autorelease];
if([MFMessageComposeViewController canSendText])
{
picker.messageComposeDelegate = self;
picker.recipients =[NSArray arrayWithObject:#"123"];
picker.body=#"hello";
[self presentModalViewController:picker animated:YES];
}
but I do not want to load message picker and send sms to friends.
// [self presentModalViewController:picker animated:YES];
is it possible to send sms without click in send button.
The two options available in the iOS API are:
MFMessageComposeViewController - requires user confirmation
sms:// URLs - requires user confirmation
If you want to do something else, you'll need to set up a network-based service with an SMS gateway provider and send messages via that. I used to work with such a provider that had an HTTP POST interface, which would be simple enough to use. That comes with a couple of important differences:
the SMS is actually sent by the gateway server, not the handset (though you can usually rewrite the sender ID and get the message billed to the handset owner)
you'll need to pay for access to the service, which might include paying per message (or more likely per 1,000 messages)
Also note that sending SMS on your users' behalf without confirmation might be frowned upon when your app is reviewed, especially if they're billed for.