-1

Since writeData call is synchronous, what is the best way to use it when we call writeData from a different thread other than main queue?

For instance, a web service is called to fetch some data and the completionHandler is assigned to the web service call. Now this completion handler will be executed on a different thread (not on main queue).

I have seen my app getting stuck, on writeData method for 5 to 6 mins. This is the only thing I can suspect right now.

I tried wrapping around my writeData call with dispatch_async(mainQueue) but it did not work.

- (void) writeToFile: (NSString *) targetString
{
    //_loggingString holds the data, which keeps on accumulating as the user performs operations. At some point of time (callbacks from API's I call this method, to actually, write this string in the file and clear this string afterwards.)
    NSString *oldString = [_loggingString copy];

    _loggingString = [oldString stringByAppendingString:targetString];

    if (![[NSFileManager defaultManager]fileExistsAtPath:@"somePath"])
    {
        [[NSFileManager defaultManager]createFileAtPath:@"somePath" contents:nil attributes:nil];
    }

    NSFileHandle *fileHandle =  [NSFileHandle fileHandleForWritingAtPath:@"somePath"];

    [fileHandle seekToEndOfFile];

    [fileHandle writeData:[_loggingString dataUsingEncoding:NSUTF8StringEncoding]];

    _loggingString = @"";
}
nr5
  • 4,228
  • 8
  • 42
  • 82
  • share example of how you are handling NSFileHandle write operation. – Ankit Thakur Oct 23 '18 at 08:09
  • @AnkitThakur , edited my question with the code. – nr5 Oct 23 '18 at 08:17
  • Possible duplicate of [NSFileHandle writeData synchronously delaying main thread operations](https://stackoverflow.com/questions/52943056/nsfilehandle-writedata-synchronously-delaying-main-thread-operations) – gog Oct 23 '18 at 11:23

2 Answers2

0

You can do the saving part in a BackGround thread

- (void) writeToFile: (NSString *) targetString
{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSString *oldString = [_loggingString copy];

    _loggingString = [oldString stringByAppendingString:targetString];

    if (![[NSFileManager defaultManager]fileExistsAtPath:@"somePath"])
    {
        [[NSFileManager defaultManager]createFileAtPath:@"somePath" contents:nil attributes:nil];
    }

    NSFileHandle *fileHandle =  [NSFileHandle fileHandleForWritingAtPath:@"somePath"];

    [fileHandle seekToEndOfFile];

    [fileHandle writeData:[_loggingString dataUsingEncoding:NSUTF8StringEncoding]];

    _loggingString = @"";

});
}
Md. Ibrahim Hassan
  • 5,359
  • 1
  • 25
  • 45
  • Is it required to get the main queue again if I am bot doing anything in that? Just wondering... – nr5 Oct 23 '18 at 11:37
  • No its not required I just added it just in case you needed to get the main Thread after the task is done. Have updated the answer and removed it – Md. Ibrahim Hassan Oct 23 '18 at 11:38
0

It is not preferred to do file write operation in main thread. Also, there will be issue in performance with default global queue, as the system cannot prioritize the task.

So try to create 4 types of background queues:

dispatch_queue_t GlobalUserInteractiveQueue(void) {
    return dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0);
}

dispatch_queue_t GlobalUserInitiatedQueue(void) {
    return dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0);
}

dispatch_queue_t GlobalUtilityQueue(void) {
    return dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
}

dispatch_queue_t GlobalBackgroundQueue(void) {
    return dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0);
}

In your code just do this:

create custom queue. queue = dispatch_queue_create("customQueueName", NULL);

then write code in dispatch async

dispatch_async( queue ,
                   ^ {
                       // execute asynchronously
                       [fileHandle seekToEndOfFile];
                       [fileHandle writeData:[_loggingString dataUsingEncoding:NSUTF8StringEncoding]];

                   }); 

Check the working process of each queue here: https://gist.github.com/ankitthakur/dd945a66924fbd697169

Ankit Thakur
  • 4,739
  • 1
  • 19
  • 35