From a2d64457e1c52d2d72863407537e950c80595231 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Tue, 1 Jun 2010 00:10:02 +0000 Subject: - Ensure start/end query notifications are sent on the main thread to avoid the interface being updated from the wrong thread on listeners - Add a "Support Files" folder to MCPKit, containing NSNotificationAdditions to support main thread notifications from within MCPKit --- Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m | 7 +- .../MCPKit/Support files/NSNotificationAdditions.h | 35 ++++++++++ .../MCPKit/Support files/NSNotificationAdditions.m | 76 ++++++++++++++++++++++ Source/CustomQuery.m | 6 +- Source/SPDatabaseDocument.m | 4 +- Source/SPTableContent.m | 14 ++-- Source/SPTableStructure.m | 8 +-- Source/SPTablesList.m | 4 +- sequel-pro.xcodeproj/project.pbxproj | 16 +++++ 9 files changed, 149 insertions(+), 21 deletions(-) create mode 100644 Frameworks/MCPKit/Support files/NSNotificationAdditions.h create mode 100644 Frameworks/MCPKit/Support files/NSNotificationAdditions.m diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m index eca76dcb..f36cff2c 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m @@ -35,6 +35,7 @@ #import "MCPStringAdditions.h" #import "SPStringAdditions.h" #import "RegexKitLite.h" +#import "NSNotificationAdditions.h" #include #include @@ -1388,7 +1389,7 @@ void performThreadedKeepAlive(void *ptr) if ([delegate respondsToSelector:@selector(queryGaveError:connection:)]) [delegate queryGaveError:@"No connection available!" connection:self]; // Notify that the query has been performed - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:delegate]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:delegate]; // Inform the delegate that there is no connection available if (delegate && [delegate respondsToSelector:@selector(noConnectionAvailable:)]) { @@ -1439,7 +1440,7 @@ void performThreadedKeepAlive(void *ptr) [self setLastErrorMessage:errorMessage]; // Notify that the query has been performed - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:delegate]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:delegate]; // Show an error alert while resetting if ([delegate respondsToSelector:@selector(showErrorWithTitle:message:)]) @@ -1460,7 +1461,7 @@ void performThreadedKeepAlive(void *ptr) if (queryErrorMessage) [queryErrorMessage release], queryErrorMessage = nil; // Notify that the query has been performed - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:delegate]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:delegate]; return nil; } } diff --git a/Frameworks/MCPKit/Support files/NSNotificationAdditions.h b/Frameworks/MCPKit/Support files/NSNotificationAdditions.h new file mode 100644 index 00000000..33c8ec10 --- /dev/null +++ b/Frameworks/MCPKit/Support files/NSNotificationAdditions.h @@ -0,0 +1,35 @@ +// +// $Id: NSNotificationAdditions.h 2045 2010-03-31 18:01:50Z stuart02 $ +// +// NSNotificationAdditions.h +// sequel-pro +// +// Copied from the Colloquy project; original code available from Trac at +// http://colloquy.info/project/browser/trunk/Additions/NSNotificationAdditions.h +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +@interface NSNotificationCenter (NSNotificationCenterAdditions) + +- (void) postNotificationOnMainThread:(NSNotification *) notification; +- (void) postNotificationOnMainThread:(NSNotification *) notification waitUntilDone:(BOOL) wait; + +- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object; +- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo; +- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo waitUntilDone:(BOOL) wait; + +@end diff --git a/Frameworks/MCPKit/Support files/NSNotificationAdditions.m b/Frameworks/MCPKit/Support files/NSNotificationAdditions.m new file mode 100644 index 00000000..f27a4d5c --- /dev/null +++ b/Frameworks/MCPKit/Support files/NSNotificationAdditions.m @@ -0,0 +1,76 @@ +// +// $Id: NSNotificationAdditions.m 2045 2010-03-31 18:01:50Z stuart02 $ +// +// NSNotificationAdditions.m +// sequel-pro +// +// Copied from the Colloquy project; original code available from Trac at +// http://colloquy.info/project/browser/trunk/Additions/NSNotificationAdditions.m +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at + +#import "NSNotificationAdditions.h" +#import + +@implementation NSNotificationCenter (NSNotificationCenterAdditions) + +- (void) postNotificationOnMainThread:(NSNotification *) notification { + if( pthread_main_np() ) return [self postNotification:notification]; + [self postNotificationOnMainThread:notification waitUntilDone:NO]; +} + +- (void) postNotificationOnMainThread:(NSNotification *) notification waitUntilDone:(BOOL) wait { + if( pthread_main_np() ) return [self postNotification:notification]; + [[self class] performSelectorOnMainThread:@selector( _postNotification: ) withObject:notification waitUntilDone:wait]; +} + ++ (void) _postNotification:(NSNotification *) notification { + [[self defaultCenter] postNotification:notification]; +} + +- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object { + if( pthread_main_np() ) return [self postNotificationName:name object:object userInfo:nil]; + [self postNotificationOnMainThreadWithName:name object:object userInfo:nil waitUntilDone:NO]; +} + +- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo { + if( pthread_main_np() ) return [self postNotificationName:name object:object userInfo:userInfo]; + [self postNotificationOnMainThreadWithName:name object:object userInfo:userInfo waitUntilDone:NO]; +} + +- (void) postNotificationOnMainThreadWithName:(NSString *) name object:(id) object userInfo:(NSDictionary *) userInfo waitUntilDone:(BOOL) wait { + if( pthread_main_np() ) return [self postNotificationName:name object:object userInfo:userInfo]; + + NSMutableDictionary *info = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:3]; + if( name ) [info setObject:name forKey:@"name"]; + if( object ) [info setObject:object forKey:@"object"]; + if( userInfo ) [info setObject:userInfo forKey:@"userInfo"]; + + [[self class] performSelectorOnMainThread:@selector( _postNotificationName: ) withObject:info waitUntilDone:wait]; + + [info release]; +} + ++ (void) _postNotificationName:(NSDictionary *) info { + NSString *name = [info objectForKey:@"name"]; + id object = [info objectForKey:@"object"]; + NSDictionary *userInfo = [info objectForKey:@"userInfo"]; + + [[self defaultCenter] postNotificationName:name object:object userInfo:userInfo]; +} + +@end diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m index 3585eb16..b5ba5306 100644 --- a/Source/CustomQuery.m +++ b/Source/CustomQuery.m @@ -503,7 +503,7 @@ [tableDocumentInstance setQueryMode:SPCustomQueryQueryMode]; // Notify listeners that a query has started - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; // Start the notification timer to allow notifications to be shown even if frontmost for long queries [[SPGrowlController sharedGrowlController] setVisibilityForNotificationName:@"Query Finished"]; @@ -740,7 +740,7 @@ [customQueryView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; // Notify any listeners that the query has completed - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; // Perform the Growl notification for query completion [[SPGrowlController sharedGrowlController] notifyWithTitle:@"Query Finished" @@ -794,7 +794,7 @@ [customQueryView setTableInstance:self withTableData:resultData withColumns:cqColumnDefinition withTableName:resultTableName withConnection:mySQLConnection]; //query finished - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; // Query finished Growl notification [[SPGrowlController sharedGrowlController] notifyWithTitle:@"Query Finished" diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m index 92f83a79..72cf201b 100644 --- a/Source/SPDatabaseDocument.m +++ b/Source/SPDatabaseDocument.m @@ -1085,7 +1085,7 @@ NSString *dbName = nil; // Notify listeners that a query has started - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:self]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:self]; MCPResult *theResult = [mySQLConnection queryString:@"SELECT DATABASE()"]; if (![mySQLConnection queryErrored]) { @@ -1110,7 +1110,7 @@ } //query finished - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:self]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:self]; } - (BOOL)navigatorSchemaPathExistsForDatabase:(NSString*)dbname diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index 79b8910c..a03e17a7 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -198,7 +198,7 @@ } // Post a notification that a query will be performed - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; // Set up the table details for the new table, and trigger an interface update NSDictionary *tableDetails = [NSDictionary dictionaryWithObjectsAndKeys: @@ -234,7 +234,7 @@ // Init copyTable with necessary information for copying selected rows as SQL INSERT [tableContentView setTableInstance:self withTableData:tableValues withColumns:dataColumns withTableName:selectedTable withConnection:mySQLConnection]; // Post the notification that the query is finished - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; // Clear any details to restore now that they have been restored [self clearDetailsToRestore]; @@ -566,7 +566,7 @@ [countText setStringValue:NSLocalizedString(@"Loading table data...", @"Loading table data string")]; // Notify any listeners that a query has started - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; // Start construction of the query string queryString = [NSMutableString stringWithFormat:@"SELECT %@ FROM %@", [self fieldListForQuery], [selectedTable backtickQuotedString]]; @@ -673,7 +673,7 @@ [self updatePaginationState]; // Notify listenters that the query has finished - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; // Trigger a full reload if required if (fullTableReloadRequired) [self reloadTable:self]; @@ -2098,13 +2098,13 @@ return YES; } - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; // If editing, compare the new row to the old row and if they are identical finish editing without saving. if (!isEditingNewRow && [oldRow isEqualToArray:[tableValues rowContentsAtIndex:currentlyEditingRow]]) { isEditingRow = NO; currentlyEditingRow = -1; - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; return YES; } @@ -2204,7 +2204,7 @@ } [fieldValues release]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; // If no rows have been changed, show error if appropriate. if ( ![mySQLConnection affectedRows] && ![mySQLConnection queryErrored] ) { diff --git a/Source/SPTableStructure.m b/Source/SPTableStructure.m index e14e76a1..74cae1c3 100644 --- a/Source/SPTableStructure.m +++ b/Source/SPTableStructure.m @@ -67,7 +67,7 @@ } // Send the query started/working notification - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; // Retrieve the column information for this table. // TODO: update this and indexes to use TableData at some point - tiny bit more parsing required... @@ -75,7 +75,7 @@ // If an error occurred, reset the interface and abort if ([mySQLConnection queryErrored]) { - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; [[self onMainThread] setTableDetails:nil]; if ([mySQLConnection isConnected]) { @@ -97,7 +97,7 @@ // If an error occurred, reset the interface and abort if ([mySQLConnection queryErrored]) { - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; [[self onMainThread] setTableDetails:nil]; if ([mySQLConnection isConnected]) { @@ -192,7 +192,7 @@ [[self onMainThread] setTableDetails:tableDetails]; // Send the query finished/work complete notification - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; } diff --git a/Source/SPTablesList.m b/Source/SPTablesList.m index 153e0227..498a5166 100644 --- a/Source/SPTablesList.m +++ b/Source/SPTablesList.m @@ -90,7 +90,7 @@ if ([tableDocumentInstance database]) { // Notify listeners that a query has started - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; // Select the table list for the current database. On MySQL versions after 5 this will include // views; on MySQL versions >= 5.0.02 select the "full" list to also select the table type column. @@ -208,7 +208,7 @@ } */ // Notify listeners that the query has finished - [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance]; } // Add the table headers even if no tables were found diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj index 3813b649..a9c44afb 100644 --- a/sequel-pro.xcodeproj/project.pbxproj +++ b/sequel-pro.xcodeproj/project.pbxproj @@ -169,6 +169,8 @@ 5841423F0F97E11000A34B47 /* NoodleLineNumberView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5841423E0F97E11000A34B47 /* NoodleLineNumberView.m */; }; 584192A1101E57BB0089807F /* NSMutableArray-MultipleSort.m in Sources */ = {isa = PBXBuildFile; fileRef = 584192A0101E57BB0089807F /* NSMutableArray-MultipleSort.m */; }; 584F5F8F0F50ACD800036517 /* table-view-small.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 584F5F8E0F50ACD800036517 /* table-view-small.tiff */; }; + 58587B5A11B4437C00D129ED /* NSNotificationAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 58587B5811B4437C00D129ED /* NSNotificationAdditions.h */; }; + 58587B5B11B4437C00D129ED /* NSNotificationAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 58587B5911B4437C00D129ED /* NSNotificationAdditions.m */; }; 586EBD2411418D7C00B3DE45 /* FeedbackReporter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 586EBD2311418D7C00B3DE45 /* FeedbackReporter.framework */; }; 586EBD5D11418D9400B3DE45 /* FeedbackReporter.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 586EBD2311418D7C00B3DE45 /* FeedbackReporter.framework */; }; 586F457B0FDB269E00B428D7 /* RegexKitLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 296DC8AB0F909194002A3258 /* RegexKitLite.m */; }; @@ -635,6 +637,8 @@ 5841929F101E57BB0089807F /* NSMutableArray-MultipleSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray-MultipleSort.h"; sourceTree = ""; }; 584192A0101E57BB0089807F /* NSMutableArray-MultipleSort.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray-MultipleSort.m"; sourceTree = ""; }; 584F5F8E0F50ACD800036517 /* table-view-small.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "table-view-small.tiff"; sourceTree = ""; }; + 58587B5811B4437C00D129ED /* NSNotificationAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSNotificationAdditions.h; path = "Support files/NSNotificationAdditions.h"; sourceTree = ""; }; + 58587B5911B4437C00D129ED /* NSNotificationAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NSNotificationAdditions.m; path = "Support files/NSNotificationAdditions.m"; sourceTree = ""; }; 586EBD2311418D7C00B3DE45 /* FeedbackReporter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FeedbackReporter.framework; path = Frameworks/FeedbackReporter.framework; sourceTree = ""; }; 586F432A0FD74CFC00B428D7 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/SSHQuestionDialog.xib; sourceTree = ""; }; 5870868210FA3E9C00D58E1C /* SPDataStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPDataStorage.h; sourceTree = ""; }; @@ -1144,6 +1148,7 @@ 17B7B5561016003F00F057DE /* MySQL */, 17B7B5581016005700F057DE /* MCPEntrepriseKit */, 17B7B5571016004500F057DE /* MCPFoundationKit */, + 58587B4E11B4433B00D129ED /* Support files */, ); name = MCPKit; path = ../Frameworks/MCPKit; @@ -1642,6 +1647,15 @@ name = Compression; sourceTree = ""; }; + 58587B4E11B4433B00D129ED /* Support files */ = { + isa = PBXGroup; + children = ( + 58587B5811B4437C00D129ED /* NSNotificationAdditions.h */, + 58587B5911B4437C00D129ED /* NSNotificationAdditions.m */, + ); + name = "Support files"; + sourceTree = ""; + }; 58DA884E103E1597000B98DF /* Debugging & Support */ = { isa = PBXGroup; children = ( @@ -1719,6 +1733,7 @@ 17B7B5F0101603D200F057DE /* mysql_version.h in Headers */, 17B7B5F1101603D200F057DE /* typelib.h in Headers */, 17DCC5C7115C202700F89A00 /* MCPStringAdditions.h in Headers */, + 58587B5A11B4437C00D129ED /* NSNotificationAdditions.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1991,6 +2006,7 @@ 17B7B5DF101603B200F057DE /* MCPResult.m in Sources */, 17B7B5E1101603B200F057DE /* MCPResultPlus.m in Sources */, 583B77D4103870C800B21F7E /* MCPStreamingResult.m in Sources */, + 58587B5B11B4437C00D129ED /* NSNotificationAdditions.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -- cgit v1.2.3