0

私のプログラムは、GPS を介してユーザーの現在位置を読み込み、txt ファイルに保存して、統計目的で電子メールで送信します。私の問題は次のとおりです。

  • ポジションを保存するたびに15秒の遅延を与える最初の試み:

    [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(locationManager:) userInfo:nil repeats:YES];

問題は、これが機能せず、その理由がわからないことです。

  • 私のもう1つの問題は、ファイルが大きすぎる場合...そのために、作成された日付と毎日異なる日付に名前を付けたいことです。私はいくつかのことを試しましたが、何も得られませんでした。

コード:

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{

//Obtenemos las coordenadas.
latitud = newLocation.coordinate.latitude;
longitud = newLocation.coordinate.longitude;
precision = newLocation.horizontalAccuracy;

// Lo mostramos en las etiquetas
[latitudLabel setText:[NSString stringWithFormat:@"%0.8f",latitud]];
[longitudLabel setText:[NSString stringWithFormat:@"%0.8f",longitud]];
[precisionLabel setText:[NSString stringWithFormat:@"%0.8f",precision]];
tiempoLabel=[self.dateFormatter stringFromDate:newLocation.timestamp];
//NSLog(@"tiempo: %@",tiempoLabel);

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"textfile.txt"];
//[[NSFileManager defaultManager] removeItemAtPath:path error:nil];

// create if needed
if (![[NSFileManager defaultManager] fileExistsAtPath:path]){
    [[NSData data] writeToFile:path atomically:YES];}

NSString *contents = [NSString stringWithFormat:@"tiempo: %@ latitude:%+.6f longitude: %+.6f precisión: %f\n",tiempoLabel,latitud,longitud,precision];

NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:path];
[handle truncateFileAtOffset:[handle seekToEndOfFile]];    
[handle writeData:[contents dataUsingEncoding:NSUTF8StringEncoding]];}        

助けてくれてありがとう。StackOverflow は私のプロジェクトで大いに役立っています

4

2 に答える 2

1

あなたは2つの異なる問題を提起します:

  1. あなたのタイマーに関して、あなたはと呼ばれるメソッドを持っていますlocationManager:か? あなたはその方法を示していないので、非常に疑わしいようです。を呼び出そうとしている場合locationManager:didUpdateToLocation:fromLocation:、それは機能しません。の@selectorには、NSTimer複数のパラメーターを指定することはできません。任意のメソッドを呼び出す単純なタイマー ハンドラ メソッドを作成できます。

    - (void)handleTimer:(NSTimer *)timer
    {
        // call whatever method you want here
    }
    

    次に、次のことができます。

    [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES];
    

    タイマーを繰り返すと、保持サイクルが発生する可能性があることに注意してください。そのため、ある時点でこれを却下する予定がある場合はinvalidate、後でできるようにタイマーへの参照を保持することをお勧めします ( などviewDidDisappear)。

    そうは言っても、15 秒ごとに書き込むのではなく、desiredAccuracyandを使用しdistanceFilterてロケーション マネージャーのデリゲート メソッドが呼び出されるタイミングを制御するという助言に同意します。x秒ごとに場所をログに記録することは、ユーザーのバッテリーを消耗させる優れた方法です。その他のバッテリー節約のガイダンスについては、Location Awareness Programming Guideの「 Tips for Conserving Battery 」を参照してください。

  2. 2番目の問題について、

    • その「必要に応じて作成する」コードを実行する必要はありません。と

    • NSFileHandleファイルを書き込むとき、そのコードは必要ありません。NSStringインスタンス メソッドを使用するだけですwriteToFile:atomically:encoding:error:(ちなみに、このメソッドにはNSError、ファイルの書き込みが失敗したかどうかを調べることができるパラメーターが含まれています)。

于 2013-07-16T14:32:39.437 に答える
0

タイマーを捨てて、ある程度の精度をチェックすることをお勧めします。これは、必要に応じて変更するか、そこから1行または2行を取得する必要があるGPS精度をチェックするサンプルコードです。

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    // test the age of the location measurement to determine if the measurement is cached
    // in most cases you will not want to rely on cached measurements
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];

    if (locationAge > 5.0) return;

    // test that the horizontal accuracy does not indicate an invalid measurement
    if (newLocation.horizontalAccuracy < 0) return;

    // test the measurement to see if it is more accurate than the previous measurement
    if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) {
        // store the location as the "best effort"
        self.bestEffortAtLocation = newLocation;

        // test the measurement to see if it meets the desired accuracy
        //
        // IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue 
        // accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of 
        // acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout.
        //
        if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) {
            // we have a measurement that meets our requirements, so we can stop updating the location
            // 
            // IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible.
            //
            [self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")];

            // we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil];
        }
    }
}

名前付けの問題で混乱している日付のファイルについては、タイトルの数値形式がニーズに合っていると思います.コードを見ても、didUpdateLocationメソッドから多くのことを分離する必要があります.平均して数秒ごとに呼び出され、プログラムに特定の時点まで待機するか、ファイルを再度更新しないように指示することなく、多くの問題が発生します。

于 2013-07-16T14:35:44.560 に答える