WLPushOptions not being passed on WLPush subscribe - ibm-mobilefirst

I have a native app that is subscribing/unsubscribing and pushing notifications successfully, however, the API doesn't seem to pass in the WLPushOptions object that I'm using.
The call in my obj c code:
NSLog(#"Trying to subscribe ...");
id options = [WLPushOptions new];
[options addSubscriptionParameter:#"param3" :#"Testing3"];
NSLog(#"Connecting to server and initializing push notification … ");
ReadyToSubscribeListener *readyToSubscribeListener = [[ReadyToSubscribeListener alloc] initWithContext:ctx];
readyToSubscribeListener.alias = #"iOSPushAlias";
readyToSubscribeListener.adapterName = #"PushAdapter";
readyToSubscribeListener.eventSourceName = #"PushEventSource";
NSLog(#"Creating subscribe listener...");
MySubscribeListener *mySubscribeListener = [[MySubscribeListener alloc] initWithContext:ctx];
[[WLPush sharedInstance]subscribe:#"iOSPushAlias" :options :mySubscribeListener];
NSLog(#"Finished subscribe.");
The log:
Nov 4 20:29:44 Davids-iPhone-5 xxxx [771] <Warning>: Trying to subscribe ...
Nov 4 20:29:44 Davids-iPhone-5 xxxx [771] <Warning>: [WorklightNativeExtensionTemplateiOS] Connecting to server and initializing push notification ...
Nov 4 20:29:44 Davids-iPhone-5 xxxx [771] <Warning>: Creating subscribe listener...
Nov 4 20:29:44 Davids-iPhone-5 xxxx [771] <Warning>: Finished subscribe.
Nov 4 20:29:44 Davids-iPhone-5 xxxx [771] <Warning>: [INFO] Successfully subscribed to alias iOSPushAlias
Then, in the HSQL db log (using the local Worklight Developer client):
DELETE FROM NOTIFICATION_DEVICE WHERE ID=91
INSERT INTO NOTIFICATION_DEVICE VALUES(91,'iOSPushAlias','MYAPPNAME-iOSnative-1.0','XXXXXXXX-0C65-4BEF-BE3E-098B21BDFCEF','{}','Apple','XXXXXXXX324CA75650BB85853B946F3D1D9881E5D2E4F3E02268AA6CAA3254B3','XXXXXXXXXX-debug 1.2.0 (iPhone; iPhone OS 7.0.2; en_US)',91)
COMMIT
I've X'ed out the app and subscription id.
As you can see in the INSERT statement, the fifth field (the OPTIONS field in the NOTIFICATION_DEVICE table), is inserting an empty JSON object, where I passed in the key "param3" and value "Testing3", so, I would expect it to be:
{'param3':'Testing3'}
This seems to be what the the native iOS API docs expect (NSString parameters) to the addSubscriptionParameter method. I'm very new to Objective C, but, this looks correct to me.
Anyone know what I'm doing wrong?

This is a defect and has been logged. Fortunately there is an easy workaround:
WLPushOptions *options = [WLPushOptions new];
options.parameters = [NSMutableDictionary new];
[options addSubscriptionParameter:#"param3" :#"Testing3"];

Related

Changed predis to phpredis: Getting segmentation fault

(Code is locally tested on a mac)
I've created a simple test for Redis, but it, unfortunately, fails with [1] 27996 segmentation fault:
// Config in App.php
// Had to rename Redis, because of the use of phpredis!
'RedisManager' => Illuminate\Support\Facades\Redis::class,
//Test unit
use Illuminate\Support\Facades\Redis;
/** #test */
public function it_can_set_a_dummy_value_in_redis()
{
$value = 'Hello';
Redis::set($this->cacheKey, $value, 'EX', 60);
$this->assertEquals($value, Redis::get($this->cacheKey));
}
It fails when the command set is fired.
I went through the code up to the point: Illuminate\Redis\Connections\PhpRedisConnection.php#command
I checked what the object-value of $this->client is:
Redis {#2278
isConnected: true
host: "127.0.0.1"
port: 6379
auth: null
mode: ATOMIC
dbNum: 0
timeout: 0.0
lastError: null
persistentId: null
options: {
TCP_KEEPALIVE: 0
READ_TIMEOUT: 0.0
COMPRESSION: NONE
SERIALIZER: NONE
PREFIX: "local_database_"
SCAN: NORETRY
}
}
I check the connection with:
dd($this->client->ping()); // it's true
However, it fails at the point:
return parent::command($method, $parameters); //set is called
Even though it is in a try-catch-block, it won't be shown there...
The logs show nothing:
nginx: 0 errors
php-fpm: 0 errors
redis:
2867:M 29 Aug 2020 22:46:03.142 * Background saving started by pid 27498
27498:C 29 Aug 2020 22:46:03.145 * DB saved on disk
2867:M 29 Aug 2020 22:46:03.306 * Background saving terminated with success
So even Redis is working correctly.
I don't know what is going on. When I change to predis, everything works fine!
The only hint I have got is this thread. But since my ping() is ponged, it should work?
Any ideas how I can fix my problem?

Client cannot receive image data from gcdwebserver

I try to create a web server on iPhone to provide urls of images in ablum.
Before sending response to client, I need to do some adjustment on images (something like re-size).
These actions take up to 1 or 1.5 sec per image before response to client. (especially on iPhone 4)
The client side cannot receive data even though messages on xcode console already showed how many bytes has been GET on some sockets.
What options can I use to solve this problem?
Another question is what happens if I increase ConnectedStateCoalescingInterval value up to 2.0 or 3.0 seconds?
Thanks.
========= 2015/08/24 13:05 Updated
Here is my addHandlerForMethod:path:requestClass:asyncProcessBlock:
[_webServer addHandlerForMethod:#"GET" path:[NSString stringWithFormat:#"/image/%#",assetId] requestClass:[GCDWebServerRequest class] asyncProcessBlock:^(GCDWebServerRequest *request, GCDWebServerCompletionBlock completionBlock)
{
__strong typeof(weakself) strongself = weakself;
[strongself requestImageDataByAssetURL:assetURL completionCb:^(NSData *photoData) {
GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithData:photoData contentType:#"image/png"];
completionBlock(response);
}];
}];
Here is requestImageDataByAssetURL:completionCb:
- (void)requestImageDataByAssetURL:(NSURL *)assetURL completionCb:(void(^)(NSData *photoData))cbfunc {
__block NSData *photoData;
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
[library assetForURL:assetURL resultBlock:^(ALAsset *asset) {
#autoreleasepool {
uint64_t begin = mach_absolute_time();
// <do some image processing here>
uint64_t end = mach_absolute_time();
NSLog(#"Time taken to imageResize %g s", MachTimeToSecs(end - begin));
cbfunc(photoData);
}
} failureBlock:^(NSError *error) {
NSLog(#"[%#] fail. Error=%#", NSStringFromSelector(_cmd), error.localizedDescription);
cbfunc(nil);
}];
}
Here is the log:
[DEBUG] [2015-08-24 04:48:09 +0000] Did open connection on socket 32
[DEBUG] Connection received 221 bytes on socket 32
[DEBUG] Connection on socket 32 preflighting request "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" with 221 bytes body
[DEBUG] Connection on socket 32 processing request "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" with 221 bytes body
[DEBUG] [2015-08-24 04:48:10 +0000] Did open connection on socket 34
2015-08-24 12:48:10.799 xBoard[2981:3707] Time taken to imageResize 1.52039 s
[DEBUG] Connection received 221 bytes on socket 34
[DEBUG] Connection on socket 34 preflighting request "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" with 221 bytes body
[DEBUG] Connection on socket 34 processing request "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" with 221 bytes body
[DEBUG] Connection sent 171 bytes on socket 32
[DEBUG] Connection sent 123575 bytes on socket 32
[DEBUG] Did close connection on socket 32
[VERBOSE] [172.16.20.174:8080] 172.16.21.97:34450 200 "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" (221 | 123746)
2015-08-24 12:48:12.028 xBoard[2981:4f0b] Time taken to imageResize 1.06382 s
[DEBUG] Connection sent 171 bytes on socket 34
[DEBUG] Connection sent 123575 bytes on socket 34
[DEBUG] Did close connection on socket 34
[VERBOSE] [172.16.20.174:8080] 172.16.21.97:50852 200 "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" (221 | 123746)
We can see it creates the first socket(32).
Then creates the second socket(34) for the same image request immediately.
It seems that GCDWebServer close the first socket immediately. But why?
P.S. By the way, the client side use Android Volley library to download image instead of using web browsers.
There doesn't seem to be anything wrong according to the log: 2 GET requests for the path /image/9D959040-9FA8-4197-8150-8DC72339955D are processed on sockets 32 and 34, and each return 123,575 bytes.
Try using a desktop web browser like Chrome and its web inspector. If everything works correctly, then the problem is with your Android app.

Game Center Authentication with Swift

Using the following code, the GKLocalPlayer().authenticated variable is always false. Once the code runs to "User still not authenticated", you are able to download Game Center data. Is this a bug or an issue with the code below?
func notificationReceived()
{
println("GKPlayerAuthenticationDidChangeNotificationName - Authentication Status: \(self.localPlayer.authenticated)")
}
//MARK: 2 Authenticate the Player
func authenticateLocalPlayer()
{
println(__FUNCTION__)
self.delegate?.willSignIn()
self.localPlayer.authenticateHandler = {(viewController : UIViewController!, error : NSError!) -> Void in
if (viewController != nil)
{
dispatch_async(dispatch_get_main_queue(), {
self.showAuthenticationDialogueWhenReasonable(viewController)
})
}
else if (self.localPlayer.authenticated == true)
{
println("Player is Authenticated")
self.registerListener()
self.downloadCachedMatches()
self.delegate?.didSignIn()
}
else
{
println("User Still Not Authenticated")
self.delegate?.failedToSignIn()
}
if (error)
{
self.delegate?.failedToSignInWithError(error)
}
}
}
//MARK: 2a Show Authentication Dialogue
func showAuthenticationDialogueWhenReasonable(viewController:UIViewController!) -> Void
{
println(__FUNCTION__)
UIApplication.sharedApplication().keyWindow.rootViewController.presentViewController(viewController, animated: true, completion: nil)
}
The console output look like this:
init(notification:)
authenticationCheck()
authenticateLocalPlayer()
GKPlayerAuthenticationDidChangeNotificationName - Authentication Status: false
GKPlayerAuthenticationDidChangeNotificationName - Authentication Status: false
showAuthenticationDialogueWhenReasonable
GKPlayerAuthenticationDidChangeNotificationName - Authentication Status: false
GKPlayerAuthenticationDidChangeNotificationName - Authentication Status: false
GKPlayerAuthenticationDidChangeNotificationName - Authentication Status: false
User Still Not Authenticated
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.149128 com.apple.viceroytrace: ENV: VRTraceLogToFile="-"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.149544 com.apple.viceroytrace: ENV: VRTraceErrorLogLevel="ALL"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.149997 com.apple.viceroytrace: ENV: VRTraceMonitorNSLog="1"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.150429 com.apple.viceroytrace: ENV: VRTraceStreamOutputFormat="CSV"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.150875 com.apple.viceroytrace: ENV: VRTraceLogToFile="-"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.151312 com.apple.viceroytrace: ENV: VRTraceErrorLogLevel="ALL"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.151768 com.apple.viceroytrace: ENV: VRTraceMonitorNSLog="1"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.152211 com.apple.viceroytrace: ENV: VRTraceStreamOutputFormat="CSV"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.152626 com.apple.viceroytrace: ENV: VRTraceLogToFile="-"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.153060 com.apple.viceroytrace: ENV: VRTraceErrorLogLevel="ALL"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.153489 com.apple.viceroytrace: ENV: VRTraceMonitorNSLog="1"
Aug 2 07:33:10 iMac.local <Debug>: 07:33:10.153925 com.apple.viceroytrace: ENV: VRTraceStreamOutputFormat="CSV"
Aug 2 07:33:10 iMac.local <Info>: 07:33:10.154140 com.apple.viceroytrace: [CHECKPOINT] logging-started
Aug 2 07:33:10 iMac.local <Notice>: 07:33:10.154146 com.apple.viceroytrace: gVRTraceErrorLogLevel initialized to ALL (9)
Aug 2 07:33:10 iMac.local <Info>: 07:33:10.144097 com.apple.AVConference: GKSConnSettings: set server: {
"gk-cdx" = "17.173.254.218:4398";
"gk-commnat-cohort" = "17.173.254.220:16386";
"gk-commnat-main0" = "17.173.254.219:16384";
"gk-commnat-main1" = "17.173.254.219:16385";
}
if you are attempting to translate the Objective-C code in the Game Center Programming Guide re: "Authenticating a Local Player" ->
(https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/Users/Users.html#//apple_ref/doc/uid/TP40008304-CH8-SW18)
...then you're not quite following the pattern correctly
where you are using:
if (viewController) {
...
} else {
if (localPlayer.authenticated) {
...
} else {
...
}
}
...their pattern uses:
if (viewController) {
...
} else if (localPlayer.authenticated) {
...
} else {
...
}
try re-writing your code using their pattern - an important item to note is where they write:
Game Kit automatically authenticates the player asynchronously, calling your authentication handler as necessary to complete the process.
...they don't specifically say when or how many times they attempt to authenticate - and it's all happening asynchronously anyways, I can totally imagine that it may be the case that your code, in its current form, may print to the console "User Still Not Authenticated", but that by the time some other part of your app checks they may have authenticated and be able to download Game Center data.
One more note: it may also be possible that you are seeing a situation where there is cached Game Center data... note that in the final else of the example's conditional branching (if...else if... else), they disable Game Center altogether
let me know how this turns out! I'd be interested in knowing
You can use that, I create a simple class for iOS game center in GitHub
https://github.com/DaRkD0G/Easy-Game-Center-Swift
Begin
import GameKit
/// The local player object.
let gameCenterPlayer = GKLocalPlayer.localPlayer()
After in your func
self.gameCenterPlayer.authenticateHandler={(var gameCenterVC:UIViewController!, var gameCenterError:NSError!) -> Void in
if gameCenterVC != nil {
self.presentViewController(gameCenterVC, animated: true, completion: { () -> Void in
// no idea
})
}
}
I've been struggling with the same issue. I have the same authenticate construction. I think Apple has changed their login routine: if you become no error and no LoginViewController it means that you have successfully logged in. Since they deleted GKLocalPlayer.localPlayer attribute it could be the solution. There is one thing though - they didn't delete the GKLocalPlayer.authenticated flag and this leaves the issue unresolved.
EDIT: My assumption about changing the authentication-routine was false: https://developer.apple.com/library/prerelease/iOS/documentation/GameKit/Reference/GKLocalPlayer_Ref/index.html#//apple_ref/occ/instp/GKLocalPlayer/authenticateHandler
they actually use this flag to confirm the authentication. The problem remains unresolved.
This has been fixed in Xcode 6 Beta 6 – there's now GKLocalPlayer.localPlayer() class func which does the business.
As of Xcode6 GM authenticated is still false.
I recently faced that issue and I solved it by enabling Sandbox mode on from setting -> Game Center -> Developer -> Sandbox.
Hope it will help someone.

invokeSelector:withObject: crashes in Release

I have code
[target invokeSelector:handler.successAction withObject:object];
It may call some methods. With object or without. It perfectly works in Debug, but crashes in Release:
Nov 20 21:55:13 efpies project[7202] <Warning>: >>>> selector: successfulLogin
Nov 20 21:55:13 efpies project[7202] <Warning>: >>>> target: <AppDelegate: 0x1f595a90>
Nov 20 21:55:13 efpies project[7202] <Warning>: >>>> object: <7b226d65 73736167 65223a22 5c753034 31325c75 30343435 5c753034 33655c75 30343334 205c7530 3434305c 75303433 305c7530 3433375c 75303434 305c7530 3433355c 75303434 385c7530 3433355c 75303433 64227d> NSConcreteMutableData
Nov 20 21:55:13 efpies project[7202] <Error>: -[AppDelegate invokeSelector:withObject:]: unrecognized selector sent to instance 0x1f595a90
Nov 20 21:56:12 efpies project[7205] <Warning>: >>>> selector: driversUpdated:
Nov 20 21:56:12 efpies project[7205] <Warning>: >>>> target: <DriversList: 0x1cd5ffd0>
Nov 20 21:56:12 efpies project[7205] <Warning>: >>>> object: (
) __NSArrayM
Nov 20 21:56:12 efpies project[7205] <Error>: -[DriversList invokeSelector:withObject:]: unrecognized selector sent to instance 0x1cd5ffd0
Those methods are available (and even presented in header file). What's wrong? The data and objects are 100% correct
Use
[target performSelector:handler.successAction withObject:object];
That is the way to do this in cocoa-touch since NSObject will handle this for you.
Check Apple documentation for more details.
As it turned out, invokeSelector:withObject: is a category method in the static library. Categories from a static library don't load automatically so you should write
-force_load $(BUILD_ROOT)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/lib_name.a
to the Other linker flag field in target's Build settings if it compiles as dependency for the target.

Releasing allocations in response to low memory warning, but app still crashes

I'm building an app for viewing photos I pull down from an API. Each photo is ~1MB in size. I've set up a "slideshow" to show a photo, then move onto the next one, like a user would actually use the app. I'm testing on an iPad 1 in Instruments.
When my app receives a low memory warning, I'm dumping all photos that are currently not being displayed to the user, as well as all cached model data returned from the API. I'm seeing a significant drop in my allocations in Instruments, and a similar drop in the virtual memory use. Even with this drop in consumed memory, my app is still being killed by the OS.
The application responds to 2-3 memory warnings without crashing before being terminated.
I've recently switched to ARC, so maybe there's something I'm not understanding? I assume setting my references to nil is sufficient. Here's my code for the in-memory models dumping their image data:
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
NSLog(#"Received memory warning; clear image for photo named \"%#\"", _name);
_image = nil;
_imageThumbnail = nil;
}];
Which is getting called. I also have an NSMutableDictionary which I'm calling removeAllObjects on when I received the low memory warning. I'm getting the following in the device console:
Oct 5 19:43:46 unknown configd[25] <Notice>: jetsam: kernel termination snapshot being created
Oct 5 19:43:46 unknown com.apple.launchd[1] <Notice>: (com.apple.accessoryd) Exited: Killed: 9
Oct 5 19:43:46 unknown com.apple.launchd[1] <Notice>: (com.apple.locationd) Exited: Killed: 9
Oct 5 19:43:46 unknown com.apple.launchd[1] <Notice>: (com.apple.mediaserverd) Exited: Killed: 9
Oct 5 19:43:46 unknown com.apple.launchd[1] <Notice>: (UIKitApplication:com.500px[0xd492]) Exited: Killed: 9
Oct 5 19:43:47 unknown kernel[0] <Debug>: launchd[1996] Builtin profile: accessoryd (sandbox)
Oct 5 19:43:47 unknown ReportCrash[1999] <Error>: libMobileGestalt loadBasebandMobileEquipmentInfo: CommCenter error: 1:45
Oct 5 19:43:47 unknown ReportCrash[1999] <Error>: libMobileGestalt copyInternationalMobileEquipmentIdentity: Could not get mobile equipment info dictionary
Oct 5 19:43:47 unknown ReportCrash[1999] <Error>: Saved crashreport to /Library/Logs/CrashReporter/LowMemory-2011-10-05-194347.plist using uid: 0 gid: 0, synthetic_euid: 0 egid: 0
Oct 5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : <NSThread: 0x1cd31410>{name = (null), num = 1}
Oct 5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : {
OSMemoryNotificationLevel = 0;
timestamp = "2011-10-05 23:43:47 +0000";
}
Oct 5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : <NSThread: 0x1cd31410>{name = (null), num = 1}
Oct 5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : {
OSMemoryNotificationLevel = 0;
timestamp = "2011-10-05 23:43:47 +0000";
}
Oct 5 19:43:48 unknown com.apple.locationd[1997] <Notice>: locationd was started after an unclean shutdown
Oct 5 19:43:49 unknown SpringBoard[29] <Warning>: Application '500px' exited abnormally with signal 9: Killed: 9
Does anyone have any idea why my app is being killed even though it's freeing memory?
_image = nil;
_imageThumbnail = nil;
This is just setting the pointers to nil, not releasing the actual objects. Release the objects, then they'll get deallocated (if their retain count hits 0).
Since you're using ARC, just set the properties to nil.
Turns out I was hanging onto references to the model classes somewhere else - they weren't getting dealloc'd, even if they released their image data during memory warnings. Eventually there were too many of them and the app crashed.