Consume REST POST web service does not work in iOS

221 views
Skip to first unread message

hebert....@gmail.com

unread,
Oct 29, 2015, 2:31:36 PM10/29/15
to CodenameOne Discussions
The full platform my issue applies to:
IDE: Eclipse
Android and windows Simulator ok
iOS does not works
Device: iPAD

I have a web service in Java running into Glassfish. 
When I try to consume  this WS in iOS it does not works and the method ConnectionRequest.readResponse(InputStream input) receives the input with no information.
If i try to convert it to byte[] it returns NULL.

Actually the service does not arrive in the WS. But it passes to the method ConnectionRequest.readResponse.

When a use the WS with the @GET annotation and consume with GET too it works.

Any tips to me?

Thanks in advanced

// WebService Java code:
===================================================================================

@Path("/apontamentoSrv")
@Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
@Stateless
public class ApontamentoResource {
@EJB
    private ApontamentoController aptBoletimController;
private ApontamentoController getAptBoletimController() {
return aptBoletimController;
}

@POST
@Path("/saveApontamento")
public Response saveApontamento( @FormParam("boletimJSON") String boletimJSON, @FormParam("talhaoJSON") String talhaoJSON, @FormParam("insumoJSON") String insumoJSON, @FormParam("recursoJSON") String recursoJSON, @FormParam("funcionarioJSON") String funcionarioJSON) {
String response = getAptBoletimController().saveApontamento(boletimJSON,talhaoJSON,insumoJSON,recursoJSON,funcionarioJSON);
return Response.status(Response.Status.OK).entity(ok).build();

}
}

/// CodenameOne code:
==============================================
protected Boolean consumePostWebService(String webService, String method, List<String> keys, List<String> 

values, Boolean isGet,AptBoletim aptBoletim, ConnectionRequest  connectionRequest) throws FailedReturnException {    
Boolean result = false;
if ( connectionRequest != null ) {

initWebServiceRequestByQueryParam(webService, method, keys, values, isGet, true, 

connectionRequest, false);
         NetworkManager.getInstance().addToQueueAndWait(getWebServiceRequest());
         Map<String, Object> response = getWebServiceRequest().getResults();
         
        if ( response == null ) {
       byte[] data = getWebServiceRequest().getResponseData();
 
   if (data == null) {
  throw new FailedReturnException();  
 } 
   
        } else {       
        result = processSendWSResponse(response, aptBoletim);
        }
   
        }
   return result;
}

private void initWebServiceRequestByQueryParam(String webService, String method, List<String> keys, 

List<String> values, Boolean isGet, Boolean isJson, ConnectionRequest webServiceRequest, Boolean 

showProgress) {    
String url = getURL(getUrlPattern(),webService,method);  
webServiceRequest.resetResults();
Log.p("URL => "+ url );
if ( webServiceRequest != null ) {    
String httpMethod = null;    

        webServiceRequest.setUrl(url);
      webServiceRequest.removeAllArguments();
        webServiceRequest.setPost(!isGet);
        webServiceRequest.setPriority(ConnectionRequest.PRIORITY_CRITICAL);
       
if ( isGet ) {
httpMethod = "GET";
webServiceRequest.setHttpMethod(httpMethod);
}
      
        if(isJson) {
        webServiceRequest.setContentType("application/json");
        webServiceRequest.addRequestHeader("Accept", "application/json");
        } else {
        webServiceRequest.setContentType("application/xml");
        webServiceRequest.addRequestHeader("Accept", "application/xml");
        }
       
    for(int iter = 0 ; iter <  keys.size(); iter++) {
          String p = keys.get(iter);
          String v = values.get(iter);
           webServiceRequest.addArgument(p, v);
        }
}
}

// ConnectionRequest code:
=====================================================
protected void readResponse(InputStream input) throws IOException {
    byte[] data = Util.readInputStream(input);
   if (data == null) {
    String msg = getSynchronizerController().getAppController().getKeyValue("msg.error.network.data.null");    
            throw new IOException(msg);
         }
    
    ByteArrayInputStream newInput = new ByteArrayInputStream(data);

if (isJson()) {
JSONParser jp = new JSONParser();
InputStreamReader reader = new InputStreamReader(newInput, "UTF-8");
Map<String, Object> response = jp.parseJSON(reader);
loadResults(response);
} else {
XMLParser xp = new XMLParser();
Element response = xp.parse(new InputStreamReader(newInput));
setRoot(response);
}
}


Steve CN1 Hannah

unread,
Oct 29, 2015, 2:44:10 PM10/29/15
to codenameone...@googlegroups.com
Does it work in the simulator?  If it works in the simulator, but not on iOS, then look at the following:

1. Is the URL accessible on the iOS device?  (e.g. if the glassfish server is running on localhost - same machine as the simulator, then it may work in simulator, but not on the device).
2. What version of iOS is the device running?  iOS9 has disabled access to non-secure URLs by default.

If it does not work in the simulator, then take a look in the network monitor to see exactly what request is being sent and what the response is from the server.  That may help you track it down.

Steve

--
You received this message because you are subscribed to the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to codenameone-discu...@googlegroups.com.
Visit this group at http://groups.google.com/group/codenameone-discussions.
To view this discussion on the web visit https://groups.google.com/d/msgid/codenameone-discussions/05cf0fc8-44f8-4b66-a853-7e044ef9cc3c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Steve Hannah
Software Developer
Codename One

hebert....@gmail.com

unread,
Oct 29, 2015, 2:52:50 PM10/29/15
to CodenameOne Discussions, hebert....@gmail.com
1. it works in the simulator and Android , but not on iOS:
2. The URL is accessible on the iOS device and  the glassfish server is running on remote server.
3. The version of iOS where the device is running is  iOS9 but other ss with GET is working, just when i use POST it does not work.

Steve CN1 Hannah

unread,
Oct 29, 2015, 3:05:26 PM10/29/15
to codenameone...@googlegroups.com, Hebert Luchetti
if you can post a test case that i can build and run to the issue tracker, I'll take a look.

--
You received this message because you are subscribed to the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to codenameone-discu...@googlegroups.com.
Visit this group at http://groups.google.com/group/codenameone-discussions.

For more options, visit https://groups.google.com/d/optout.

hebert....@gmail.com

unread,
Nov 5, 2015, 11:22:45 AM11/5/15
to CodenameOne Discussions, hebert....@gmail.com

Steve,
I think the problem is that iOS9 has disabled access to non-secure URLs by default.

But i have found a lot examples where the ios developers could enable this feature again programatically when you have to use REST POST without HTTPS.

You would implement this code when codename translate the java to object-C in ios.;

please see the links below maybe you can solve the problem because some web services that we need to use do not use https.

http://www.ekreative.com/blog/adapting-my-ionic-framework-hybrid-mobile-app-for-ios-9-problems-and-solutions/455-adapting-my-ionic-framework-hybrid-mobile-app-for-ios-9-problems-and-solutions

http://forum.ionicframework.com/t/solved-ios9-fails-with-setrequestheader-native-with-custom-headers-in-http-service/32399

http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

https://mobile.awsblog.com/post/Tx2QM69ZE6BGTYX/Preparing-Your-Apps-for-iOS-9

Thanks



On Thursday, October 29, 2015 at 4:31:36 PM UTC-2, hebert....@gmail.com wrote:

Steve CN1 Hannah

unread,
Nov 5, 2015, 12:43:58 PM11/5/15
to codenameone...@googlegroups.com, Hebert Luchetti
I think the best solution, right now is to use the ios.plistInject build hint to add the following:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
Keep in mind, that Apple warns not to use this unless you have a good reason.  Your app may be rejected.  If you can change the server to use secure URLs, or you only require this for a specific domain, you may want to use a more refined setting here.  See this comment:


Steve

--
You received this message because you are subscribed to the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to codenameone-discu...@googlegroups.com.
Visit this group at http://groups.google.com/group/codenameone-discussions.

For more options, visit https://groups.google.com/d/optout.

hebert....@gmail.com

unread,
Nov 5, 2015, 1:16:38 PM11/5/15
to CodenameOne Discussions, hebert....@gmail.com
Hi Steve,

Where can i change this code. I do not have a IOS environment . I use windows with eclipse. I do not have how compile the native code.



On Thursday, October 29, 2015 at 4:31:36 PM UTC-2, hebert....@gmail.com wrote:

Steve CN1 Hannah

unread,
Nov 5, 2015, 1:28:29 PM11/5/15
to codenameone...@googlegroups.com, Hebert Luchetti
Use the "ios.plistInject" build hint.

You can set build hints in the project properties.

Steve

--
You received this message because you are subscribed to the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to codenameone-discu...@googlegroups.com.
Visit this group at http://groups.google.com/group/codenameone-discussions.

For more options, visit https://groups.google.com/d/optout.

Hebert Luchetti

unread,
Nov 5, 2015, 1:43:09 PM11/5/15
to Steve CN1 Hannah, codenameone...@googlegroups.com
Thanks a lot Steve .

I will try this solution because i need a debug version right now. In the next version i will have time to implement the security connection.

Hebert Luchetti Ribeiro 
Desenvolvimento de Produtos 
T: +55 (16) 3623.5680 
E: 
hebert....@hexagonagriculture.com 
Hexagon Agriculture | iLab Solutions 
Av. Costábile Romano, 1747 
Ribeirão Preto, SP, 14096-380, Brazil 

hexagonagriculture.com | LinkedIn | Facebook | Twitter 

Reply all
Reply to author
Forward
0 new messages