分类目录归档:开发文档

Swift 基础运算符

对任何一门高级编程语言,基础运算符都是不可或缺的。为了让更多开发者了解 Swift 的基础运算符,我们翻译了《The Swift Programming》的《Basic Operators》一章,如有错误,敬请指正。转载请在开始位置注明出处。

基础运算符

运算符是一种可以检查、修改或结合数值的特殊符号或短语。例如,加法运算符可以将两个数字相加(let i = 1 + 2)。更复杂的例子还包括逻辑与运算符 &&if enteredDoorCode && passedRetinaScan)以及可以简化增量操作的运算符 ++i

Swift 支持大多数标准 C 运算符,并增强了避免常见编码错误的能力。赋值运算符(=)没有返回值,这可以防止误用(=)和等于符号(==)。算数运算符(+*)会检测且禁止数值溢出,避免因处理数据不当而导致的意外结果。你可以使用 Swift 的溢出运算符来自定义溢出行为,详情请参考 溢出运算符

继续阅读

Objective-C 开发者眼中的 Swift: 那些激动人心的新功能

swiftfeature

我们会在 blog 上持续地发布 Swift 相关的文章。AVOS Cloud 的 Swift SDK 也会很快推出,请大家关注。在转载本文时请务必保持完整性并在开头提供出处链接。

本文翻译自 http://www.raywenderlich.com/73997/swift-language-highlights

如果你和我一样,周一早上坐下来准备好好看看苹果的 Keynote,兴奋地准备开始尝试一些新的 API,结果你听到最多的是一门新的语言:Swift!你突然被告知,这不是 Objective-C 的扩展,而是一门完完全全新的语言。你是会激动呢,还是高兴,抑或头脑一片空白?

Swift 将会完全改变我们写 iOS 和 Mac 应用的方式,在这片文章里,我概括了这门语言的一些要点,并和 Objective-C 里面相应部分做了对比。

注意:这不是 Swift 的入门读物,苹果已经发布了一本很全面的 Swift Programming Language,我强烈建议你先读它。这篇文章只会讨论一些特别 cool、值得玩味的知识点。

继续阅读

Swift 编程之闭包

‌‌Java 8 都引入了 Lambda,作为苹果新设计的编程语言,Swift 如果没有支持闭包,都不好意思出门跟众多新语言打招呼。这篇文档翻译自 《The Swift Programming Language》的《Closures》一章,如有错误,敬请指正。转载请在开始位置注明出处。

闭包

闭包 (Closures)是可以在你的代码里传递和使用的,自包含的功能代码块。Swift 里的闭包跟 C 和 Objective-C 里的 block 类似,也就是其他语言里的所谓的 lambda 。

闭包可以从定义的上下文 (Context) 里捕获和存储常量或者变量的引用。这被称为 「闭合」(closing over)了这些常量和变量,这也是 「闭包」 名称的由来。Swift 帮你处理了所有捕获相关的内存管理。

继续阅读

Swift 语言概览

过去的一周里 iOS 的开发者们最关注的话题无疑是 Apple WWDC 宣布的新的 iOS 平台程序设计语言 Swift. 不知道有多少非 iOS 开发者和我一样有「现在开始学 iOS 开发还不晚」的想法。

Not too late to learn

相对于 Objective-C 而言,因为没有了历史包袱,Swift 是一个更简洁的语言。同时 Swift 也是一个比较简单的语言,与其他现代的程序设计语言并没有太大不同。所以对于有一定经验的开发者来说只要对语法和基本特性有一定了解,就可以马上开始用 Swift 做开发。我们翻译了官方「The Swift Programming Language」中的「A Swift Tour」一章发布出来,旨在帮助有经验的开发者快速熟悉这门语言。

在这个过程中我们发现这本书在语言方面的质量并不是很高,比如一些地方出现了类型和类型的实例的混淆,以及声明和定义等概念的混淆等等。但无论如何在短期内,这本书还是学习 Swift 的主要资源。我们也会在 blog 上持续地发布相关的文章。AVOS Cloud 的 Swift SDK 也会很快推出,请大家关注。

在转载本文时请务必保持完整性并在开头提供出处链接。

继续阅读

Android SDK 子类化指南

从 1.4.0 版本开始,我们为 Android SDK 添加了子类化支持,一个简单的指南如下。

子类化

AVOSCloud 希望设计成能让人尽快上手并使用。你可以通过 ParseObject.get 方法访问所有的数据。但是在很多现有成熟的代码中,子类化能带来更多优点,诸如简洁、可扩展性以及 IDE 提供的代码自动完成的支持等等。子类化不是必须的,你可以将下列代码转化:

AVObject shield = new AVObject("Armor");
shield.put("displayName", "Wooden Shield");
shield.put("fireproof", false);
shield.put("rupees", 50);

成这样:

Armor shield = new Armor();
shield.setDisplayName("Wooden Shield");
shield.setFireproof(false);
shield.setRupees(50);

子类化 ParseObject

创建一个 ParseObject 的子类很简单:

  • 首先声明一个子类继承自 Parseobject。
  • 添加 @AVClassName 注解。它的值必须是一个字符串,也就是你过去传入 ParseObject 构造函数的类名。这样以来,后续就不需要再在代码中出现这个字符串类名。
  • 确保你的子类有一个 public 的默认(参数个数为 0)的构造函数。切记不要在构造函数里修改任何 ParseObject 的字段。
  • 在你的应用初始化的地方,在调用 AVOSCloud.initialize()之前注册子类 AVObject.registerSubclass(YourClass.class)

下列代码成功实现并注册了 ParseObject 的子类 Armor:

// Armor.java
import com.avos.avoscloud.AVClassName;
import com.avos.avoscloud.AVObject;

@AVClassName("Armor")
public class Armor extends AVObject {
}

// App.java
import com.avos.avoscloud.AVOSCloud;
import android.app.Application;

public class App extends Application {
  @Override
  public void onCreate() {
    super.onCreate();

    AVObject.registerSubclass(Armor.class);
    AVOSCloud.initialize(this, "{{appid}}", "{{appkey}}");
  }
}

访问器,修改器和方法

添加方法到 ParseObject 的子类有助于封装类的逻辑。你可以将所有跟子类有关的逻辑放到一个地方,而不是分成多个类来分别处理商业逻辑和存储/转换逻辑。

你可以很容易地添加访问器和修改器到你的 ParseObject 子类。像平常那样声明字段的 getter 和 setter 方法,但是通过 Parseobject 的 get 和 put 方法来实现它们。下面是这个例子为 Armor 类创建了一个 displayName 的字段:

// Armor.java
@AVClassName("Armor")
public class Armor extends AVObject {
  public String getDisplayName() {
    return getString("displayName");
  }
  public void setDisplayName(String value) {
    put("displayName", value);
  }
}

现在你就可以使用 armor.getDisplayName()方法来访问 displayName 字段,并通过 armor.setDisplayName("Wooden Sword")来修改它。这样就允许你的 IDE 提供代码自动完成功能,并且可以在编译时发现到类型错误。

各种数据类型的访问器和修改器都可以这样被定义,使用各种 get() 方法的变种,例如 getInt(), getAVFile(), 或者 getMap()。

如果你不仅需要一个简单的访问器,而是有更复杂的逻辑,你可以实现自己的方法,例如:

public void takeDamage(int amount) {
  // 递减 armor 的 durability 字段,并判断是否应该设置 broken 状态
  increment("durability", -amount);
  if (getDurability() < 0) {
    setBroken(true);
  }
}

初始化子类

你可以使用你自定义的构造函数来创建你的子类对象。你的子类必须定义一个公开的默认构造函数,并且不修改任何父类 ParseObject 中的字段,这个默认构造函数将会被 SDK 使用来创建子类的强类型的对象。

要创建一个到现有对象的引用,可以使用 AVObject.createWithoutData():

Armor armorReference = AVObject.createWithoutData(Armor.class, armor.getObjectId());

查询

你可以通过 AVObject.getQuery()或者 AVQuery.getQuery 的静态方法获取特定的子类的查询对象。下面的例子就查询了用户能够购买的盔甲 (Armor) 列表:

AVQuery<Armor> query = AVObject.getQuery(Armor.class);
//rupees 是游戏货币
query.whereLessThanOrEqualTo("rupees", AVUser.getCurrentUser().get("rupees"));
query.findInBackground(new FindCallback<Armor>() {
  @Override
  public void done(List<Armor> results, AVException e) {
    for (Armor a : results) {
      // ...
    }
  }
});

ParseUser 的子类化

ParseUser 作为 ParseObject 的子类,同样允许子类化,你可以定义自己的 User 对象,不过比起 ParseObject 子类化会更简单一些,只要继承 ParseUser 就可以了:

import com.avos.avoscloud.AVObject;
import com.avos.avoscloud.AVUser;

public class MyUser extends AVUser {
    public void setNickName(String name) {
    this.put("nickName", name);
    }

    public String getNickName() {
    return this.getString("nickName");
    }
}

不需要添加 @ParseClassname 注解,所有 ParseUser 的子类的类名都是内建的_User。同样也不需要注册 MyUser。

注册跟普通的 ParseUser 对象没有什么不同,但是登陆如果希望返回自定义的子类,必须这样:

MyUser cloudUser = AVUser.logIn(username, password,
            MyUser.class);

GEO Point 的使用

GEO Point 是什么

在 APP 开发的过程中, 我们经常会遇到在针对于地理坐标的一些问题. 而现实的地理坐标在我们的 AVOS Cloud 上提供一个对应, 我们把它称之为 GEO Point. 每一个 GEO Point 只包含 2 个信息, 就是它的经度 (longtitude) 与纬度 (latitude).

下面我们建立一个北纬 40 度, 东经 30 度的点:

JavaScript:

var point = new AV.GeoPoint({latitude: 40.0, longitude: -30.0});

(JavaScript 的 SDK 下载到这里。)

这只是一个代表这坐标信息的点而已, 而我们需要把这个点关联到对象上去, 这样才构成了一个有地理位置信息的对象

JavaScript:

placeObject.set("location", point);

这样我们就为 placeObject 这个对象加入了地理位置信息了. 在之后我们可以用 SDK 提供的功能进行查找.

做一个” 查找附近的人” 的功能

有了 AVOS Cloud 以后, 您可以轻松地实现类似于微信中:” 查找附近的人” 这种功能. 而这并不需要您做太多的工作, 大部分事情都可以交给 AVOS Cloud 来做.

为每个用户加入地理位置信息

为了提供这项功能, 当然确定用户的地理位置是一定需要的, 获取用户当前的地理位置需要根据用户所用的设备来调用相应设备的 API, 以获取当前用户的地理位置信息. 然后如果需要的话应该将其转换为经度和纬度, 我们这里假设用户在东经 40 度北纬 50 度的地方, 然后设定当前用户的地理位置, 同时为了让其他用户能得到当前用户的地址, 我们应该更新当前用户的地理信息:

var point = new AV.GeoPoint({latitude: 40.0, longitude: -30.0});
var currentUser = AV.User.current();
if (currentUser) {
    currentUser.set("location", point);
    currentUser.save();
} else {
    // user signup or login
}

查找当前用户附近的用户

有了用户的地理信息之后, 我们就可以提供一个搜索了, 这一点可以用 AVOS Cloud 带有的地理查询功能来做:

var query = new AV.Query(Parse.User);
query.near("location", point);
query.limit(10);
query.find({
  success: function(users) {
  }
});

AVOS Cloud 对于 near 类型的查询会按距离由近到远进行排序, 这样我们非常轻松地就找到了离我们的当前用户距离最近的十个用户了.

GEO Point 还有哪些查询方式?

上面的例子中我们限定了返回 10 个结果, 但是如果我们只想查找同城的用户的话怎么办呢?

可以用 withinKilometers 方式来限定我们的查询, 或者说是用 withinGeoBox 这个方法把结果限定在一个矩形之内.
withinKilometers 接受一个距离参数, 可以限定 query 的距离范围. 而 withinGeoBox 接受 2 个 GEO Point, 这两个点代表了矩形的对角的两个点, 这样就可以把查询限定在一个矩形范围内了.