How to upload photo with Rubymotion? - objective-c

I am building an iOS app using Rubymotion.
I need to let the user snap a photo with the camera and then upload it to a Rails 3 backend (with Paperclip) using the BubbleWrap Http module (or any better?).
How can I do this?
This is my code:
controller = UIImagePickerController.alloc.init
controller.sourceType = UIImagePickerControllerSourceTypeCamera
controller.mediaTypes = [KUTTypeImage]
controller.allowsEditing = true
controller.delegate = self
self.navigationController.presentModalViewController(controller, animated:true)
This I use after taking the shot:
metadata = info.objectForKey(UIImagePickerControllerMediaMetadata)
the_image = info.objectForKey(UIImagePickerControllerOriginalImage)
image = view.viewWithTag 3
image.image = the_image
picker.dismissModalViewControllerAnimated(true)
This is my upload code:
data = {access_token: TOKEN, id: task, image: image}
BubbleWrap::HTTP.get("#{URL}#{project}/message", {payload: data}) do |response|
if response.ok?
json = BubbleWrap::JSON.parse(response.body)
if json['total'] > 0
infos = json['taskinfos'].map {|ej| self.from_json(ej["taskinfo"])}
block.call(true, infos)
else
block.call(false, nil)
end
else
block.call(false, nil)
end
end

Uploading images should be done via a POST request and not a GET request like you have done. Most web servers have a limit to how big a GET request can be, and it is usually 8k, read here for more info maximum length of HTTP GET request? , so it's not suitable for images.
Play around with bubble motion and look at the requests in the log files on the server to see what comes out. Try to make the request look like a request made from within rails itself, ie from a web page where you upload to the the controller.
So you could change the request to POST and let people know what error messages you get.

Related

Iron Web Scraper - Login

I've read the tutorials to log into a website prior to scraping it, but it just ain't workin'. I constructed a HttpIdentity object, added it to the Identities collection, and processed the request, but the page returned to scrape was still the login page. There isn't a lot about this on their website and documentation. Here's my code for that:
var identity = new HttpIdentity
{
UseCookies = true,
NetworkUsername = _username,
NetworkPassword = _password
};
Identities.Add(identity);
Request(_uri, Parse, identity);
In the Parse method I get a Response object returned with a Status Code of 200, and the "WasSuccessful" property of Response is "true". It seems that I should be redirected to the page I was trying to access, but I'm just getting the login html.
Is there something I'm missing?
I wasn't able to find a solution using the Iron Web Scraper, but I was able to do it with ScrapySharp, which is a free utility, so it worked out. ScrapySharp is able to mimic a browser to a degree, so navigation and submitting forms is pretty easy.
var browser = new ScrapingBrowser();
var homepage = browser.NavigateToPage(_Uri); // login Uri
var form = homepage.FindForm("login"); // get form by name
form.Method = HttpVerb.Post;
form["username"] = "my_username"; // get form fields by id
form["password"] = "my_password";
var resultPage = form.Submit(); // login
var loggedInPage = browser.NavigateToPage(new Uri("https://path.to.target.page"));
And that's it. I'm not sure what the problem was with Iron Web Scraper. Maybe some ajax on the login page. In any case, this code is working for me now.

Open Camera app installed from a UWP app and capture image

Instead of creating a Windows built-in camera UI (CameraCaptureUI) or using a custom MediaCapture control and capture picture I want to open any Camera App downloaded in the device to capture an image and get the result.
I have used
string uriToLaunch = "microsoft.windows.camera:";
var uri = new Uri(uriToLaunch);
var success = await Windows.System.Launcher.LaunchUriAsync(uri);
But this just opens the camera app, I need to get the result file back to the app and save it.
Is there a way to do this?
The method you are using:
var success = await Windows.System.Launcher.LaunchUriAsync(uri);
just opens the default camera, nothing more, the result is a boolean with information if the application has been opened successfully, nothing more.
With CameraCaptureUI you don't need to create camera - this seems to be designed for the task like you have described. With lines:
var captureUI = new CameraCaptureUI();
captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
captureUI.PhotoSettings.CroppedSizeInPixels = new Size(200, 200);
var photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
you just launch the camera app and your app waits for the photo, which you can process further/save.
If you don't want to use it or implement own camera capture, you can think of sharing a picture taken by other app. This is described well at app-to-app communication at MSDN. In this case user will have to click Share button and choose your app as a target. That will invoke OnShareTargetActivated event where you can process the received content.

Attach photo to Activity through Google + Domains API

Im trying to post an activity with an image to a google+ domain with the new google + domains API
Posting an activity is working fine but when i try to attach a photo to it, i receive a 500 error with null description.
This is the code:
String msg = "Activity with photo";
// Create a list of ACL entries
PlusAclentryResource resource = new PlusAclentryResource();
resource.setType("domain"); // Share to domain
List<PlusAclentryResource> aclEntries = new ArrayList<PlusAclentryResource>();
aclEntries.add(resource);
Acl acl = new Acl();
acl.setItems(aclEntries);
acl.setDomainRestricted(true); // Required, this does the domain restriction
// Create a new activity object
Activity activity = new Activity()
.setObject(new Activity.PlusObject().setOriginalContent(msg))
.setAccess(acl);
// Attach the link
Activity.PlusObject.Attachments attachment = new Activity.PlusObject.Attachments();
attachment.setObjectType("photo");
attachment.setUrl( "http://c299813.r13.cf1.rackcdn.com/MuseeduLouvre_1335428699_org.jpg" );
attachment.setId( randomId ); //if not specified, google returns an error with "you must specify the photo id"
List<Activity.PlusObject.Attachments> attachments = new ArrayList();
attachments.add(attachment); // You can also add multiple attachments to the post
activity.getObject().setAttachments(attachments);
activity = plus.activities().insert("me", activity).execute();
When the code calls the execute, i receive this error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 500
{
"code": 500,
"message": null
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
The same code but with the attachemnt lines commented works fine. Has someone managed to create an activity with an image? any clue?
Thanks in advance.
Directly attaching a photo via URL isn't possible. The process works slightly differently, as described here: https://developers.google.com/+/domains/posts/attaching-media
If you don't have the actual binary data of the photo you will first have to "download" the photo. Then you can upload the actual photo data via the media().insert method, which will give you the Photo Id which you can then use in attachment.setId().
setUrl isn't necessary in this case.
If you want to attach a photo as URL, this could also be handled like an article attachment (same as if you would just copy/paste the URL into a Google+ post). In that case you would use attachment.setObjectType("article") and only set the Url. The id isn't necessary in this case.

Can't Save Image Blob

I am trying to save an image from the photo gallery to local storage so that I can load the image up across application sessions. Once the user is done selecting the image, the following logic is executed. On the simulator I see the error message is written out to the log. Even though I am seeing the error message I think the image is still saved in the simulato because when I restart the application I am able to load the saved image. When I run this on the device though, I still get the error message you see in the code below and the default background is loaded which indicates the write was not successful.
Can anyone see what I am doing wrong and why the image won't save successfully?
var image = i.media.imageAsResized(width, height);
backgroundImage.image = image;
function SaveBackgroundImage(image)
{
var file = Ti.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,W.CUSTOM_BACKGROUND);
if(file.write(image, false))
{
W.analytics.remoteLog('Success Saving Background Image');
}
else
{
W.analytics.remoteLog('Error Saving Background Image');
}
file = null;
}
Try this Code:
var parent = Titanium.Filesystem.getApplicationDataDirectory();
var f = Titanium.Filesystem.getFile(parent, 'image_name.png');
f.write(image);
Ti.API.info(f.nativePath); // it will return the native path of image
In your code i thing you are not giving the type of the image (png/jpeg) thats why your getting error.

Post status to Facebook profile without Facebook modal window using ASP.NET

I'm trying to work with Facebook in my ASP.NET site where I have a logged in user of my site enter in text in a box for their status on my site. I want them to be able to push that status to FB as well per their permission. I did it using simple Facebook Connect JS code but I want to get the info in .NET and push it that way. I'm not actually creating a FB app for a FB profile though.
This is pseudo-code for what I want:
Facebook fb = new Facebook(apiKey);
FBSession sess = fb.Authenticate();
if(sess.isAuthenticated) {
User u = fb.getUser(sess.userId);
u.setStatus(Textbox1.text);
u.SaveStatus();
}
Does anything like this even exist for .NET or is their API for PHP only?
Sure, here is some sample code. It's using the Facebook Developer Toolkit (you can find it on codeplex). And FBConnectAuth which can also be found on codeplex.
You want to check the cookies to make sure that the cookie is real (making sure someone is not trying to hack in); which is why the cookie validation step is important.
As long as you login using the JS code, the same cookies that are set in the JS are accessible in C#.
This works fine for a Facebook Connect app.
using FBConnectAuth;
using facebook;
public facebook.API api = new facebook.API();
bool IsLoggedInToFacebook = false;
FBConnectAuthentication auth = new FBConnectAuthentication(ConfigurationManager.AppSettings["AppKey"], ConfigurationManager.AppSettings["Secret"]);
if (auth.Validate() != ValidationState.Valid)
{
IsLoggedInToFacebook = false;
}
else
{
FBConnectSession fbSession = auth.GetSession();
string userId = fbSession.UserID;
string sessionKey = fbSession.SessionKey;
api.ApplicationKey = ConfigurationManager.AppSettings["AppKey"];
api.SessionKey = sessionKey;
api.Secret = ConfigurationManager.AppSettings["Secret"];
api.uid = Convert.ToInt64(userId);
api.status.set("statutes text goes here")
IsLoggedInToFacebook = true;
}