I've been running around in circles the past few days trying to figure out a good solution for my problem. The main key here is that this is for an iOS application. What I want is to quickly communicate from one device to another device updates. So if user 1 performs an action, I want to, in real time, tell user 2 that user 1 has performed this action.
I don't want to use Apple Push Notifications for various reasons. So that's out of the question. I looked into services like Pusher and PubNub, but those are far too expensive (and only allow a ridiculously low number of concurrent connections, ~2500). I also looked into Google App Engine's Channel API, but it works through Javascript, and would have to be implemented using shady techniques on iOS. And honestly I'd rather not use that.
So now I'm looking into XMPP in Google App Engine. It seems like it would do what I want, but I'm not sure if I'm understanding the whole picture. Couldn't I accomplish what I wanted using XMPP messages, that is when user 1 performs an action, I can notify user 2 quickly with a JSON message?
The main key here is that I would have to perform user registration for XMPP behind the scenes, using the user's unique ID. Is this possible, to automatically and without user intervention create a Jabber ID like user-unique-id#my-app-engine-domain.com?
Overall, is this a feasible solution? What am I missing? What are some exceptions?
What you have described all sounds fairly easily doable with XMPP.
Just a couple of points.
You do realize, of course, it is XML based, so your JSON messages would be embedded within XML stanzas, with appropriate escaping when necessary.
Your user registration would be determined by the server implementation, but I believe most will allow custom authentication hooks (like LDAP). So having an external registration mechanism shouldn't be a problem and is a fairly common approach.
Since you are using ios, you should be looking at XMPPFramework as your XMPP library.
Depending on your use case, you may want to look at XMPP pubsub as well for your updates, depending on how many other devices are supposed to get the message when one makes a change. I have used this approach and it works well for real time client to client updates.
AppEngine supports XMPP only as client: it can send and receive messages. The key here is if you look at the docs for sending XMPP message, that every client needs to have it's own address (JID) which is not provided by GAE.
So to support your situation, you would need to have an external XMPP server, where every client gets it's own JID and then you can send XMPP messages to them.
Related
I'm developing a Mac app that uses CloudKit as its back-end. Some of my users are requesting the ability to ingest and extract data via an automation/integration service such as Zapier. For this, I need to introduce a web API.
I am planning to use CloudKit Web Services to access the app's data. This data is user-specific and hence, resides in a private database. As a result, CloudKit requires user authentication as described here.
Essentially the user needs to be redirected to an Apple-hosted authentication page. After successful authentication, an authentication token is provided that can be used for data operations. Similar to how OAuth2 works, but different enough to not work with Zapier's (or probably any other similar services) supported authentication schemes.
Who has done something similar? What are my options? I want to keep things as simple as possible and make my web API's implementation as thin as possible.
Thanks.
Niels
This is definitely doable and you are on-track with your thinking. Here's how I envision it working:
You could do all of this with a front-end web app (no server-side app needed). I personally prefer Vue.js but you probably have something in mind already.
Your app will need to authenticate the user to CloudKit using the flow you mentioned. I highly recommend you use the Web Services API and not try to wrestle Apple's neglected CloudKit JS API. For this, you are going to need to generate an API token in the CloudKit Dashboard.
You app would then prompt the user to authenticate to Zapier.
You should now have user credentials for both CloudKit and Zapier in place in the user's browser cache (you can save, for example, the CloudKit token to sessionStorage and likewise with Zapier).
Make API calls to Zapier, pull down the data, and then save it to CloudKit all within your JS app. It's all API transactions at this point. I'm a fan of Axios for making the HTTP requests.
If you are downloading files, transacting huge amounts of data, or doing processor-intensive stuff, you might consider using a server for that work. But if you just need a place to pull and push reasonable chunks of data, I see no reason why you can't do it all in a front-end app.
Alternatively, if you don't want a web app at all, and want to only have the user work in the Mac app, that can be done, too. Just make API calls directly to Zapier from within your Cocoa app. Whether or not this is feasible depends some on how you want it to work.
If you have more specific questions or need help with any of the implementation details, feel free to add a follow-up comment or ask a new question.
Good luck!
I think the other answer is mostly correct. I don't know much about CloudKit, but we can talk through what you'd need for it to work.
Let's say you had a simple iOS app that stored contacts. On the iOS side, Apple presumably abstracts the upload and download operations.
If you wanted to make a web viewer for synced contacts using CloudKit, you'd need an endpoint to fetch all rows belonging to the authenticated user (each of which would have a UUID, name, and a phone number). I believe that's possible with CloudKit code Apple provides (but let me know if I'm off base).
Now, we want to integrate with Zapier. Say, a "New Contact" trigger. You make some sort of authenticated HTTP request from Zapier to Apple on behalf of an authenticated user. It gives back a list of contacts and Zapier can trigger on the ones it hasn't seen before. To do that, Zapier needs some sort of user token.
That's where the little front-end page the other answerer mentioned comes into play. If you've got a web page that can surface a user's token to them, they can paste it into Zapier and all of the above becomes possible. I'm not sure what the lifespan of the token is, but hopefully it can be automatically refreshed as needed (rather than the user needing to take any manual action).
I'm not sure if what I've described is possible, but do let me know if it is. It would be huge if it were possible to integrate Zapier and the iOS ecosystem!
Edit to respond to comments:
Zapier won't be able to interact with CloudKit in a way sufficient for me (some minor business logic is needed)
I'm not sure what that entails for you, but it's common to put logic in the Zapier integration to structure data in a way Zapier expects. There's a full Node.js execution environment, so the sky's the limit here.
I don't think Zapier can authenticate against CloudKit as it uses a non-standard authentication scheme
Once you've got a user's token (described above, which is unusual), you will almost certainly be able to use it in requests to cloudkit. Zapier provides a "custom" authentication scheme which lets you do basically anything you want. So unless Apple uses something that fetch can't handle (unlikely), it should be fine (once you get the token).
I would like to push data directly from my app into Zapier and have it done whatever magic the user has configured
This is also probably possible. Zapier ingests data in two ways:
polling, where Zapier frequently makes a web request, store the IDs of items we've seen before, and act on the new ones. You can read more about that here. Assuming you can work your business logic into the integration, this is doesn't require an external server besides Apple's
webhooks, where Zapier registers a subscription with you and you send new data, on demand, to that address. This would probably require a webserver on your end to handle. It's optional though - you can do polling instead.
Hopefully this cleared it up a bit. Feel free to reach out to partners#zapier.com and reference this question to talk more about it.
I'm just starting iOS app development with Swift (and in general) and I'm looking to get some information on popular practices when creating apps that require communication over arbitrary networks (i.e. not necessarily on the same network). I tried searching this on google but the answers weren't entirely what I was looking for; hopefully somebody can point be in the right direction. I wouldn't mind paying for a service, but unfortunately I don't know the first thing about backends and don't want to end up overpaying for services that I don't need. For example, I found an API called Parse, but I think it has far too many features that wouldn't benefit my app. Here's the main premise of the app:
There are two versions of the app - one for Admins and one for Employees
The Admins have the ability to post notes to a central list of notes for the employees to see
The Employees can access this list and scroll through it to pick which one they want to open. After a certain number of time, the notes expire and are removed from the list automatically
It's as simple as that. There likely won't be too many notes getting sent at once, so a large database isn't needed. My questions are as follows:
Do I need a database to store the notes, or can I handle it in some other way?
How is communication generally handled? The only things I've come across are ways to communicate when you're on the same WiFi or Bluetooth, but I haven't seen anything outside of that. How does an app like GroupMe communicate to users?
This is more of a general question, but how can you tell if you need a backend or not? I'm still kinda confused on the interaction between the frontend and backend.
Any help for any of the questions is greatly appreciated. I feel as though I don't even know where to start with a project like this.
EDIT: To clarify, I'm just looking for a place to start, not code or any implementation.
It's as simple as that. There likely won't be too many notes getting sent at once, so a large database isn't needed. My questions are as follows:
Do I need a database to store the notes, or can I handle it in some other way?
Yes you need some kind of database. That could be something complex like MySQL or something simple like writing a txt file for each note to the disk, with the filename being the date of the note.
You could use a service like Parse or run your own PHP server and write the software yourself. Parse is cheaper for a small database, running your own PHP server is cheaper for a big one and it gives you more control.
(You don't have to use PHP, but that is the most popular language for these things and it's what I use).
How is communication generally handled? The only things I've come across are ways to communicate when you're on the same WiFi or Bluetooth, but I haven't seen anything outside of that. How does an app like GroupMe communicate to users?
Usually your the phone sends a HTTP POST request to the server with some text in JSON format in the body of the HTTP request.
The server then responds with more text in JSON format in the response.
On the phone you use NSURLSession to handle to do the network communication and NSJSONSerialization to encode/decode the content. On the server, there will be something equivalent available.
Usually there would be a username and password or some other authentication system in the HTTP POST JSON text that tells the server wether or not the user is allowed to do whatever they're trying to do.
All communication between the phone and the server must be encrypted using SSL to protect your users. Do your homework and make sure you get this part right before you deploy your app to the store.
Parse will handle all of that stuff for you, but it's good to at least understand what's going on.
This is more of a general question, but how can you tell if you need a backend or not? I'm still kinda confused on the interaction between the frontend and backend.
You know you need a backend if you want two devices to communicate without being on the same WiFi/Bluetooth network. This is a security feature that cell network carriers (and home broadband ISPs) enforce to prevent malicious activity.
Generally only a commercial internet connection (and commercial router) will allow anonymous incoming network packets to get through to a phone/computer connected via that internet connection. Consumer internet connections only allow traffic coming in from a known source (for example, if you ask Google for some data, the router will temporarily allow Google to send some data to you. But if Google just sends some data without a phone/computer in your home asking for it, then it will be rejected).
You should be able to take what I've written and do a bunch of research.
If you decide to go with writing your own system in PHP, it comes pre-installed with OS X (just has to be enabled) and you can access it by IP address from the phone as long as you're on the same IP address. That should get you started for testing/development purposes at least.
The only part you won't have is SSL. Starting in iOS 9 (it's almost here!) you will need to disable NSURLSession's built in check for SSL or else it won't let you connect to the test server.
I am new to web development but I have a project done in VB6, it is a real time send and receive sms application. It uses a GSM modem connected to the server. My company asked me to make a web based version of my application, using ASP.NET MVC.
So I studied MVC about a month ago, created basic CRUD apps, read about SignalR but I don't want to start up a project that I am not confident if its feasible or not. So my question is, is this project possible with the said technology? (MVC, SignalR, and a GSM Modem)
If it is, can you point me somewhere I could start reading for maybe you know a similar project that can guide me through.
And if it is not, can you suggest me the appropriate tech to use for this project to be feasible? (I prefer ASP.NET MVC)
A little detail about the functionality of the project:
Has User Authentication - this user will have a simple "SMS box" type of thing which will update like a chatbox if an SMS is received in the GSM modem and this user can reply and use the GSM to send the SMS back to the sender.
IF anyone could help me, guide me, point me to some reading materials to make this project it would be greatly appreciated. Please post if you need clarifications and further explanation. Thanks!
User,
There are many ways to achieve this, so I will explain a method that worked for me a while back doing exactly this.
Based on the information provided, I will assume that you have a windows desktop app, that can already talk to the modem and perform various functions.
Trying to perform that same tasks in a web application can be a hard path to go down, what I opted for was rather simple in my opinion. You really have two separate problems, one is getting the received messages to the web application and the other getting the web application to send messages to the modem.
For handling received messages, I created a simple web api in the web application and defined a post method that is able to receive a sms object. You will need to provide the url for this call to your code that resides in your modem project, which I would convert to a windows service, if it is not already. Then when your code fires when the modem has received a sms, you simply create a object, serialize it to xml or json and then call the post method in your web api. This will give you the chance to use SignalR to notify clients or whatever else you might need to do. This is honestly is the simple part and you have the "real-time" handling ability now for receive.
For sending, there again where many options, I opted for database polling from the code inside the windows service, so when a user wants to reply or send a message, the message gets stored in a table in a database, from where the service code will pick it up and send it, once sent it will mark a field in the table as sent and possibly add a date and time as to when this happened. Again your service code could call another method on your web api, that will notify your app, that a message was sent and again you could notify the end user.
As for database polling, there are various methods, you could simply run some code every minute or some configurable value to see if there are any unsent messages.
You could use SqlDependency and handle the events in real time, you would register an event against the table where messages to be sent will be inserted into and when this happens, your service code will receive a real time event which can be handled.
You could also in the windows service, create a service, even a self hosted web api again, which can be called from your web application when it wants to send an email.
I did various implementations based on client requirements, but for me hosting either a wcf service or web api in the windows service project, proved to be the best in my opinion. You then simply have a configuration section in your web application, and provide the service address, or uri for the post method.
I hope that I have given you enough ideas to get a starting point for your project.
With CloudKit, you can focus on your client-side app development and let iCloud eliminate the need to write server-side application logic. CloudKit provides you with Authentication, private and public database, structured and asset storage services — all for free with very high limits.
You cannot upload any code to run on Apple's servers?
I've heard it being compared to Google App Engine and other cloud computing platforms, but without the ability to run your own code, isn't the whole thing pretty limited and not really comparable?
For example, if I want to build a news app which periodically pushes stories on topics that the user is interested, then this can't be done just using CloudKit because I would need scheduled jobs and data processing on the server.
Any thoughts?
Server-side
As you said CloudKit doesn't allow server-side code.
But there are possibilities.
Crons
You don't want to connect to the iCloud Dashboard everyday in order to perform the push by adding a record. One solution here is to code an app on a mac server (I guess mac mini as server will become more popular with CloudKit) that add a new Daily CKRecord every day.
Subscriptions
Subscriptions concept is that the client registers for specific updates. You can create a record type called Daily for instance and make users register to it. You should check the Apple documentation and WWDC14 videos (even if Subscriptions are not detailed, it's a good start point).
The good thing is push notifications are linked with the subscription concept. So basically you say: Send my a notification for each new CKRecord of type Daily added.
BaaS party
What is the point for using CloudKit (vs Parse and other?)
Price: CloudKit has a really nice pricing
Ready to go: 2 clicks inside XCode and you are ready to go
User consistency: you get free user login for all his devices through their iCloud account. With a very good privacy system. And you can get relationships with a smart system.
But:
You are stick on Apple platform. We don't even know if we could export the data..
Only data-centered for now (no server-side code)
The CloudKit dashboard is too limited
The future
CloudKit is still pretty new. At the WWDC some guys behind it made me understand that they are still heavily working on it. My bets are they are working on 2 important points :
Server side code execution through remote scheduled tasks
CloudKit for Analytics (Visualization side)
Edit: Apple guys are fully aware and concerned about the lack of web access for the data. It means that one day it may be accessible from other platforms. I read in a comment that Apple probably would have bought Parse if CloudKit wasn't better, AFAIK they tried to buy Parse (skills buy it's said, but we don't really know).
Update WWDC15
CloudKit is now available in JS and some dashboard are available now. Wait and see.
Update February 2016
CloudKit Now Supports Server-to-Server Web Service Requests
Web Services Reference
In some cases, we do not need server-side logic, and just storing static data can cover all the usage scenario.
In this case, it would be very helpful if there's a free accessible storage that you can store something. CloudKit provides such stuffs rather then full service platform.
Yes it is limited. Anyway can be useful for some people. For example, your case actually can be supported CloudKit. Though CloudKit is just a static storage, it support subscription. Which monitors a set of conditions and pushes the event notification to client. It's fortunate that the only background job feature supported by CloudKit is just what you need.
Anyway, if you need more, then you might need to consider full fledged servers. Usually simple web services with simple server-side code execution support are also limited.
You cannot upload any code to run on Apple's servers?
You can and you can't. You can't upload code / SOAP based web services to the server, instead of it you can upload / store observers on the server, called subscription.
whole thing pretty limited and not really comparable?
I would say in CloudKit and in MBaas client communicates with server though a more narrower more robust interface: you can not upload exotic web service to do XML parsing, database manipulations and based on it trigger push notifications, but RestFull architecture allows you to perform the 4 basic operation on the data store, and with subscription client can get notified about INSERT / UPDATE / DELETE operations performed on tables.
I think MBaas is just the next step in evolution of server - client architecture. First it seems it is limiting, but you can do all as in SOAP based web services world. Development is extremely fast / scalable / comfortable to use and easier to control things like permissions / setup, maintain server, security needs almost no effort.
Believe it or not, you can actually get REALLY far with this approach.
I've not used CloudKit, but I can describe for you my application stack:
AngularJS (or your favorite client side HTML rendering framework): A single page will host a series of templates/controllers selected by the router and driven by users changing the anchor to select which page they're on.
Firebase.io (or your favorite cloud storage): Any dynamic data goes into the cloud document store. The controller needs to load the data and render the template on the client, and when the data changes, send the data back. This also provides the authentication and authorization as well, since you can limit access to the data.
Now you need a place to serve the HTML/CSS/JS/images... which requires no 'server side code execution', just a web server where you can put the assets.
Using this technique you could store all the user's topics in the database for that user, and when the page loads, go and aggregate all the sources for those topics (also stored in the database) completely client side. There's nothing in your example application which actually requires server side execution that I can see, so long as you have cloud storage which will provide you with authentication and authorization services, and a 'dumb' web server for serving up static assets.
CloudKit isn't a full-fledged web hosting service. Instead, it's an SDK for iCloud. You shouldn't be putting a web site up there, just storing user data that you may want to use in multiple applications or platforms.
iCloud APIs enable your apps to store app data in iCloud, keeping your apps up to date automatically. Use iCloud to give your users a consistent and seamless experience across iCloud-enabled devices.
Essentially combining Parse with Pubnub, Pusher or similar, Instead of building a custom backend from scratch.
I'll be working on a real-time messaging system with facebook login and file storage/sharing. In theory I could use a combination of Parse and something like Pubnub to cover backend requirements. Were:
Parse takes care of:
Login
File Storage
Push-notifications(closed app)
And Pubnub takes care of:
real
time delivery of messages...
Requirements:
I need a system that can extend to millions of users if needed and can be deployed quickly
In general a solution that will fit this criteria and specs.
Criteria:
Quick deployment by one or 2 developers.
Can expand to millions of users.
High reliability
Specs:
FB Login
Realtime Msg delivery
Push for closed app delivery
Shared file & image storage
Any feedback if this as a first stage deployment would work well and any pitfalls would be greatly appreciated.
I'm a little biased but check out StackMob (www.stackmob.com), with the StackMob Marketplace you get direct access to PubNub with no need to create a second account. There are also a lot of other great services in the marketplace to add functionality such as SendGrid.
All the features you are looking for are out of the box even the separate development and production accounts. Something you don't get with Parse. With a simple click of a button you can move Schemas and custom code from development to production.
We can certainly support the users you are talking about. We have 7 games from Atari on the platform and other big enterprise like Land O Lakes and Adidas Japan. We also have a great track record when it comes to reliability.
Sounds good, but 2 systems (Parse and PubNub) contradict your criteria Quick deployment by one or 2 developers.
There is reason to find one system which satisfies all your requirements.
You could loot at QuickBlox backend - your own cloud backend
It has 7 modules(sets of API) for different tasks. You may be interested in:
Users module - it has Facebook/Twitter login
Messages module - this is Push Notifications. It supports iOS, Android, BlackBerry, WindowsPhone push notifications
Content/CMS module - it allows to store/share/stream any type of files, any size (up to 5 TB!)
Chat module - realtime message delivery. QuickBlox Chat is a quick and reliable chat solution which combines benefits of scalable cloud hosted XMPP chat server, seamless Single Sign-On authorization via Users module, incoming IM / chat alerts via Push Notifications and file attachments via Content.
I recommend look at it, it also have lots of great features such custom API creation via Custom Objects module
Also, there is Enterprise solutions - QuickBlox this is white box, so you can deploy it to your own server and re-sale to other clients if you want
The short answer:
no.
The details:
Anyway you hash it, it's too expensive to setup a chat with any of these systems since their BaaS model is based on charging on a per number of calls basis.
I had to work out a lot of the logic my self using parse.com and now that I'm implementing an XMPP solution, the quantity of work is the same to get something working.
My alternative solution:
Use an open source xmpp server like ejabberd on something like AWS and then use one of the APIs to connect to it.
Contact me of you need more info on my experiences:
#andrescanella