Writing a URL to an embed-field using PodioKit - objective-c

I hope to find some help to diving deeper into Podiokit, the ObjC-API to Podio. I try to set a link-field's value to a URL. My first simple try looked like this:
NSDictionary *embedAttributes = [NSDictionary dictionaryWithObject: #"http://www.google.com" forKey: #"url"];
PKTEmbed *embed = [[PKTEmbed alloc] initWithDictionary: embedAttributes];
item[#"linkfield"] = embed;
I found an example using PHP but had no luck to transform it into Objective-C:
$attributes = array( 'url' => 'http://www.infranet.com' );
$embed = PodioEmbed::create( $attributes );
$attribute['embed']['embed\_id'] = $embed->embed\_id;
$attribute['file']['file\_id'] = $embed->files[0]->file\_id;
$this->orgItem->field('organizationlink')->set\_value($attribute);
Maybe someone knows how to get it right, would be fine :-)
[Edit] The PodioKit-Manual just says:
PKTEmbed *link = ...;
item[#"link"] = link;
[Edit 2] The error occurs when I try to save the item. The log says:
Error: Saving file Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: Ungültige Anforderung (400)" UserInfo=0x600000c7ee80 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x6000008358e0> { URL: https://api.podio.com/item/app/_xxxx_/ } { status code: 400, headers {
"Content-Length" = 263;
"Content-Type" = "application/json; charset=utf-8";
Date = "Sat, 27 Sep 2014 19:16:22 GMT";
Server = nginx;
"X-Podio-Request-Id" = yqyl6yku;
"X-Rate-Limit-Limit" = 250;
"X-Rate-Limit-Remaining" = 248;
} }, NSLocalizedDescription=Request failed: Ungültige Anforderung (400), NSErrorFailingURLKey=https://api.podio.com/item/app/_xxxx_/}
Thanks,
Michael / Hamburg

Sebastian at Podio here. You need to first create the PKTEmbed object server side, then use it as the value of the item field. So you would use:
PKTItem *item = ...;
[[PKTEmbed createEmbedForURLString:#"https://www.google.com"] onSuccess:^(PKTEmbed *embed) {
item[#"link-field"] = embed;
} onError:^(NSError *error) {
// Handle error
}];
The server will assign you an embedID and generate a thumbnail for you etc. I will look into adding the ability to simply provide a URL string directly, as I agree that makes a lot of sense.
Hope that helps!

Related

Getting certificate error in Uploading image with https Amazon AWS

I am facing an issue while uploading image in Amazon AWS. Here is my code:
import UIKit
protocol ContentUploaderDelegate {
func onContentLoadComplete(status:Bool,serverResponse:String)
}
class ContentUploader
{
let contentURL = "https:<MY URL>amazonaws.com/api/v1/contents"
var delegate:ContentUploaderDelegate?
func uploadImage(image:UIImage,xAuth:String,mimeType:String,imageName:String)
{
let url = NSURL(string: contentURL)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
let boundary = generateBoundaryString()
//define the multipart request type
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.setValue(xAuth, forHTTPHeaderField: "x-auth-token")
request.setValue("application/json", forHTTPHeaderField: "accept")
let image_data = UIImageJPEGRepresentation(image, 1.0)
if(image_data == nil)
{
return
}
let body = NSMutableData()
//name to save in server
let fname = imageName
let mimetype = mimeType
//define the data post parameter
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:form-data; name=\"test\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("hi\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:form-data; name=\"files\"; filename=\"\(fname)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(image_data!)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
//set the HTTPBody
request.HTTPBody = body
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("error")
self.delegate?.onContentLoadComplete(false, serverResponse: (error?.description)!)
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("success \(dataString)")
self.delegate?.onContentLoadComplete(true, serverResponse:dataString! as String)
}
task.resume()
}
private func generateBoundaryString() -> String
{
return "Boundary-\(NSUUID().UUIDString)"
}
The following delegate method never gets called. What could be the reason?
func URLSession(session: NSURLSession,
task: NSURLSessionTask,
didReceiveChallenge challenge: NSURLAuthenticationChallenge,
completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?)
-> Void) {
let protectionSpace = challenge.protectionSpace
let theSender = challenge.sender
if protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
if (challenge.protectionSpace.host == "ec2-52-36-216-81.us-west-2.compute.amazonaws.com") {
if let theTrust = protectionSpace.serverTrust{
let theCredential = NSURLCredential(trust: theTrust)
theSender!.useCredential(theCredential, forAuthenticationChallenge: challenge)
return
}
}
}
theSender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
return
}
}
And I am getting the following error. Any idea why getting this error?
Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this
server is invalid. You might be connecting to a server that is
pretending to be “.amazonaws.com” which could put your
confidential information at risk."
UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=Would you like to
connect to the server anyway?, _kCFStreamErrorDomainKey=3,
_kCFStreamErrorCodeKey=-9813, NSErrorPeerCertificateChainKey={type = immutable, count = 1, values = (
0 : .com i: www..com> )}, NSUnderlyingError=0x7f9d42aedc10 {Error
Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)"
UserInfo={_kCFStreamPropertySSLClientCertificateState=0,
kCFStreamPropertySSLPeerTrust=,
_kCFNetworkCFStreamSSLErrorOriginalValue=-9813, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, kCFStreamPropertySSLPeerCertificates={type = immutable, count = 1, values = (
0 : .com i: www..com> )}}}, NSLocalizedDescription=The certificate for this server is
invalid. You might be connecting to a server that is pretending to be
“.amazonaws.com” which could put your confidential information
at risk., NSErrorFailingURLKey=https://amazonaws.com/api/v1/contents,
NSErrorFailingURLStringKey=https://.amazonaws.com/api/v1/contents,
NSErrorClientCertificateStateKey=0}
Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “.amazonaws.com”
I believe something is wrong with the common name “.amazonaws.com”
NSErrorFailingURLKey=https://amazonaws.com/api/v1/contents,
NSErrorFailingURLStringKey=https://.amazonaws.com/api/v1/contents
The URLs shown in the error message do not appear to be a well know endpoint. I would expect to see something like https://ec2-2-2-2-2.compute-1.amazonaws.com or another Fully Qualified Domain name there.
The error message also confirms this. You are connecting a host, but the name on the certificate does not match. This is the reason for the pretending to be “.amazonaws.com” error.
Confirm the correct endpoint, and how your code is forming the full URL.
The following delegate method never gets called. What could be the
reason?
The error occurs before the function is called. The session is never established because of the certificate error.

how to Pass Raw Json to post request in Swift?

Hi I am new to swift please spare me.
I need to post to particular API but the api is not a fan of key value pair the api expect raw json as post data
I use this library here to make post request.
this is my code
func postItem(itemname: String, itemnumber: Int, itemcode:String, url:String, baseURL:String, completion: (result: Dictionary<String, AnyObject>) -> ()){
var dict: Dictionary<String, AnyObject>!
var params: Dictionary<String,AnyObject> = ["parentItem": ["itemname":itemname,"itemnumber":itemnumber,"itemcode":code]]
let data = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.PrettyPrinted, error: nil)
let string = NSString(data: data!, encoding: NSUTF8StringEncoding)
var request = HTTPTask()
request.requestSerializer = JSONRequestSerializer()
request.requestSerializer.headers[headerKey] = getToken() //example of adding a header value
request.POST(url, parameters: params, success: {(response: HTTPResponse) in
if response.responseObject != nil {
let data = response.responseObject as NSData
var error: NSError?
dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as Dictionary<String, AnyObject>;
completion(result: dict)
}
},failure: {(error: NSError, response: HTTPResponse?) in
dict = ["error" : "error" ]
completion(result: dict)
})
}
i need to pass this kind of raw json in api
eg. {"parentItem": {"itemname":"Cocoa","itemnumber":123,"itemcode":"cocoa-12-A"}}
but when I println my params because it is dictionary it generate something like
["parentItem": ["itemname"="Cocoa"; "itemnumber"=123; "itemcode"="cocoa-12-A"]]
I just couldn't convert the params to JSON because the library I'm using is expecting dictionary and I'm having a hard time creating my own class.
could anyone help me? any comments and suggestion would do. Thanks in advance.
Why don't use Alamofire framework ? It's pretty good and sends standard json

Restkit 20 failed to match all (0) response descriptors

I don't know if failed to match all (0) response descriptors means there are 0 descriptors?
Here are some logs:
PATH:
search/patients?q=qwer&start=0&max=40
BASE URL:
https://amb.XXX.com/
RKRESPONSEDESCRIPTORS:
(
"<RKResponseDescriptor: 0xaaca6a0 method=(GET) pathPattern=search/patients?q=qwer&start=0&max=40 keyPath=(null) statusCodes=(null) : <RKObjectMapping:0xaab4f80 objectClass=NSMutableDictionary propertyMappings=(\n \"<RKAttributeMapping: 0x9edf630 final_page => finalPage>\",\n \"<RKRelationshipMapping: 0xaac9750 results => patientSearchResultDetails>\"\n)>>"
)
restkit.object_mapping:RKMapperOperation.m:378 Executing mapping operation for representation: {
"final_page" = 1;
results = (
{
age = "39 years";
"date_of_birth" = "1975-01-15";
gender = Male;
mrns = {
effective = (
10000423
);
ineffective = (
);
};
"name_full_formatted" = "DOE, PETER";
"person_id" = 1390007;
"phone_numbers" = {
home = "(816) 555-5555";
};
"preferred_name" = PETE;
"primary_care_provider" = {
name = "Test, Physician4";
};
}
);
}
and targetObject: (null)
2014-04-16 12:45:03.263 IONShell[31463:4f03] D restkit.object_mapping:RKMapperOperation.m:404 Finished performing object mapping. Results: (null)
2014-04-16 12:45:03.264 IONShell[31463:4e1b] E restkit.network:RKObjectRequestOperation.m:208 GET 'https://amb.XXX.com/search/patients?q=qwer&start=0&max=40' (200 OK / 0 objects) [request=1.5086s mapping=0.0000s total=1.5143s]:
error=Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "No response descriptors match the response loaded." UserInfo=0xa9eead0 {NSErrorFailingURLStringKey=https://amb.XXX.com/search/patients?q=qwer&start=0&max=40, NSLocalizedFailureReason=A 200 response was loaded from the URL 'https://amb.XXX.com/search/patients?q=qwer&start=0&max=40', which failed to match all (0) response descriptors:, NSLocalizedDescription=No response descriptors match the response loaded., keyPath=null, NSErrorFailingURLKey=https://amb.XXX.com/search/patients?q=qwer&start=0&max=40, NSUnderlyingError=0xa9e3f40 "No mappable object representations were found at the key paths searched."}
Does (0) mean my RKObjectManager has no response descriptors? Or am I missing something else? This is driving me nuts.
thanks
Figure it out. I needed to send down the query part of the string as params.
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:queryString, #"q", start, #"start", maxCount, #"max", nil];
[self loadObjectsAtResourcePath:#"search/patients" params:params objectMapping:mapping]

Cocoa: Handling 407 http response cfnetwork

I am creating downloader application.
I am facing a problem with proxy authentication.
I am getting 407 response code i.e proxy authentication required. I have valid proxy authentication details.
Following is Code Flow:
1. Create Http request using CFHTTPMessageCreateRequest
2. Set necessary header field values like Cache-Control, Accept-Ranges, Range & User-Agent using CFHTTPMessageSetHeaderFieldValue
3. Create read stream using CFReadStreamCreateForHTTPRequest
4. Set proxy server URL & port properties on read stream using CFReadStreamSetProperty
5. Set kCFStreamPropertyHTTPShouldAutoredirect to kCFBooleanTrue using CFReadStreamSetProperty
6. open read stream using CFReadStreamOpen
7. In a loop wait for stream to get opened
while (1)
{
if (kCFStreamStatusOpen == CFReadStreamGetStatus)
{
if (CFReadStreamHasBytesAvailable)
{
Get Http response header using CFReadStreamCopyProperty
Get response code using CFHTTPMessageGetResponseStatusCode
if (200 || 206 is response code)
SUCCESS
else check if response code is 407.
}
}
}
I tried using following code
if (407 == nsiStatusCode)
{
CFStreamError err;
cfAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, cfHttpResponse);
if ((cfAuthentication) && (CFHTTPAuthenticationIsValid(cfAuthentication, &err)))
{
if (CFHTTPAuthenticationRequiresUserNameAndPassword(cfAuthentication))
{
CFHTTPMessageApplyCredentials(cfHttpRequest, cfAuthentication, (CFStringRef)pnsUserName, (CFStringRef)pnsPassword, &err);
}
}
}
but unable to make it work.
How do I handle 407 status code so as to communicate with authenticating HTTP server?
Thanks in advance.
Vaibhav.
Build a CFHTTPMessageRef
-(CFHTTPMessageRef)buildMessage
{
NSURL *myURL = [NSURL URLWithString:#"http://myurl.com"];
NSData *dataToPost = [[NSString stringWithString:#"POST Data It Doesn't Matter What It Is"] dataUsingEncoding:NSUTF8StringEncoding];
//Create with the default allocator (NULL), a post request,
//the URL, and pick either
//kCFHTTPVersion1_0 or kCFHTTPVersion1_1
CFHTTPMessageRef request = CFHTTPMessageCreateRequest(NULL, CSTR("POST"), (CFURLRef)myURL, kCFHTTPVersion1_1);
CFHTTPMessageSetBody(request, (CFDataRef)dataToPost);
//Unfortunately, this isn't smart enough to set reasonable headers for you
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("HOST"), (CFStringRef)[myURL host]);
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Length"), (CFStringRef)[NSString stringWithFormat:"%d", [dataToPost length]);
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), CFSTR("charset=utf-8"));
return [NSMakeCollectable(request) autorelease];
}
Send it to the server and read back the response
-(CFHTTPMessageRef)performHTTPRequest:(CFHTTPMessageRef)request
{
CFReadStreamRef requestStream = CFReadStreamCreateForHTTPRequest(NULL, request);
CFReadStreamOpen(requestStream);
NSMutableData *responseBytes = [NSMutableData data];
CFIndex numBytesRead = 0 ;
do
{
UInt8 buf[1024];
numBytesRead = CFReadStreamRead(requestStream, buf, sizeof(buf));
if(numBytesRead > 0)
[responseBytes appendBytes:buf length:numBytesRead];
} while(numBytesRead > 0);
CFHTTPMessageRef response = (CFHTTPMessageRef)CFReadStreamCopyProperty(requestStream, kCFStreamPropertyHTTPResponseHeader);
CFHTTPMessageSetBody(response, (CFDataRef)responseBytes);
CFReadStreamClose(requestStream);
CFRelease(requestStream);
return [NSMakeCollectable(response) autorelease];
}
Adding Authentication to an HTTP Request
-(void)addAuthenticationToRequest:(CFHTTPMessageRef)request withResponse:(CFHTTPMessageRef)response
{
CFHTTPAuthenticationRef authentication = CFHTTPAuthenticationCreateFromResponse(NULL, response);
[NSMakeCollectable(authentication) autorelease];
CFStreamError err;
Boolean success = CFHTTPMessageApplyCredentials(request, authentication, CFSTR("username"), CFSTR("password"), &err);
}
Putting It All Together
-(void)magicHappens
{
CFHTTPMessageRef request = [self buildMessage];
CFHTTPMessageRef response = [self performHTTPRequest: request];
UInt32 statusCode;
statusCode = CFHTTPMessageGetResponseStatusCode(response);
//An HTTP status code of 401 or 407 indicates that authentication is
//required I use an auth count to make sure we don't get stuck in an
//infinite loop if our credentials are bad. Sometimes, making the
//request more than once lets it go through.
//I admit I don't know why.
int authCount = 0;
while((statusCode == 401 || statusCode == 407) && authCount < 3)
{
request = [self buildMessage];
[self addAuthenticationToRequest:request withResponse:response];
response = [self performHTTPRequest: request];
statusCode = CFHTTPMessageGetResponseStatusCode;
authCount++;
}
NSData *responseBodyData = [(NSData*)CFHTTPMessageCopyBody(response) autorelease];
NSString *responseBody = [[[NSString alloc] initWithData:responseBodyData encoding:NSUTF8StringEncoding] autorelease];
NSLog(responseBody);
}
Refer this link.

how to specify open id realm in openid4java 0.9.5

my url # development : http://192.168.0.1:8888/com.company.MyEntryPoint/MyEntrypoint.html
my url # live env : http://www.example.com/com.company.MyEntryPoint/MyEntrypoint.html
I need users to authenticate using open id,
this is how i want my realm to be:
*.company.MyEntryPoint
I wrote a simple code to specify realm:
AuthRequest authReq =
manager.authenticate(
discovered,
returnToUrl,
"*.company.MyEntryPoint"
);
it does not work.
Exception:
org.openid4java.message.MessageException: 0x301: Realm verification failed (2) for: *.company.MyEntryPoint
at org.openid4java.message.AuthRequest.validate(AuthRequest.java:354)
at org.openid4java.message.AuthRequest.createAuthRequest(AuthRequest.java:101)
at org.openid4java.consumer.ConsumerManager.authenticate(ConsumerManager.java:1073)
Of all the combinations I tried, curiously, the following worked:
AuthRequest authReq =
manager.authenticate(
discovered,
returnToUrl,
"http://localhost:8888/com.capgent.MyEntryPoint"
);
This does not solves my issue but rather complicates it :)
According to google and open id spec it should have worked
complete code snippet:
List discoveries = manager.discover(clientUrl);
DiscoveryInformation discovered = manager.associate(discoveries);
AuthRequest authReq = manager.authenticate(discovered, returnToUrl,"*.company.MyEntryPoint");
FetchRequest fetch = FetchRequest.createFetchRequest();
fetch.addAttribute("email", "http://schema.openid.net/contact/email", true);
fetch.addAttribute("country", "http://axschema.org/contact/country/home", true);
fetch.addAttribute("firstname", "http://axschema.org/namePerson/first", true);
fetch.addAttribute("lastname", "http://axschema.org/namePerson/last", true);
fetch.addAttribute("language", "http://axschema.org/pref/language", true);
authReq.addExtension(fetch);
String returnStr;
if (!discovered.isVersion2())
{
returnStr = authReq.getDestinationUrl(true);
}
else
{
returnStr = authReq.getDestinationUrl(false);
}
What am I doing wrong over here ?
returnStr = authReq.getDestinationUrl(false); => returnStr = authReq.getDestinationUrl(true);