boltsframework / bolts-objc Goto Github PK
View Code? Open in Web Editor NEWBolts is a collection of low-level libraries designed to make developing mobile apps easier.
License: Other
Bolts is a collection of low-level libraries designed to make developing mobile apps easier.
License: Other
Hello,
I am trying to implement the following logic:
However I get the exception:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot set the result on a completed task.'
The exception rises in this line: tempPost.timeSincePosted = self.getTimeSincePostedfromDate(post.createdAt!)
What does the setResult in the (self.getTimeSincePostedfromDate(post.createdAt!))
has to do with the main task?
func loadFeedPosts() -> BFTask {
let mainTask = BFTaskCompletionSource()
let user = PFUser.currentUser()!
let relation = user.relationForKey("feed")
let query = relation.query()
query?.addDescendingOrder("createdAt")
query?.findObjectsInBackground().continueWithBlock({ (task: BFTask!) -> AnyObject! in
var tasks = [BFTask]()
if task.error == nil, let result = task.result {
let posts = result as! [PFObject]
for post in posts {
var tempPost = Post()
tempPost.userName = (post["createdBy"] as! PFUser).username
tempPost.timeSincePosted = self.getTimeSincePostedfromDate(post.createdAt!)
tempPost.profileImageURL = (post["createdBy"] as! PFUser)["smallProfileImage"] as? String
tasks.append(self.getMovieInfoByITunesID(post["trackID"] as! Int))
}
}
return BFTask(forCompletionOfAllTasksWithResults: tasks)
}).continueWithBlock({ (task: BFTask!) -> AnyObject! in
for var i = 0; i < Post.sharedInstance.feedPosts.count; ++i {
Post.sharedInstance.feedPosts[i].bigPosterImageURL = self.getBigPosterImageURL((task.result as! JSON)[i]["artworkUrl100"].stringValue)
}
mainTask.setResult(nil)
return nil
})
return mainTask.task
}
func getMovieInfoByITunesID(iTunesID: Int) -> BFTask {
let task = BFTaskCompletionSource()
ITunesApi.lookup(iTunesID).request({ (responseString: String?, error: NSError?) -> Void in
if
// error == nil,
let responseString = responseString, let dataFromString = responseString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
let json = JSON(data: dataFromString)
task.setResult(json["results"].arrayObject!)
} else {
// process error
}
})
return task.task
}
Hi Guys
I have a question "how to stop the BFTask chain, break from the chain execution"
See Commnets
BFTask *task = [_model getX1Task]; [[task continueWithBlock:^id(BFTask *task) { if (task.error || task.exception || task.isCancelled) { return nil; } else { NSDictionary *dic = (NSDictionary *)task.result; if ([dic isKindOfClass:[NSDictionary class]]) { if ([self checkX1OK]) { return [_model getX2Task]; } else { //here I want break //so i return nil, but I found the continueWithBlock will still return a new task have a nil result, so the chain automaticall go to below return nil } } } }] continueWithBlock:^id(BFTask *task) { //but the code come here, even the before task is return nil if (task.error || task.exception || task.isCancelled) { return nil; } else { if ([self checkX2OK]) { return [_model getX3Task]; } else { //here want break //so i return nil return nil } } }] ;
I found why the nil case return default task in BFTask's method
continueWithExecutor:withBlock:
- (BFTask *)continueWithExecutor:(BFExecutor *)executor withBlock:(BFContinuationBlock)block { BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource]; ............................ //because the result is nil, so it's not a BFTask class if ([result isKindOfClass:[BFTask class]]) { [(BFTask *)result continueWithBlock:^id(BFTask *task) { ........... return nil; }]; } else { tcs.result = result; //so nil result will go here } }]; }; ...... return tcs.task; //so even a nil result will return a default task which is create by BFTaskCompletionSource }
I have thought a way like this to add one stop:BOOL in the block
typedef id(^BFContinuationWithStopBlock)(BFTask *task, BOOL *stop);
so I can mark &stop = YES
, when I want to stop the execution, what are your opinions?
When you use "waitUntilFinished" at the end of a task, the parse completion block for a somethingInBackground is never called. It works with a dispatch semaphore.
The reason why may be that parse block callbacks always occur on the main thread.
Example:
-(BFTask *)createCorporation {
NSLog(@"Creating corporation.");
BFTaskCompletionSource *task = [BFTaskCompletionSource taskCompletionSource];
PFObject *corporation = [PFObject objectWithClassName:@"AcctCorporation"];
[corporation setObject:[_locationInfo objectForKey:@"locationName"] forKey:@"name"];
[corporation setObject:[_locationInfo objectForKey:@"postalCode"] forKey:@"postal"];
[corporation setObject:[_locationInfo objectForKey:@"country"] forKey:@"country"];
[corporation setObject:[_locationInfo objectForKey:@"state"] forKey:@"state"];
[corporation setObject:[_locationInfo objectForKey:@"address"] forKey:@"address"];
[corporation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
NSLog(@"HERE!"); // Never gets called
if(!error) {
[task setResult: corporation];
} else {
[task setError: error];
}
}];
return task.task;
}
Test:
- (void) testCreateCorporation {
NSDictionary *userProfile = [NSDictionary dictionaryWithObjectsAndKeys:@"[email protected]", @"email", @"jimbo2s223s4", @"username", @"Jim", @"firstName", @"O'Brien", @"lastName", @"1234", @"pin", @"888xxxx8", @"password", @"619-xxxxxxx", @"cell", nil];
NSDictionary *locationInfo = @{
@"locationName": @"Joe's Garage",
@"address": @"111 Frank Zappa Street",
@"mainPhone": @"619-xxx-xxxx",
@"postalCode": @"91910",
@"city": @"Palmdale",
@"state": @"California",
@"country": @"USA",
@"position": @"Head Chief and Cook"
};
__block PFObject *corporation = nil;
TAPParseSignup *signup = [[TAPParseSignup alloc] initWithLocationInfo:locationInfo andUserProfile:userProfile];
[[[signup createCorporation] continueWithBlock:^id(BFTask *task) {
STAssertNil(task.error, @"Error should be nil");
corporation = [task result];
return nil;
}] waitUntilFinished];
STAssertNotNil(corporation, @"Corp should not be nil.");
STAssertNotNil([corporation objectId], @"Object id should not be nil");
}
With semaphore working:
- (void) testCreateCorporation {
NSDictionary *userProfile = [NSDictionary dictionaryWithObjectsAndKeys:@"[email protected]", @"email", @"jimbo2s223s4", @"username", @"Jim", @"firstName", @"O'Brien", @"lastName", @"1234", @"pin", @"8888", @"password", @"619-xxxxxxxx", @"cell", nil];
NSDictionary *locationInfo = @{
@"locationName": @"Joe's Garage",
@"address": @"111 Frank Zappa Street",
@"mainPhone": @"619-xxx-xxxx",
@"postalCode": @"91910",
@"city": @"Palmdale",
@"state": @"California",
@"country": @"USA",
@"position": @"Head Chief and Cook"
};
__block PFObject *corporation = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
TAPParseSignup *signup = [[TAPParseSignup alloc] initWithLocationInfo:locationInfo andUserProfile:userProfile];
[[signup createCorporation] continueWithBlock:^id(BFTask *task) {
STAssertNil(task.error, @"Error should be nil");
dispatch_semaphore_signal(semaphore);
corporation = [task result];
return nil;
}];
while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW)) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:20]];
}
STAssertNotNil(corporation, @"Corp should not be nil.");
STAssertNotNil([corporation objectId], @"Object id should not be nil");
}
We are trying to re-throw exceptions as follows. But this way is not only ugly but also takes care of only the last continueWithBlock:
.
What would you guys suggest on this?
[[task continueWithBlock:^id(BFTask *task) {
//throws an exception
return nil;
}] continueWithBlock:^id(BFTask *task) {
dispatch_async(dispatch_get_main_queue(), ^{
if (task.exception) {
@throw task.exception;
}
});
return nil;
}];
I am using this code to navigate to another native app with the registered URL scheme 'receiver'
NSURL *url = [NSURL URLWithString:@"receiver://"];
[[BFAppLinkNavigation resolveAppLinkInBackground:url] continueWithSuccessBlock:^id(BFTask *task) {
BFAppLink *link = task.result;
NSLog(@"resolved link %@", link);
BFAppLinkNavigation *navigation = [BFAppLinkNavigation navigationWithAppLink:link
extras:@{ @"access_token": @"t0kEn" }
appLinkData:@{ @"referer_app_link": @{
@"url": @"playlist://",
@"app_name": @"Playlist" }}];
NSError *error = nil;
[navigation navigate:&error];
return nil;
}];
I can make this work with an http:// url like http://spotify.com, but I can't get it to work with a custom URL scheme like receiver://
However, I can open the receiver app using standard method openURL:@"receiver://"
But it's necessary for me to use the BFAppLinkNavigation methods because I need to send the appropriate metadata to let the receiver app generate the proper back button back to the first app. Any ideas why this isn't working?
Please help me, Facebook says: "The Bolts Framework , which is included in Facebook SDK, provides easy to use APIs to help you to parse the incoming URL." Thank you!
Ourapp's url: https://itunes.apple.com/hu/app/iptvhungary/id999802622?mt=8
In Readme.md, the following function generates the error: Cannot invoke 'fetchInBackgroundWithBlock' with an argument list of type '((PFObject!, NSError!) -> Void)'.
func fetchAsync(object: PFObject) -> BFTask {
var task = BFTaskCompletionSource()
object.fetchInBackgroundWithBlock {
(object: PFObject!, error: NSError!) -> Void in
if error == nil {
task.setResult(object)
} else {
task.setError(error)
}
}
return task.task
}
I looked through issues and documentation and I have no idea how to cancel network task that I do not need anymore.
When using:
BFURL *parsedUrl = [BFURL URLWithInboundURL:url sourceApplication:sourceApplication];
on url that contain non-breaking space - '%A0' the BFURL doesn't parse all the parameters correctly. So I have to manually change them like so:
NSString *newUrlString = [urlString stringByReplacingOccurrencesOfString:@"%A0" withString:@"%20"];
Similar issue: #38
The method [BFAppLinkNavigation navigateToURLInBackground:url]
does not support custom URL Schemes. I personally feel like it should! It supports almost all other forms of opening URL's. The only way to actually navigate to links with custom URL schemes is to implement continueWithBlock:^id(BFTask *task)
. Is there a specific reason that custom URL schemes are not supported?
When using Bolts in an app extension development. Some Blots classes have references to [UIApplication sharedApplication]
which is not available in an app extension target.
Need a way to avoid the unavailable API usage when linking against app extension targets. Maybe a macro for conditional compile?
The 1.1.0 podspec is referencing the tag v1.1.0, which doesn't exist (see https://github.com/CocoaPods/Specs/blob/master/Specs/Bolts/1.1.0/Bolts.podspec.json)
Could you add the tag or update the podspec ?
Tank you
I have a scenario where I have many, many network requests to make. I would like to provide a BFTask for the completion of all of them.
I want to be able to cancel them if necessary. Also, if any of them individually fail, I would like to abort the ones not yet dispatched. They are all scheduled on a BFExecutor built from an NSOperationQueue.
Each task begins with a check on a shared cancellationToken to see if they should proceed. If the request fails, it returns its error and sets the cancellationToken to true. The remaining tasks in the queue then check the cancellationToken and dutifully return -[BFTask cancelledTask] when they get their turn.
The problem is that the continuation block for -[BFTask taskForCompletionOfAllTasks:] gives cancellations precedent over errors. So, the task for the completion of all of them returns a cancelled task instead of an error. There's an important distinction there. I want to message errors in my user experience, but not cancellations.
I suspect it's intentional, but I don't know why. Is my use of the same cancellation token for canceling and errors discouraged? Or is this something that you could possibly change (to give errors precent over cancellations)?
Socios?
when target_url is null in the url, a crash occurs in the method initWithURL:forOpenInboundURL:sourceApplication:forRenderBackToReferrerBar:
when control reaches this line:
_targetURL = target ? [NSURL URLWithString:target] : url;
target is of class NSNull
When the returnToRefererView is shown in a setup with a UINavigationController containing a UITableViewController with a searchBar on top, there are a couple of issues:
To me it looks like it's not a good idea to mess with the navigationBar position!
Now that Swift has been released, the API design between Android and iOS should be brought together with the support of generics in Swift.
Swift apps should be able to reference a more modern API that takes advantage of generics for task results and continuations.
For legacy purposes it likely makes sense to keep the Objective-C implementation separate, since Obj-C does not support generics. However Swift codebases should not be held back from leveraging the advantages of generics due to the legacy nature of the Bolts Obj-C library.
I've installed Bolts via cocoapods in Xcode 7, now I get 2 errors when I try to build the app.
The first error is "'CFURLCreateStringByAddingPercentEscapes' is deprecated: first deprecated in iOS 9.0 - Use [NSString stringByAddingPercentEncodingWithAllowedCharacters:] instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent (since each URL component or subcomponent has different rules for what characters are valid)."
And the second error is "'sendAsynchronousRequest:queue:completionHandler:' is deprecated: first deprecated in iOS 9.0 - Use [NSURLSession dataTaskWithRequest:completionHandler:] (see NSURLSession.h"
The errors are in two different Files, the first is in BFAppLinkNavigation.m, the second in BFWebViewAppLinkResolver.m.
Here is the repro: https://github.com/telip007/testPods
using the latest Bolts framework...
Frameworks/Bolts.framework/Bolts(BFExecutor.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I installed the iOS SDK via CocoaPods. The SDK is working fine.
I then run xctool to test my App via command line and everything is working out good!
But when i try to setup a Mac CI server with xctool and when I clone my project into another dir and try to run the tests via xctool is stops with various errors:
In file included from some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:11:
In file included from some Dir//Pods/Bolts/Bolts/iOS/BFAppLink_Internal.h:11:
some Dir//Pods/Headers/Private/Bolts/BFAppLink.h:1:1: error: expected identifier or '('
../../../Bolts/Bolts/iOS/BFAppLink.h
^
In file included from some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:11:
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink_Internal.h:21:1: error: missing context for method declaration
- (BOOL)isBackToReferrer;
^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink_Internal.h:23:1: error: expected method body
@end
^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: cannot find interface declaration for 'BFAppLink'
@interface BFAppLink ()
^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: class extension has no primary class
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: class extension has no primary class
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: class extension has no primary class
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:23:12: error: class extension has no primary class
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:38:30: error: no known class method for selector 'alloc'
BFAppLink *link = [[self alloc] initWithIsBackToReferrer:isBackToReferrer];
^~~~~
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:39:10: error: property 'sourceURL' not found on object of type 'BFAppLink *'
link.sourceURL = sourceURL;
^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:40:10: error: property 'targets' not found on object of type 'BFAppLink *'
link.targets = [targets copy];
^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:41:10: error: property 'webURL' not found on object of type 'BFAppLink *'
link.webURL = webURL;
^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:55:18: error: 'BFAppLink' cannot use 'super' because it is a root class
if ((self = [super init])) {
^
some Dir//Pods/Bolts/Bolts/iOS/BFAppLink.m:56:12: error: property 'isBackToReferrer' not found on object of type 'BFAppLink *'
self.isBackToReferrer = isBackToReferrer;
^
I managed to reduce the # of errors by switching to use precompiled headers from off to on in the Pods-Bolt target but these errors above still exists. I am developing an iOS 8 only app.
Any ideas?
DEVICE: iPhone 4
IOS VERSION: 7.0.4
Thread : Crashed: com.apple.main-thread
0 ??? 0x2beeb0c4
1 ??? 0x2beebf07
2 ??? 0x2beed69f
3 libdyld.dylib 0x38ba80d0 dyld_stub_binder + 20
4 APP 0x000f3281 38+[BFTask taskForCompletionOfAllTasks:]_block_invoke (BFTask.m:102)
5 APP 0x000f4521 __41-[BFTask continueWithExecutor:withBlock:]_block_invoke_2 (BFTask.m:287)
6 APP 0x000f235d __29+[BFExecutor defaultExecutor]_block_invoke_2 (BFExecutor.m:43)
7 APP 0x000f2795 -BFExecutor execute:
8 APP 0x000f44af __41-[BFTask continueWithExecutor:withBlock:]_block_invoke (BFTask.m:284)
9 APP 0x000f4331 -BFTask continueWithExecutor:withBlock:
10 APP 0x000f4869 -BFTask continueWithBlock:
11 APP 0x000f2f87 +BFTask taskForCompletionOfAllTasks:
12 APP 0x0022544b -PFTaskQueue enqueue:
13 APP 0x001e76a7 -PFObject saveInBackground
14 APP 0x0022303d -PFInstallation saveInBackground
15 APP 0x0004c155 -AppDelegate application:didRegisterForRemoteNotificationsWithDeviceToken:
16 UIKit 0x30d9a473 _UIXXRemoteNotificationRegistrationSucceeded + 150
17 UIKit 0x30d9afe1 _XRemoteNotificationRegistrationSucceeded + 92
18 AppSupport 0x31ae6a97 migHelperRecievePortCallout + 190
19 CoreFoundation 0x2e2db9df __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 34
20 CoreFoundation 0x2e2db97b __CFRunLoopDoSource1 + 346
21 CoreFoundation 0x2e2da14f __CFRunLoopRun + 1398
22 CoreFoundation 0x2e244c27 CFRunLoopRunSpecific + 522
23 CoreFoundation 0x2e244a0b CFRunLoopRunInMode + 106
24 GraphicsServices 0x32f23283 GSEventRunModal + 138
25 UIKit 0x30ae8049 UIApplicationMain + 1136
26 APP 0x000510fb main (main.m:16)
In BFAppLinkReturnToReferrerView.m, when it calculates the size of the status bar, there is an option to include the status bar in the size Always/iOS7+/Never.
As I see it, the problem is that the Always option is the same as the Never option. I'm assuming this is some copy/pasting bug. If not, is there some reason why it is like it is?
When will AppLink be formally released?
I've been thinking you could use NSProgress to report progress of a task but also as a cancellation token as it has a cancelling method.
I want to do multiple asynchronous tasks in parallel, each of which returns a value, and then when all have completed, get an array of those results.
As of now, taskForCompletionOfAllTasks just returns a result of nil.
I have 10 elements in an array. After checking each element in that array, I created the task. Now I want to run all the tasks parallel in different thread not in the main thread. For that I used the BFExecutor.
BFExecutor* executor = [BFExecutor executorWithBlock:^void(void(^block)()) {
dispatch_async(dispatch_get_global_queue(0,0), block);
}];
BFTask* task = [BFTask taskWithResult: nil];
[[task continueWithExecutor:executor withBlock:^id(BFTask* task) {
return task2;
}] continueWithBlock:^id(BFTask* task) {
# Do something with that task.result
return nil;
}];
Is this is the correct way of using BFTask in separate thread ?
Thanks.
Frequently, I have to write code like this:
BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource];
[.... continueWithBlock:^id(BFTask *task) {
if (task.faulted) {
NSError *error = task.error;
if (error) {
[source trySetError:error];
} else {
[source trySetException:task.exception];
}
} else if (task.cancelled) {
[source trySetCancelled];
} else {
[source trySetResult:task.result];
}
return task;
}];
It would be nice if there was an API similar to [source trySetTask:task]
instead of having this ugly block of code.
See https://en.wikipedia.org/wiki/Spurious_wakeup for a description of "spurious wakeup". This seems to apply to NSCondition
, as Apple's documentation (Threading Programming Guide) states:
Due to the subtleties involved in implementing operating systems, condition locks are permitted to return with spurious success even if they were not actually signaled by your code. To avoid problems caused by these spurious signals, you should always use a predicate in conjunction with your condition lock.
(The reference documentation for NSCondition
also touches on this topic.)
I think something like this may be more correct:
- (void)waitUntilFinished {
if ([NSThread isMainThread]) {
[self warnOperationOnMainThread];
}
@synchronized (self.lock) {
if (self.completed) {
return;
}
[self.condition lock];
}
while (YES) {
[self.condition wait];
@synchronized (self.lock) {
if (self.completed)
break;
}
}
[self.condition unlock];
}
Alternately, using dispatch_semaphore_t
may provided a simpler implementation.
(Note that I have not actually observed a spurious wakeup. I don't know if this is a possibility on iOS.)
I was wondering, what is the intended approach to task cancellation?
BFTask
only exposes methods for task consumption and continuation, while the cancellation is implemented through BFTaskCompletionSource
(which actually just calls internal cancellation methods of BFTask
).
There is no way to cancel a BFTask
without having a reference to its completion source.
Does this mean that a task producer should keep a reference to all its long-running cancellable task completion sources and expose an interface for identifying and cancelling a specific task?
[!] Error installing Bolts
[!] Attempt to read non existent folder /Volumes/ABC/Projects/TestApp/Pods/Bolts
.
I encounter this error when pod install
Hi,
Fantastic framework! From what I can see, there's no facility for automatically creating an array of the results from grouped tasks (using taskForCompletionOfAllTasks:
). Errors and exceptions are collected, but not the results. Of course this can be done from the array of tasks manually, but I just wanted to confirm I wasn't missing something, or that (more likely) this was intentionally left unimplemented.
Thanks,
J
I am using the following code to open the Facebook app:
...
NSString *testUrl = @"fb://";
NSURL *url = [[NSURL alloc] initWithString:testUrl];
[[BFAppLinkNavigation navigateToURLInBackground:url] continueWithBlock:^id(BFTask *task) {
NSLog(@"yay!");
return 0;
}];
...
and what I get is an error (generated in BFWebViewAppLinkResolver.m) - NSURLErrorDomain - code 1002.
When I use [[UIApplication sharedApplication] openURL:url] on the same URL it works just fine..
Please help me guys :)
I want to use Bolts to interact with Facebook app.
I write this testcase for reproduce my issue.When runs to line [BFTask waitUntilFinished], it cannot return.
- (void)testAsyncWait {
NSLog(@"Start call");
BFExecutor *backgroundExecutor = [BFExecutor executorWithDispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)];
BFTask *task = [[[BFTask taskFromExecutor:backgroundExecutor withBlock:^id(BFTask *task) {
NSLog(@"Background call");
return nil;
}] continueWithSuccessBlock:^id(BFTask *task) {
NSLog(@"Background call2");
return nil;
}] continueWithExecutor:[BFExecutor mainThreadExecutor] withSuccessBlock:^id(BFTask *task) {
NSLog(@"Foreground call");
return @"Test Result";
}];
NSLog(@"Wait call");
[task waitUntilFinished];
NSLog(@"End call");
NSLog(@"%@", task.result);
}
Can you update the podspec to include the update with the Task Cancellation feature please ?
Hello,
I am deep in trying to properly codesign Bolts for use with the Parse framework and it shows as "..not a valid format..."
I see here that this branch is newer than what Parse is using. I did a build from the master using your scripts and dropped the OSX framework into my project, added copy files phase and checked to code sign like I do for other frameworks. I am getting:
"...bundle format is ambiguous (could be app or framework)"
This is odd as Parse and Sparkle code sign perfectly. Any ideas? I tried re-working the plist but was not successful. I also noticed that your release build script place the OSX Bolts.frameworks inside itself.
-matt
I am using Bolts via Parse, and am seeing an untrappable bolts error, with Bolts trying to set an error, with no error except the faulted = YES .. with no hint, no clue, no ANYTHING except a stopped app.
The ONLY thing changed between a working app and this was UI settings of another view, a child of the offending view.
Unsettling that Bolts is giving nothing to act on yet is stopping my app from running. For now i am going to toss in a check for a nil error and ignore, but this is frustrating. ;)
The stoppage occurs in:
(void)setError:(NSError *)error { if (![self trySetError:error]) { [NSException raise:NSInternalInconsistencyException format:@"Cannot set the error on a completed task."]; } }
I have no clue how to better describe this, and will try. The last time this happened, i simply stepped back an entire coding day and rebuilt, testing each save and got past the point of the last occurrence, which shows me it is not grounded in that which i am doing but in something very fuzzy.
Same thing happened today, but i will only lose about 2 hours of work to rebuild.
Hi,
I have a first app which performs a navigation to the second app:
- (IBAction)open:(id)sender
{
NSURL *url = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"];
[[BFAppLinkNavigation resolveAppLinkInBackground:url] continueWithSuccessBlock:^id(BFTask *task) {
BFAppLink *link = task.result;
BFAppLinkNavigation *navigation = [BFAppLinkNavigation navigationWithAppLink:link
extras:@{ @"_test_": @"SURPRISE mother fucker!" }
appLinkData:@{ @"referer_app_link": @{
@"url": @"applinks://",
@"app_name": @"AppLinks"
}}];
NSError *error = nil;
[navigation navigate:&error];
return task;
}];
}
The second app shows up but the back view is missing and the app crashes without any output.. did I miss something ?
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.appLinkReturnToRefererView) {
self.appLinkReturnToRefererView.hidden = YES;
}
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (delegate.parsedUrl) {
self.appLink = [delegate.parsedUrl appLinkReferer];
[self _showRefererBackView];
}
delegate.parsedUrl = nil;
}
- (void) _showRefererBackView {
if (nil == self.appLinkReturnToRefererView) {
// Set up the back link navigation view
BFAppLinkReturnToRefererView *backLinkView = [[BFAppLinkReturnToRefererView alloc] initWithFrame:CGRectMake(0, 30, 320, 40)];
self.appLinkReturnToRefererView = backLinkView;
}
self.appLinkReturnToRefererView.hidden = NO;
// Initialize the back link view controller
BFAppLinkReturnToRefererController *alc =[[BFAppLinkReturnToRefererController alloc] init];
alc.view = self.appLinkReturnToRefererView;
// Display the back link view
[alc showViewForRefererAppLink:self.appLink];
}
EDIT:
If I use the solution without using Bolts, everything is fine. I followed this tutorial:
It there an issue in the BFAppLinkReturnToRefererView
class ?
The test [result isKindOfClass:[BFTask class]] is failing sometimes when using tasks created from Swift.
The result of the test is undefined (know bug by apple)
According to the guide, you can either setup the view explicitly:
self.returnToRefererView = [[BFAppLinkReturnToRefererView alloc] initWithFrame:CGRectZero];
self.returnToRefererController = [[BFAppLinkReturnToRefererController alloc] init];
self.returnToRefererController.view = self.returnToRefererView;
Or implicitly, by not creating and assigning a BFAppLinkReturnToReferrerView
— which will automatically be created when calling -showViewForRefererURL:
on the controller.
Looking at the code I see that when this view is automatically created and _attachedToNavController
is not nil
, it is added to the view hierarchy. OTOH, when manually setting this view, it is not attached to the nav controller. I feel like this violates the Principle of Least Astonishment — ideally the whole return to referrer view would work like a black box that magically works with the least external setup possible.
Quick & dirty fix would be adding a [_attachedToNavController.view addSubview:_view];
on -setView:
Now, on to the real problem, initializing the view with CGRectZero
always results in a blank view. Doesn't matter if it's explicitly created and provided to the returnToRefererController
or internally created. I've set a few breakpoints throughout the code and the size always ends up being (0, 0, 0, 52)
instead of (0, 0, 320, 52)
.
The only way I can get the view to behave properly (i.e. render as it should, the label and the X button with a blue background) is if I initialize it manually with the target width:
// Using a magic value for the sake of demo
self.returnToRefererView = [[BFAppLinkReturnToRefererView alloc] initWithFrame:CGRectMake(0, 0, 320, 0)];
This is contradictory to the instructions on the README which state that the view should be initialized with CGRectZero
.
BFAppLinkReturnToRefererController
— I like the ability of being able to pass my own implementation of BFAppLinkReturnToRefererView
(should I ever need it) but having to write more code (that should be internal to the controller) when I do is cumbersome;-init
and -initForDisplayAboveNavController:
constructors on BFAppLinkReturnToRefererController
and add a new one, `-initWithViewController: — I feel like it should make no difference whether it's a navigation controller or a regular view controller, this thing should be a black boxI'd be more than happy to discuss this further and/or advance a solution if you feel like any of this makes sense.
Hi there, can you please add an "isFaulted" property to BFTask on iOS?
The abstraction for the SDK should be as consistent as possible between Android and iOS - this one of the Bolts framework biggest benefits is that it allows cross-platform teams to write code that is architecturally identical across both the Objective-C and Java SDKs.
The API surface should be identical for all purposes, simply using language-specific mechanisms such as blocks in Obj-C, anonymous interfaces in Java to leverage each language's best native syntax for the API.
After reading about the interesting idea of cancellation tokens in the readme,
I thought about using NSProgress instead of implementing it on my own.
Are there any known problems or issues with this approach?
I seen the compiling error: 'sharedApplication' is unavailable: not available on iOS (App Extension) in Bolts 1.2.0.
Will you fix that?
When I typing the end bracket ']' for continueWithBlock:, the start bracket '[' cannot be autocomplete with Xcode,but this works good for other case,for example:
[[NSArray array] enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
<#code#>
}];
This issue is for tracking compatibility with Carthage.
OS X version is already compatible, but we need to make Bolts for iOS/tvOS also compile and work great with Carthage.
[BFTask waitUntilFinished] shows this quite clearly. Fire off a few tasks, then call waitUntilFinished. The call to wait... will continue (and the task will be set to completed) before the execution block has been called.
This is due to [self runContinuations] always being called after completed/cancelled etc. being set. As a result.
I'm wondering if this is due to thread contention if the was called on the same thread as the executor block, but at the moment the behaviour seems incorrect and results in a lot of additional checks to make sure the task has actually finished.
I have an operation executed when user taps a button, I want to be able to prevent duplicate tasks from being fired.
I have a BFTask
that is returning false to [ob isKindOfClass:[BFTask class]]
and yet returns @"BFTask"
for NSStringFromClass([obj class])
.
Here is a sample project: [email protected]:krusek/Bolts-error.git
I would like to use Tasks and don't add App Links' code to my project.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.