Push notifications not working in the production environment - iphone

When I run my app in development mode, I can get the push notifications I send to myself through PushMeBaby without a problem. However, when I try to test it in the production environment, I can not get any push notifications. I re-generated all the certificates and provisioning profiles, used the aps_production_identity.cer as the certificate for push notifications, changed the SSL to gateway.push.apple.com, and did a release build for the app, but still couldn't get it to work. I found that in PushMeBaby, the line
result = SSLHandshake(context);
Returns error -9844. Does this mean that something is wrong with the aps_production_identity.cer file?

Yes, I've solved this error. I lost a few days finding the solution. The problem is in the line:
result = SSLSetPeerDomainName(context, "gateway.sandbox.push.apple.com", 30);
NSLog(#"SSLSetPeerDomainName(): %d", result);
You have to change the port to number 30. This solves the problem.

I think it is better to not hardcode numbers like this in code, even if it is sample code. I thought that the 30 was a port number (shame on me for not doing more code evaluation).
I changed that line to something like this:
#define kApplePushGateway "gateway.push.apple.com" //"gateway.sandbox.push.apple.com"
result = SSLSetPeerDomainName(context, kApplePushGateway, [[NSString stringWithUTF8String:kApplePushGateway] length]);
NSLog(#"SSLSetPeerDomainName(): %d", result);

Related

IOCreatePlugInInterfaceForService returns mysterious error

I am trying to use some old IOKit functionality in a new Swift 4.0 Mac app (not iOS). I have created a bridging header to use an existing Objective C third party framework, DDHidLib, and I am current working in Xcode 9.
The code that attempts to create a plug in interface for a usb gamepad falls over on IOCreatePlugInInterfaceForService, returning a non-zero error.
The truly bizarre thing is I have an older app created in a previous version of Xcode that uses the same framework and works correctly after opening in the new Xcode 9. This previous project is still Swift using a bridging header for the same Obj-C framework. I have checked the build settings and tried to make everything match, but I get the same result; the old app works but any new apps do not.
Is there a way to either: find out the exact differences in build settings/compilers to see what the elusive difference may be, OR to step into the IOCreatePlugInInterfaceForService IOKit method to see what may be causing the error to be returned in one project but not another?
EDIT: Here is the method that is failing:
- (BOOL) createDeviceInterfaceWithError: (NSError **) error_; {
io_name_t className;
IOCFPlugInInterface ** plugInInterface = NULL;
SInt32 score = 0;
NSError * error = nil;
BOOL result = NO;
mDeviceInterface = NULL;
NSXReturnError(IOObjectGetClass(mHidDevice, className));
if (error)
goto done;
NSXReturnError(IOCreatePlugInInterfaceForService(mHidDevice, kIOHIDDeviceUserClientTypeID,kIOCFPlugInInterfaceID,&plugInInterface,&score));
if (error)
goto done;
//Call a method of the intermediate plug-in to create the device interface
NSXReturnError((*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID) &mDeviceInterface));
if (error)
goto done;
result = YES;
done:
if (plugInInterface != NULL)
{
(*plugInInterface)->Release(plugInInterface);
}
if (error_)
*error_ = error;
return result;
}
In the old version that works, IOCreatePlugInInterfaceForService always returns a value of 0. In all the versions that don't work, the return value appears to always be -536870210. The mHidDevice in this function is the io_object_t handle for the device.
EDIT2: Here is the IORegistryExplorer page for the device
Finally managed to resolve this after weeks of head scratching. The new Xcode 9 uses app sandboxing to basically prevent access to USB, bluetooth, camera and microphone etc. by default in a new app. Once I switched this off it reverted to it's expected behaviour.
Glad it was such a simple answer in the end but disappointed Xcode does not provide more descriptive error messages or responses to let a user know they are essentially preventing themselves from accessing the parts of the system they need.
Looks like kIOReturnNoResources is returned if the loop at the end of IOCreatePlugInInterfaceForService completes with haveOne == false for whatever reason. Perhaps Start() is returning false because another process or driver already has exclusive access? I'd check what clients the device has in IORegistryExplorer.
This error also happens when an application is trying to access the camera or bluetooth on MacOS 10.14 and higher. Permission shall be granted either explicitly by user (pop-up window), or through the Security & Privacy. The application should check for permission as shown here.

Checking private network for local devices with a certain port open (iPhone/Objective C)

I've spent the whole day creating a system between my Mac and iPhone where i have used cocoaasyncsocket to create a listen server on my mac and a client on my iPhone. The basic idea is to leave the app on the mac running while the computer is on and then when I wish to transfer data from the iPhone app, fire up the app an it connects and sends the data... I have this system working exactly how I want it to function however I have 1 issue what I have been trying to solve for about 4 hours in total!
I wanted to create something what scans my wireless network for my mac with the listener running... I thought this would be simple, but I was wrong. I have searched high and low with no luck on the case and I am using stackoverflow as my last resort.
My current plan was to "autoscan" by retrieving the internal IP of the iPhone (ie 192.168.1.94) then use that to figure out what the other IP's on the network will be (192.168.1.0-254), now I know what IP's to scan i can loop through each one and check to see if the port is open/I get a response.
Now I want to do this as quick as possible however I haven't been able to get ANYTHING to give me accurate results...
Using connectToAddress:error: in the cocoaasyncsocket will simply just return true for every one of the 255 different IP addresses, so will any other reachability functions that I have come across... I have read that it is because they only check to see if the connection gets made and don't care about what happens at the other end so I need to think of something else.
My only other solution that I can think of, is to maybe ping each internal IP and see if i get a response but im not sure if this is going to take up too much time having to go through 255 IP addresses... and then, once i get what IP's are active I still then have to check to see if the port is open somehow :/
If anyone here knows how it can be done or has any better idea how I can check for the open port (i'm not very good with networking) I would be VERY grateful.
Thanks for reading,
Liam
Ok, I had a pay around today and I managed to get it working using Bonjour!
As it took me time to figure it all out I thought I will help anyone else out...
First off, on the listener side we need to set up a NSNetService, this can be done like so:
listenService = [[NSNetService alloc] initWithDomain:#"" type:#"_appname._tcp" name:#"Display Name" port:2427];
[listenService setDelegate:self]; //make sure you include the NSNetServiceDelegate
[listenService publish];
You can then plug into the NSNetServiceDelegate to make sure the service was published successfully and I used Bonjour Browser to check that my service was running fine (and it was)...
Then on the client we need to search for the service using [NSNetServiceBrowser][3]... This can be done like so:
serviceBrowser = [[NSNetServiceBrowser alloc] init];
[serviceBrowser setDelegate:self]; //remember to include NSNetServiceBrowserDelegate
[serviceBrowser searchForServicesOfType:#"_appname._tcp" inDomain:#""];
If you then include the NSNetServiceBrowserDelegate methods you can listen in to
netServiceBrowser:didFindService:moreComing:
You must then retain the service, give it a delegate and then resolve the service... Then if you listen into the NSNetServiceDeligate for the netServiceDidResolveAddress: you can then run the following code to convert the sockaddr into a readable IP address:
#include <arpa/inet.h>
-(void)netServiceDidResolveAddress:(NSNetService *)sender {
for (NSData* data in [sender addresses]) {
char addressBuffer[100];
struct sockaddr_in* socketAddress = (struct sockaddr_in*) [data bytes];
int sockFamily = socketAddress->sin_family;
if (sockFamily == AF_INET ) {//|| sockFamily == AF_INET6) { /*only support ipv4 atm*/
const char* addressStr = inet_ntop(sockFamily,
&(socketAddress->sin_addr), addressBuffer,
sizeof(addressBuffer));
int port = ntohs(socketAddress->sin_port);
if (addressStr && port) {
//you now have the services IP and Port.. all done
}
}
}
[sender release];}
Hope this helps anyone who is stuck with this.. Note that I borrowed parts of other samples/ instructions into one complete post what explains the whole system.
Enjoy.
I haven't worked with it myself but basically Bonjour is actually what you are looking for it's purpose is publishing and discovery of services

Recent gyroscope support from Corona SDK seems to be non-responsive

I'm using a recent daily build of the Corona SDK (version 2001.562) to add gyroscope support to an existing application. Unfortunately, I can't seem to get the event-handling function for the gyroscope to fire. The application is running on an iPod touch, version 4.3.3.
I attach the gyroscope to an event handler like so:
if system.hasEventSource("gyroscope") then
feedbackFile = io.open(system.pathForFile("log.txt", system.DocumentsDirectory), "a");
feedbackFile:write((os.clock()-startupTime).."\tgyroscope on\n");
io.close(feedbackFile);
Runtime:addEventListener( "gyroscope", onGyroscopeDataReceived )
else
feedbackFile = io.open(system.pathForFile("log.txt", system.DocumentsDirectory), "a");
feedbackFile:write((os.clock()-startupTime).."\tgyroscope off\n");
io.close(feedbackFile);
end
When I launch the application on the device, then close it and download the resource files, I find that log.txt contains the line with a timestamp and "gyroscope on". Good so far!
On to the event-handling function:
local function onGyroscopeDataReceived(event)
feedbackFile = io.open(system.pathForFile("log.txt", system.DocumentsDirectory), "a");
feedbackFile:write((os.clock()-startupTime).."\tgyroscope reading delta="..event.deltaRotation..",x="..event.xRotation..",y="..event.yRotation..",z="..event.zRotation.."\n");
io.close(feedbackFile);
end
This line of information never appears in the log.txt file!
Please advise. Thanks in advance!
The problem is event.deltaRotation doesn't exist. You might mean event.deltaTime.
Then when you concatenate a nil value, Lua throws an error and your write code never gets completed. (The latest daily build will now print out a message when you encounter a Lua error on a device.)
The documentation shows how to compute your own deltaDegrees or deltaRadians:
http://developer.anscamobile.com/reference/index/events/gyroscope/eventxrotation
Just a wild guess but it may be your listener is never called --- I noticed your onGyroscopeDataReceived function is local. If that's the case, then you need to make sure the variable is declared prior to the addEventListener call.

ProductName length cause connection problem

It seems incredible but if I put a productName (not BundleNamethat appears in home screen) longer than 10 chars my app works well except from I'm not able to get response of my connection requets.
I mean...for example if I put APPNAME123 in productName I obtain APPNAME123.app and all works fine.
If i put APPNAME1234 in productName I obtain APPNAME1234.app and app works except for connections methods...for example if I call www.mydomain.com/example.asp I got no errors, but zero bytes as response!!!!
I use
NSURLRequest *request=[NSURLRequest requestWithURL:MYURL];
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
and result is not nil but with zero length while error is nil
Of course I tried in various way (both on simulator and device), cleaning and rebuilding project avery time, and of course I tried with other names...same results..if longer than 10 chars I got same problems!
I've also created a new project with desired name longer than 10 chars and I got the same problem.
That made me crazy for a whole day...because I didn't find a specification for this and the rest of app wiorking good!!!
I'd like to know:
1) if anyone else notice this or itis just my problem, maybe some dirty on my mac
2) if there some documentation about this everywhere
thanks in advance for your answers
that doesn't sound like your problem, sounds totally unrelated, perhaps remove products from simulator and do a clean and build. My guess is that you have 2 copies, one working and one broken on the simulator, and it is launching the wrong one.
Sounds more like a memory issue. What's about response, do you read it immediately? What if appname has a length of 12, 13, ... characters, any change than? Have you tried to have a look into memory browser before/after calling sendSyncRequest?

the svnpoller is not triggered (warning in the twistd.log)

I am not sure what is going on, but i get this weird issue with buildbot.
The SVNPoller is configured as it should (checked various config example files), when i run the buildbot checkconfig it says that everything is fine....but it won't work at all.
If i trigger a build via the scheduler class it works fine, i can retrieve the source updates and build without problems (tried with a 1h timeframe).
The problem thou is that the poller is not working, so even if i build each hour, the changes column stays empty (i get the changes for the various versions thou, so if i click on the build detail i can see the sourcestamp carrying the right and most recent revision everytime that i modify the codebase); so I have no way to know if the build fails who did the last change.
Another peculiar thing is that in the twistd.log i see this line:
Warning: no ChangeSources specified in c['change_source']
And i am not sure why it wouldn't work since the checkconfig does not raise any error.
The result of this is of course that the only thing built is the hourly one, leaving me without the poller, and without knowing who is putting code in each build.
This is the code for the poller:
c['change source']=SVNPoller
(svnurl="svn+ssh://user#svnserver.domain.com/svn/project/trunk,
pollinterval=60*5,
histmax=10,
project=myproj,
svnbin = '/usr/bin/svn')
So far it looks good, so I am not really sure what is wrong here...why the SVNPoller is not triggering any build.
Anyone that has some suggestions about why is this happening ? Is there any other way to get changes from an SVN server? I am a total newbie at BuildBot and I am not really getting too much out of the manual; that looks much more like a scholastic book instead of being a manual that shows you how you do stuff :)
Thanks!!!!!
Ok, silly me :) the problem is the missing underscore on change_source...once added it the problem is solved
c['change_source'] = SVNPoller (svnurl=source_svn_url,
pollinterval=60,
histmax=10,
project='The_project',
svnbin= '/usr/bin/svn'
)
this will poll the svn codebase at source_svn_url (just put your svn:// path); and will check every minute to see if anyone has done changes; and will keep 10 changes in the record list (any change after the 10th will not show up so use it carefully if you do a lot of commits).
Hope that this helps who uses buildbot!