I am trying to make an iOS app which would involve 5 or so users connected to a single web document, with one of them editing it while the others received updates in realtime.
How can I make the app so that it can update its documents in realtime (without the user having to click a "sync" button)? It should work similar to shared google docs, when one user makes a change, it is instantly reflected in all users' copies, but it should run natively on iOS, not through a web browser.
I am not asking for a full app schematic or any code, I only need a nudge in the right direction.
I would suggest that you keep a master copy of the document on your server (and by the way, you will need a server in order to make this work effectively), and while the users edit a temporary version of the document that is stored locally on their iPhones, the server is constantly notified of changes when there is one, and when the version on the server is changed (if the version on the server isn't the same as the one on the device), the server sends a message using a special protocol that you will make to specify if
Content (text, image or something else) is added to the document
Content is removed from the document
Content is edited in the document
... You get the point
All you need are different ways to notify the devices of different types of changes made to the server document. From those notifications, the user's temporary document can get changed according to what change was made to the server's version without having to constantly download the full document over and over. Every once in a while (or from manual user input), you can have the iPhone app request the full server document to make sure that all changes made on the iPhone are correct.
Use NSInputStreams and NSOutputStreams to receive and send messages to your server. Use an NSStreamDelegate to handle server events (its only instance method is an event handling method). This guide is an excellent start if you really don't know anything about sending messages. You can send and receive NSData and NSStrings in which you can store your protocol.
As an example of protocol, an app that I have created that receives and sends messages to and from a Windows server does the following:
When preparing the data to be sent on the iOS app, I first write 4 bytes of data to an NSData object that contain the length of the proceeding data so that the server knows exactly how many bytes to read from the stream. I chose 4 bytes since that's the size of an unsigned int type, which can represent very large numbers (and therefore very large data sizes).
I add the data to the NSData object. The data is in the form of a struct in my case. Really, you can send any type of data so long as you know how to parse it at the other end.
I send the NSData object.
Really, sending, receiving and parsing NSStream messages is very simple, but if you are writing server-client code for the first time for an iOS app, the process can seem daunting. I did simplify the process down quite a bit, because you also have to consider if the server is ready to receive messages, has space available for messages to be written and so on, but the guide that I linked to earlier, which is also right here, was quite helpful as I was writing my client-server app.
Hopefully these guidelines are general enough (and specific on the right topics) for your liking.
Related
In a World of Warcraft Vanilla Lua Addon Development, how can I issue an HTTP call to receive data back? If not, how can I get data from a web source into the game while playing?
I have a feeling the answer is tragically short, but would like the question asked and answered on Stack Overflow. My research came up lacking, and I recall doing some LUA in ~2007 and was disappointed.
Well, tragically short is an understatement. You simply can't. There was never any APIs that interacted directly with connections, let alone create any, let alone to arbitrary URLs.
Most of them just broadcast game events that occur from the game's connection, and the closest thing you can get to a "data stream" is add-on chat channels. But since bots violate the ToS, you wouldn't be able to make an account that responds to your addon's inquiries.
The closest thing you can get is building an "asynchronous mesh network", but that's only good if your addon has a considerable user base, and it's not guaranteed you'll get information timely.
The general idea is that your addon will have a public key (as in encryption), and you (only you) will detain a private key. Your addon emits a message to any connected peers, which store it on cross-realm SavedVariables, and you hope that someone will have characters on more than one realm. Upon login, the client addon will broadcast its latest packet (still encrypted) to that realm's addon channel, and hopefully within a week or so you might get the updated information across all clients.
A disadvantage is that you'll only get "push" notifications, the client won't be able to send any data back to you*.
That, or you could release a patch for the addon on Curse :P
BUT WAIT!
You mention vanilla, so I can presume you're developing this for a private server. Private servers often have one or a very small amount of realms, making the above mesh network much simpler. Instead of a mesh, just have encryption and manually login&broadcast on each realm every time you want to update the information retrieved.
Plus, you might even be able to contact the server devs to allow you an API that sends messages to the appropriate ingame addon channel (you'd have to ask).
Of course, if you pretend to make your addon server-agnostic, instead of tailored to a specific server, you're back to square one.
* Unless you are really dedicated to make that happen, because it's a ton of work.
There is no web API in vanilla WoW. There is a web browser widget in the game currently though, albeit very limited in usage.
If you have access to the server software code, you may be able to hook listening on specific game channels for user messages in a defined format, and let the server respond in a way for the addon to parse it.
Given the recent addition of local datastore for iOS to Parse, it should be possible to rely exclusively on Parse to manage app's database, thus totally avoiding Core Data. Does this sound like a good idea? What would be the pros and cons of such an approach?
In particular, I am wondering whether it will be possible to pre-populate Parse local datastore with some data, and include this database as a part of the app when submitting to appstore.
UPDATE
From the comments that were posted, it seems that people misunderstood my intended use case. Sorry guys, I should have made my question more clear from the beginning. Let me clarify it now, anyway.
So, there is some amount of data in Parse database on the web, same for every user, e.g. a catalogue of books. It will be updated every now and then. What I want is to publish an app on App Store which is pre-populated with Parse data store, as it stands at the moment when the app is published. For that to happen, I'd like to pin all available data when building my app and ship that data store along with the app. The problem is that the pinned data will be stored on device's (or emulator's) file system, it won't be part of the project. That's why if I build the app and submit it to app store, the data won'd be included.
Any suggestions how to attach the local data store to the app?
The local data store is stored in the sandboxed part of the filesystem in iOS. When you package the store with the app, it'll live in the signed application folder, not in the location Parse expects it to be.
So, if you were looking to do this, you'd need to include your default local data store in the application on building/submission, and copy it into the location Parse expects it to be in (which is Library/Private Documents/Parse and the file is called ParseOfflineStore) when your application starts up. This must happen before you call enableLocalDatastore, or an empty one will be initialized.
It should be possible!
Read this in the docs. Parse has a highly resourceful and fully documented guide for their backend.
https://parse.com/docs/ios_guide#localdatastore
Per my comment above concerning didFinishLaunchingWithOptions; it has been a place for your to create objects on launch, I have been doing that for a long time. Especially with channels. However, by enabling the local data store you can access those objects you pinned or created with a simple query with no reachability per your concern. Either way they both are created on disk. Core Data has a lot more cons. Especially with NSFetchedResultsController and the flexibility it offers. It's all up to you what you want to do with your app. PFQueryTableViewController isn't bad but if your direction and vision for your app is to be exclusively Parse then why not. It's a great feature. However I didn't see anything in the docs about the local queries effecting your limit so I would suggest looking into that if you have a large audience performing numerous queries per second.
Take advantage of their docs. They do a great job at keeping us informed.
Scenario:
As a user I am able to take (an unlimited amount of) photos and videos which are stored in the apps documents folder. Each of these media files gets a record within a Sqlite database with additional information (for exeample a caption). All this is possible to do completely offline.
Back online I get a dialog with a list of all the videos and photos I took and a button which starts an upload process.
Each file is uploaded after the other together with its metadata by making a multipart POST request to the server. The response of the server is stored together with the metadata in the Sqlite database (so there is no fire and forget).
Reliable solutions?
If I am reading and understanding this chart correctly, the most simple solution would be to wrap each of these uploads within a Task. Side effect: after 10 minutes every task would be cancelled, which becomes a problem by having a slow connection or very large files (for example a very long video).
The recommended way would be to use NSUrlSession/Background transfer service.
Which leads me to my question:
Is it possible to wrap multipart POSTs in NSURLSessionDataTasks and would this be reliable, even if the task is running longer than 10 minutes or the user is suspending the app?
As I am a Xamarin/C# guy I would really appreciate some sample snippets for a working multipart upload, even if it's in Objective-C ;-).
Almost and... yes.
Background Transfer service works with NSUrlSessionDownloadTasks and NSUrlSessionUploadTasks only. Not NSUrlSessionDataTasks, as described here.
Other than this "basic" limitation, it's safe to use background transfer service with upload tasks.
The 10-minute-freepass-in-the-background no longer applies on iOS 7 (basically, it's there, but different), however, with NSURLSession and background transfer service you do not need it.
I've a blog post here for background transfer service, based on download tasks.
An important thing to note is that, starting a task basically means that it will actually start sometime and actually finish some other time. This depends on whether the device is on cellular or Wi-Fi and other factors which are (probably) only known to iOS (and Apple).
Newbie question.
I will need to have a data base from about 200 UIImages (single of them less than 500kb size) for iPad app. Customer want to have possibility to change set of this images from time to time without releasing new version of app in appstore and app must work without connection to the web (local data base on a device). I don't see how this can be done simultaneously, I see only one common option here:
Image data base would be stored on a server, what app customer will be able to change anytime. User will need to have web connection and every time he will start the application - existing data base will load into the app.
Main questions here:
is it possible to update data base on user's device without releasing new version of app and what data base managing system is more proper to this situation(SQLite, MySQL etc...)?
Q : is it possible to update data base on user's device without releasing new version of app?
A : Yes. It is possible.
SQLite will be perfect for you.
The photographs reside on the web server.
A number of start-off photographs may reside within the boundle so that the app is not really empty at start.
However, when downloading the app, the user must be online. In most cases he would still be online directly afterwards when he launches the app for the first time.
The server provides two services:
A quick one that just provides a version number of the
photo-database content and/or the date of the last change to the
photographs on the server.
The app frequently (not more than daily I would say) checks wether there are new images on the server or not.
If they are then the user is asked, whether he wants to download them.
If the user says YES then the app sends the version number and/or last date and/or IDs of all local photographs to the server and the
server provides the information about which photographs have been
added and where to download that very photograph and which have to
be deleted.
Then you add or delete or update the photographs from the download source given by the server. (That may well be an URL to the
very same server of course.)
For 200 data sets I would strongly suggest core data with SQLite - the standard stuff.
You may then think of holding the image data in the file system or in NSData properties within the database.
I'm making a program for IOS for the first time. I never had a iPhone so I don't really get how it works...
I want to make my system able to call a webservice on the background and depending in the answer show a notification.
How can I do this?
I read on the Internet that I can push notifications to the phone, however that won't solve my problem because I want my server to track the user position, so it need the user to silently tell the server it's gps coordinates.
Thank you,
GustDD
I will suggest building the app first to run in the foreground. I will assume you already understand how to use the GPS, so will not go into detail on that.
First off, you will need to write the server backend and app pretty much simultaneously. There are many choices for writing the server backend language wise. I prefer python, others ruby on rails. You want to build a REST API for the server that the iDevice can talk to with simple HTTP protocol.
You must decide on the API. You must think about what kind of data you will want to send and receive and how you will wrap the data. Also what HTTP protocols will you be using for specific requests, like GET POST etc. Furthermore, you will have to decide at what URL's on the server will it be useful to GET or POST to depending on the data you want to send or receive. I would suggest you use JSON to wrap your data. It is quite intuitive and easy to encode and decode.
Next you will have to decide how to talk to the server in iOS. There are many great third party libraries that dress up NSURLConnection or you can use NSURLConnection itself (sometimes a bit tedious). I personally like to use AFNetworking. It will do the JSON decoding and encoding for you which is a big bonus.
Finally, once you have the two communicating with how you want and with the data you want, now time to dress it up. You can allow your app to run in the background and collect GPS data and send it. You can also use the notification center to display information it gets from the server in the background.
Update to Comment
This will be extremely helpful for you with background programming. From an Android perspective, iOS is a little bit different since there is not really a direct correlation for Android services in iOS. Every little detail to put your project together is in that link.